fix: Migrating project to the new Gitea Host.
This commit is contained in:
parent
ef348f1979
commit
a7ea9227cf
6
.gitignore
vendored
Executable file
6
.gitignore
vendored
Executable file
@ -0,0 +1,6 @@
|
||||
PHP/KStats.Secrets.php
|
||||
KStats.apache2.conf
|
||||
Public/index.html
|
||||
Public/es
|
||||
Public/dev
|
||||
Data
|
183
HTML/base.kstats.html
Executable file
183
HTML/base.kstats.html
Executable file
@ -0,0 +1,183 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es" dir="ltr">
|
||||
<head>
|
||||
<title>{title}</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<link rel="icon" href="/images/KStats-32.png" sizes="32x32" />
|
||||
<link rel="icon" href="/images/KStats-192.png" sizes="192x192" />
|
||||
<link rel="icon" href="/images/KStats-512.png" sizes="512x512" />
|
||||
<link rel="apple-touch-icon-precomposed" href="/images/KStats-180.png" />
|
||||
<meta name="msapplication-TileImage" content="/images/KStats-270.png" />
|
||||
|
||||
<meta name="licence:text" content="© 2020-2021 CopyLeft. GPLv3" />
|
||||
<meta name="licence:link" content="https://www.gnu.org/licenses/gpl-3.0.txt" />
|
||||
<meta name="licence:icon" content="https://www.gnu.org/graphics/gplv3-88x31.png" />
|
||||
|
||||
<meta name="xdoc:link" content="{url}" />
|
||||
<meta name="xdoc:author" content="{author}" />
|
||||
<meta name="xdoc:since" content="{since}" />
|
||||
<meta name="xdoc:version" content="{version}" />
|
||||
<meta name="xdoc:access" content="public" />
|
||||
|
||||
<meta name="description" data-i18n="kstats_description" content="{description}" />
|
||||
<meta name="keywords" data-i18n="kstats_keywords" content="{key_words}" />
|
||||
<meta name="author" content="{author}" />
|
||||
<meta name="copyright" content="© 2020-2021 CopyLeft" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="googlebot" content="index,follow,max-snippet:-1,max-image-preview:large,max-video-preview:-1" />
|
||||
<meta name="bingbot" content="index,follow,max-snippet:-1,max-image-preview:large,max-video-preview:-1" />
|
||||
<!--<meta http-equiv="refresh" content="30" />-->
|
||||
<!--<meta http-equiv="cache-control" content="no-cache" />-->
|
||||
<!--<meta http-equiv="expires" content="0" />-->
|
||||
<link rel="canonical" href="{url}" />
|
||||
<link rel="alternate" href="{url}" hreflang="es" />
|
||||
<meta property="og:locale:alternate" content="es_ES" />
|
||||
<meta name="referrer" content="origin" />
|
||||
<meta name="fragment" content="!" /><!-- Para uso AJAX -->
|
||||
<meta name="language" content="es" />
|
||||
<meta name="revisit-after" content="7 days" /><!-- Regreso de las arañas. Información Crawl. -->
|
||||
<meta name="rating" content="general" /><!-- Tipo de contenido: general, mature, restricted, adult, 14 years, safe for kids. -->
|
||||
<meta name="author" content="{author}" />
|
||||
<meta name="owner" content="{author}" />
|
||||
|
||||
<meta property="og:locale" content="es_ES" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" data-i18n="kstats_title" content="{title}" />
|
||||
<meta property="og:description" data-i18n="kstats_description" content="{description}" />
|
||||
<meta property="og:url" content="{url}" />
|
||||
<meta property="og:site_name" content="{project}" />
|
||||
<meta property="og:image" content="{logo}" />
|
||||
<!--<meta property="fb:admins" content="FB-AppID" />-->
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:description" data-i18n="kstats_description" content="{description}" />
|
||||
<meta name="twitter:title" data-i18n="kstats_title" content="{title}" />
|
||||
<!--<meta name="twitter:site" content="@KStats" />-->
|
||||
<!--<meta name="twitter:creator" content="@KStats" />-->
|
||||
|
||||
<meta name="SKYPE_TOOLBAR" content="SKYPE_TOOLBAR_PARSER_COMPATIBLE" />
|
||||
<!--<meta name="google-site-verification" content="123456789" />--><!-- Verificación en el Google Search Console. -->
|
||||
<meta name="google" content="nositelinkssearchbox" />
|
||||
<link rel="dns-prefetch" href="{url}" />
|
||||
<!--<link rel="amphtml" href="{url}index.amp.html" />--><!-- Indica si tiene página para móviles. Tecnología AMP. -->
|
||||
|
||||
<link type="text/css" rel="stylesheet" data-language="CSS3" href="https://cdn.k3y.pw/css/fonts/local/Roboto.css" data-crossorigin="anonymous" charset="utf-8" />
|
||||
<link type="text/css" rel="stylesheet" data-language="CSS3" href="https://cdn.k3y.pw/css/fonts/local/RobotoMono.css" data-crossorigin="anonymous" charset="utf-8" />
|
||||
<link type="text/css" rel="stylesheet" data-language="CSS3" href="https://cdn.k3y.pw/css/fonts/local/FontAwesome5Free.css" data-crossorigin="anonymous" charset="utf-8" />
|
||||
<link type="text/css" rel="stylesheet" data-language="CSS3" href="https://unpkg.com/@highlightjs/cdn-assets@10.7.2/styles/default.min.css" data-crossorigin="anonymous" charset="utf-8" />
|
||||
|
||||
<script data-type="text/javascript" data-language="JavaScript 1.8.5" src="https://unpkg.com/mermaid@8.9.3/dist/mermaid.min.js" data-js-map="https://unpkg.com/mermaid@8.9.3/dist/mermaid.min.js.map" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
<script data-type="text/javascript" data-language="JavaScript 1.8.5" src="https://unpkg.com/@highlightjs/cdn-assets@10.7.2/highlight.min.js" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" src="https://kstats.k3y.pw/ecma/KStats.ecma.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
kstats = new KStats({url : "https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/json/set"});
|
||||
|
||||
</script>
|
||||
|
||||
<link type="text/css" rel="stylesheet" data-language="SASS/CSS3" href="https://wmarkdown.k3y.pw/scss/WMarkDown.css" data-scss="https://wmarkdown.k3y.pw/scss/WMarkDown.scss" data-css-map="https://wmarkdown.k3y.pw/scss/WMarkDown.css.map" data-crossorigin="anonymous" charset="utf-8" />
|
||||
<link type="text/css" rel="stylesheet" data-language="CSS3" href="https://wmarkdown.k3y.pw/css/WMarkDown.icons.css" data-crossorigin="anonymous" charset="utf-8" />
|
||||
<link type="text/css" rel="stylesheet" data-language="CSS3" href="/css/KStats.icons.css" data-crossorigin="anonymous" charset="utf-8" />
|
||||
|
||||
<style data-type="text/css" data-rel="stylesheet" data-language="CSS3" charset="utf-8">
|
||||
|
||||
html,body{
|
||||
height : 100%;
|
||||
margin : 0px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" src="https://wmarkdown.k3y.pw/ecma/WMarkDown.ecma.js" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" src="https://wmarkdown.k3y.pw/ecma/WMarkDown.Dictionary.ecma.js" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" src="https://wmarkdown.k3y.pw/ecma/WMarkDown.Multimedia.ecma.js" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" charset="utf-8">
|
||||
|
||||
wmarkdown = new WMarkDown({
|
||||
dictionary_links : "https://wdictionaries.k3y.pw/?es/values,own_projects,projects,digital,common,kyman",
|
||||
dictionary_title : "Diccionario"
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="wmarkdown ks kstats">
|
||||
<header>
|
||||
<h1 class="logo">
|
||||
<a href="https://kstats.k3y.pw#">
|
||||
<span class="image">
|
||||
<span style="background-image:url('/images/KStats.png');"></span>
|
||||
<img src="/images/KStats.png" alt="KStats" />
|
||||
</span>
|
||||
<span class="text">KStats</span>
|
||||
</a>
|
||||
</h1>
|
||||
<nav class="main-menu">
|
||||
<ul>
|
||||
<li><a href="/" data-i18n="home" data-i18n-without="true" title="Home" target="_self">
|
||||
<span data-icon="home"></span>
|
||||
<span data-i18n="home">Home</span>
|
||||
</a></li>
|
||||
<li><a href="/dev" data-i18n="developt" data-i18n-without="true" title="Desarrollo" target="_self">
|
||||
<span data-icon="developt"></span>
|
||||
<span data-i18n="developt">Desarrollo</span>
|
||||
</a></li>
|
||||
<li><a href="https://git.k3y.pw/KyMAN/KStats" data-i18n="git" data-i18n-without="true" title="Git" target="_blank">
|
||||
<span data-icon="git"></span>
|
||||
<span data-i18n="git">Git</span>
|
||||
</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<main class="body" data-headers-menu-deployed="true" data-files-menu-deployed="true">
|
||||
<fieldset class="headers-menu">
|
||||
<legend data-i18n="headers_menu" title="Menu">Menu</legend>
|
||||
<nav>
|
||||
<ul>{menu}</ul>
|
||||
</nav>
|
||||
<div class="menu-buttons">
|
||||
<button type="button" data-i18n="hide" data-i18n-without="true" title="Hide" onclick="wmarkdown.hide_menu(this, event);" data-visible="true">
|
||||
<span data-icon="hide"></span>
|
||||
<span data-i18n="hide">Hide</span>
|
||||
</button>
|
||||
<button type="button" data-i18n="show" data-i18n-without="true" title="Show" onclick="wmarkdown.show_menu(this, event);" data-visible="false">
|
||||
<span data-icon="show"></span>
|
||||
<span data-i18n="show">Show</span>
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="content">
|
||||
<legend data-i18n="content" title="Content">Content</legend>
|
||||
<div class="content-box">{content}</div>
|
||||
</fieldset>
|
||||
<fieldset class="files">
|
||||
<legend data-i18n="files" title="Files">Files</legend>
|
||||
<nav>
|
||||
<ul>{files}</ul>
|
||||
</nav>
|
||||
<div class="menu-buttons">
|
||||
<button type="button" data-i18n="hide" data-i18n-without="true" title="Hide" onclick="wmarkdown.hide_menu(this, event);" data-visible="true">
|
||||
<span data-icon="hide"></span>
|
||||
<span data-i18n="hide">Hide</span>
|
||||
</button>
|
||||
<button type="button" data-i18n="show" data-i18n-without="true" title="Show" onclick="wmarkdown.show_menu(this, event);" data-visible="false">
|
||||
<span data-icon="show"></span>
|
||||
<span data-i18n="show">Show</span>
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</main>
|
||||
<footer>
|
||||
<a href="https://www.gnu.org/licenses/gpl-3.0.txt" target="_blank" title="GPLv3" class="license">
|
||||
<span data-i18n="license_text">© 2021-2022 CopyLeft.</span>
|
||||
<img src="https://www.gnu.org/graphics/gplv3-127x51.png" alt="GPLv3" />
|
||||
</a>
|
||||
<div data-preload="wmarkdown-preloader"></div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
1
JSON/html.files.json
Executable file
1
JSON/html.files.json
Executable file
@ -0,0 +1 @@
|
||||
{"files":["\/mnt\/d\/git\/KStats\/Public\/dev\/ECMAScript\/index.html","\/mnt\/d\/git\/KStats\/Public\/dev\/PHP\/index.html","\/mnt\/d\/git\/KStats\/Public\/dev\/Public\/api\/index.php.html","\/mnt\/d\/git\/KStats\/Public\/dev\/Public\/ecma\/KStats.ecma.js.html","\/mnt\/d\/git\/KStats\/Public\/dev\/Public\/git_update.php.html","\/mnt\/d\/git\/KStats\/Public\/dev\/Public\/tests\/sessions.php.html","\/mnt\/d\/git\/KStats\/Public\/dev\/Public\/wmd.php.html","\/mnt\/d\/git\/KStats\/Public\/dev\/Public\/wmd_scripts.php.html","\/mnt\/d\/git\/KStats\/Public\/dev\/index.html","\/mnt\/d\/git\/KStats\/Public\/es\/bugs.html","\/mnt\/d\/git\/KStats\/Public\/es\/index.html","\/mnt\/d\/git\/KStats\/Public\/es\/project.html","\/mnt\/d\/git\/KStats\/Public\/es\/projects.html","\/mnt\/d\/git\/KStats\/Public\/es\/targets.html","\/mnt\/d\/git\/KStats\/Public\/es\/work.html","\/mnt\/d\/git\/KStats\/Public\/index.html"],"directories":["\/dev","\/dev\/ECMAScript","\/dev\/PHP","\/dev\/Public","\/dev\/Public\/api","\/dev\/Public\/ecma","\/dev\/Public\/tests","\/es"]}
|
447
MySQL/KStats.my.sql
Executable file
447
MySQL/KStats.my.sql
Executable file
@ -0,0 +1,447 @@
|
||||
create database if not exists KStats character set utf8mb4 collate utf8mb4_general_ci;
|
||||
use KStats;
|
||||
|
||||
delimiter ;^
|
||||
|
||||
drop procedure if exists tables_remove;^
|
||||
create procedure tables_remove() begin
|
||||
|
||||
-- Level 2.
|
||||
drop table if exists SessionsUrls;
|
||||
|
||||
-- Level 1.
|
||||
drop table if exists Sessions;
|
||||
drop table if exists IpsData;
|
||||
|
||||
-- Level 0.
|
||||
drop table if exists Urls;
|
||||
drop table if exists Ips;
|
||||
drop table if exists Tokens;
|
||||
drop table if exists Settings;
|
||||
|
||||
end;^
|
||||
|
||||
drop procedure if exists tables_create;^
|
||||
create procedure tables_create() begin
|
||||
|
||||
-- Level 0.
|
||||
create table if not exists Ips(
|
||||
id integer not null auto_increment,
|
||||
address varchar(39) not null,
|
||||
date_in datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint ips_id primary key(id)
|
||||
);
|
||||
|
||||
create table if not exists Urls(
|
||||
id integer not null auto_increment,
|
||||
url varchar(2048) not null,
|
||||
date_in datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint urls_id primary key(id)
|
||||
);
|
||||
|
||||
create table if not exists Tokens(
|
||||
id integer not null auto_increment,
|
||||
token varchar(256) not null,
|
||||
enabled boolean not null default true,
|
||||
pattern varchar(2048),
|
||||
public boolean not null,
|
||||
remarks varchar(2048),
|
||||
date_in datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint tokens_id primary key(id)
|
||||
);
|
||||
|
||||
create table if not exists Settings(
|
||||
id integer not null auto_increment,
|
||||
name varchar(32) not null,
|
||||
value varchar(256),
|
||||
date_in datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint settings_id primary key(id)
|
||||
);
|
||||
|
||||
create table if not exists Countries(
|
||||
id integer not null auto_increment,
|
||||
name varchar(128),
|
||||
code varchar(16),
|
||||
date_in datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint countries_id primary key(id)
|
||||
);
|
||||
|
||||
create table if not exists Isps(
|
||||
id integer not null auto_increment,
|
||||
name varchar(256),
|
||||
date_in datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint countries_id primary key(id)
|
||||
);
|
||||
|
||||
-- Level 1.
|
||||
create table if not exists Sessions(
|
||||
id integer not null auto_increment,
|
||||
ip integer not null,
|
||||
date_in datetime not null default now(),
|
||||
date_last datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint sessions_id primary key(id),
|
||||
constraint sessions_ip foreign key(ip) references Ips(id)
|
||||
);
|
||||
|
||||
create table if not exists IpsData(
|
||||
id integer not null auto_increment,
|
||||
ip integer not null,
|
||||
country integer not null,
|
||||
isp integer,
|
||||
latitude decimal(9, 6),
|
||||
longitude decimal(9, 6),
|
||||
`data` text not null,
|
||||
date_in datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint ips_data_id primary key(id),
|
||||
constraint ips_data_ip foreign key(ip) references Ips(id),
|
||||
constraint ips_data_country foreign key(country) references Countries(id),
|
||||
constraint ips_data_isp foreign key(isp) references Isps(id)
|
||||
);
|
||||
|
||||
-- Level 2.
|
||||
create table if not exists SessionsUrls(
|
||||
id integer not null auto_increment,
|
||||
`session` integer not null,
|
||||
token integer not null,
|
||||
url integer not null,
|
||||
date_in datetime not null default now(),
|
||||
date_last datetime not null default now(),
|
||||
date_out datetime,
|
||||
constraint sessions_urls_id primary key(id),
|
||||
constraint sessions_urls_session foreign key(`session`) references Sessions(id),
|
||||
constraint sessions_urls_token foreign key(token) references Tokens(id),
|
||||
constraint sessions_urls_url foreign key(url) references Urls(id)
|
||||
);
|
||||
|
||||
end;^
|
||||
|
||||
drop procedure if exists tables_update;^
|
||||
create procedure tables_update() begin
|
||||
|
||||
if (select 1 from information_schema.columns where table_schema = 'KStats' && table_name = 'Tokens' && column_name = 'enabled' limit 1) is null then
|
||||
alter table Tokens add column enabled boolean not null default true;
|
||||
end if;
|
||||
if (select 1 from information_schema.columns where table_schema = 'KStats' && table_name = 'Tokens' && column_name = 'pattern' limit 1) is null then
|
||||
alter table Tokens add column pattern varchar(2048);
|
||||
end if;
|
||||
if (select 1 from information_schema.columns where table_schema = 'KStats' && table_name = 'Tokens' && column_name = 'public' limit 1) is null then
|
||||
alter table Tokens add column public boolean not null;
|
||||
end if;
|
||||
if (select 1 from information_schema.columns where table_schema = 'KStats' && table_name = 'Tokens' && column_name = 'remarks' limit 1) is null then
|
||||
alter table Tokens add column remarks varchar(2048);
|
||||
end if;
|
||||
if (select 1 from information_schema.columns where table_schema = 'KStats' && table_name = 'SessionsUrls' && column_name = 'date_last' limit 1) is null then
|
||||
alter table SessionsUrls add column date_last datetime not null default now();
|
||||
end if;
|
||||
|
||||
end;^
|
||||
|
||||
drop procedure if exists tables_fill;^
|
||||
create procedure tables_fill() begin
|
||||
|
||||
drop temporary table if exists KStatsTTSettings;
|
||||
create temporary table KStatsTTSettings(
|
||||
id integer not null auto_increment,
|
||||
name varchar(32) not null,
|
||||
value varchar(256),
|
||||
date_in datetime not null default now(),
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
insert into KStatsTTSettings(name, value) values
|
||||
('token_alphabet', '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'),
|
||||
('token_length', 57),
|
||||
('default_value', null),
|
||||
('session_timeout', 900);
|
||||
|
||||
insert into Settings(name, value)
|
||||
select name, value from KStatsTTSettings where name not in (
|
||||
select name from Settings where date_out is null
|
||||
);
|
||||
|
||||
drop temporary table KStatsTTSettings;
|
||||
|
||||
end;^
|
||||
|
||||
-- call tables_remove();^
|
||||
call tables_create();^
|
||||
call tables_update();^
|
||||
call tables_fill();^
|
||||
|
||||
drop function if exists settings_get;^
|
||||
create function settings_get(
|
||||
$name varchar(32)
|
||||
) returns varchar(256) begin
|
||||
return ifnull(
|
||||
(select value from Settings where date_out is null && name = $name limit 1),
|
||||
(select value from Settings where date_out is null && name in ('default_value', 'value') limit 1)
|
||||
);
|
||||
end;^
|
||||
|
||||
drop function if exists settings_get_integer;^
|
||||
create function settings_get_integer(
|
||||
$name varchar(32)
|
||||
) returns integer begin
|
||||
return convert(settings_get($name), integer);
|
||||
end;^
|
||||
|
||||
drop procedure if exists token_create;^
|
||||
create procedure token_create(
|
||||
in $public boolean,
|
||||
in $pattern varchar(2048),
|
||||
in $remarks varchar(2048),
|
||||
out $error bigint,
|
||||
out $id integer,
|
||||
out $token varchar(256)
|
||||
) begin
|
||||
|
||||
set $id := 0;
|
||||
set $error := (
|
||||
(case
|
||||
when $public is null then 1 << 1
|
||||
else 0 end) |
|
||||
/*(case
|
||||
when $pattern is null then 1 << 2
|
||||
when $pattern = '' then 1 << 3
|
||||
else 0 end) |
|
||||
(case
|
||||
when $remarks is null then 1 << 4
|
||||
when $remarks = '' then 1 << 5
|
||||
else 0 end) |*/
|
||||
0
|
||||
);
|
||||
|
||||
if !$error then begin
|
||||
|
||||
declare $alphabet varchar(256) default settings_get('token_alphabet');
|
||||
declare `$length` integer default settings_get_integer('token_length');
|
||||
declare $l integer default length($alphabet);
|
||||
|
||||
while $token is null || (select 1 from Tokens where date_out is null && token = $token limit 1) is not null do
|
||||
set $token := '';
|
||||
while length($token) < `$length` do
|
||||
set $token := concat($token, substring($alphabet, floor(rand() * $l) + 1, 1));
|
||||
end while;
|
||||
end while;
|
||||
|
||||
insert into Tokens(token, public, pattern, remarks) values($token, $public, $pattern, $remarks);
|
||||
set $id := last_insert_id();
|
||||
|
||||
end;end if;
|
||||
|
||||
end;^
|
||||
|
||||
drop procedure if exists ips_get;^
|
||||
create procedure ips_get(
|
||||
in $ip varchar(39),
|
||||
out $error bigint,
|
||||
out $id integer
|
||||
) begin
|
||||
|
||||
set $error := (case
|
||||
when $ip is null then 1 << 1
|
||||
when $ip = '' then 1 << 2
|
||||
-- when $ip not regexp '^[0-9]{1,3}(\.[0-9]{1,3}){0,3}$' then 1 << 3
|
||||
else 0 end);
|
||||
|
||||
if !$error then begin
|
||||
|
||||
set $id := (select id from Ips where date_out is null && address = $ip limit 1);
|
||||
|
||||
if $id is null then begin
|
||||
insert into Ips(address) values($ip);
|
||||
set $id := last_insert_id();
|
||||
end;end if;
|
||||
|
||||
end;end if;
|
||||
|
||||
end;^
|
||||
|
||||
drop procedure if exists urls_get;^
|
||||
create procedure urls_get(
|
||||
in $url varchar(2048),
|
||||
out $error bigint,
|
||||
out $id integer
|
||||
) begin
|
||||
|
||||
set $error := (case
|
||||
when $url is null then 1 << 1
|
||||
when $url = '' then 1 << 2
|
||||
else 0 end);
|
||||
|
||||
if !$error then begin
|
||||
|
||||
set $id := (select id from Urls where date_out is null && url = $url limit 1);
|
||||
|
||||
if $id is null then begin
|
||||
insert into Urls(url) values($url);
|
||||
set $id := last_insert_id();
|
||||
end;end if;
|
||||
|
||||
end;end if;
|
||||
|
||||
end;^
|
||||
|
||||
drop function if exists token_get;^
|
||||
create function token_get(
|
||||
$token varchar(256)
|
||||
) returns boolean begin
|
||||
return (select id from Tokens where date_out is null && token = $token);
|
||||
end;^
|
||||
|
||||
/*drop function if exists token_validate;^
|
||||
create function token_validate(
|
||||
$token varchar(256),
|
||||
$url varchar(2048)
|
||||
) returns bigint begin
|
||||
return (case
|
||||
when $token is null then 1 << 0
|
||||
when $token = '' then 1 << 1'Token for YoutubeSoundsGame project.'
|
||||
when $token regexp '^[0-9]+$' && convert(integer, $token) < 1 then 1 << 2
|
||||
else ifnull((
|
||||
select (
|
||||
if(enabled, 0, 1 << 4) |
|
||||
if(pattern regexp (select url from Urls where date_out is null && (concat('', id) = $url || url = $url) limit 1), 0, 1 << 5) |
|
||||
0
|
||||
) from Tokens where date_out is null && (concat('', id) = $token || token = $token) limit 1
|
||||
), 1 << 3) end);
|
||||
end;^*/
|
||||
|
||||
drop function if exists token_validate;^
|
||||
create function token_validate(
|
||||
$token integer,
|
||||
$url varchar(2048)
|
||||
) returns bigint begin
|
||||
return (case
|
||||
when $token is null then 1 << 0
|
||||
when $token < 1 then 1 << 2
|
||||
else ifnull((
|
||||
select (
|
||||
if(enabled, 0, 1 << 4) |
|
||||
if(pattern is null || $url regexp pattern, 0, 1 << 5) |
|
||||
if(public, 0, 1 << 6) |
|
||||
0
|
||||
) from Tokens where date_out is null && id = $token limit 1
|
||||
), 1 << 3) end);
|
||||
end;^
|
||||
|
||||
drop function if exists session_url_validate;^
|
||||
create function session_url_validate(
|
||||
`$session` integer,
|
||||
$id integer
|
||||
) returns bigint begin
|
||||
return if(`$session` is null, 1 << 0, (case
|
||||
when $id is null then 1 << 1
|
||||
when $id < 1 then 1 << 2
|
||||
else ifnull((
|
||||
select (
|
||||
if(date_out is null, 0, 1 << 4) |
|
||||
if(`session` = `$session`, 0, 1 << 5) |
|
||||
0
|
||||
) from SessionsUrls where id = $id limit 1
|
||||
), 1 << 3) end));
|
||||
end;^
|
||||
|
||||
drop procedure if exists register;^
|
||||
create procedure register(
|
||||
in `$session` integer,
|
||||
in `$from` integer,
|
||||
in $token varchar(256),
|
||||
in $ip varchar(39),
|
||||
in $url varchar(2048),
|
||||
out $error bigint,
|
||||
out $current_session integer,
|
||||
out $id integer
|
||||
) begin
|
||||
|
||||
declare $ip_id integer;
|
||||
declare $ip_error bigint;
|
||||
declare $url_id integer;
|
||||
declare $url_error bigint;
|
||||
declare $token_id integer default token_get($token);
|
||||
|
||||
call ips_get($ip, $ip_error, $ip_id);
|
||||
call urls_get($url, $url_error, $url_id);
|
||||
|
||||
set $error := (
|
||||
($ip_error << 1) |
|
||||
($url_error << 5) |
|
||||
(token_validate($token_id, $url) << 8) |
|
||||
0
|
||||
);
|
||||
|
||||
if !$error then begin
|
||||
|
||||
if `$session` is null || (select 1 from Sessions where id = `$session` && date_out is null && ip = $ip_id && timestampdiff(second, now(), date_last) > settings_get_integer('session_timeout')) then begin
|
||||
insert into Sessions(ip) values($ip_id);
|
||||
set `$session` := last_insert_id();
|
||||
end;else
|
||||
update Sessions set date_last := now() where id = `$session`;
|
||||
end if;
|
||||
set $current_session := `$session`;
|
||||
|
||||
if `$from` is not null then begin
|
||||
set $error := (
|
||||
(session_url_validate(`$session`, `$from`) << 15) |
|
||||
0
|
||||
);
|
||||
if !$error then begin
|
||||
set $id := `$from`;
|
||||
update SessionsUrls set date_last := now() where id = $id;
|
||||
end;end if;
|
||||
end;else
|
||||
insert into SessionsUrls(`session`, token, url) values(`$session`, $token_id, $url_id);
|
||||
set $id := last_insert_id();
|
||||
end if;
|
||||
|
||||
end;end if;
|
||||
|
||||
end;^
|
||||
|
||||
drop view if exists SessionsView;^
|
||||
create view SessionsView as select
|
||||
sessions.id as id,
|
||||
sessions.ip as ip_id,
|
||||
ips.address as ip,
|
||||
sessions.date_in as date_in,
|
||||
sessions.date_last as date_last,
|
||||
sessions.date_out as date_out,
|
||||
timestampdiff(second, sessions.date_in, ifnull(sessions.date_out, sessions.date_last)) as `time`,
|
||||
ips.date_in as ip_date_in
|
||||
from Sessions sessions
|
||||
join Ips ips on sessions.ip = ips.id
|
||||
where ips.date_out is null;^
|
||||
|
||||
drop view if exists SessionsUrlsView;^
|
||||
create view SessionsUrlsView as select
|
||||
sessions_urls.id as id,
|
||||
sessions.id as session_id,
|
||||
sessions.ip_id as ip_id,
|
||||
sessions.ip as ip,
|
||||
urls.id as url_id,
|
||||
urls.url as url,
|
||||
sessions_urls.date_in as date_in,
|
||||
sessions_urls.date_last as date_last,
|
||||
timestampdiff(second, sessions_urls.date_in, sessions_urls.date_last) as `time`,
|
||||
sessions.date_in as session_date_in,
|
||||
sessions.date_last as session_date_last,
|
||||
sessions.date_out as session_date_out,
|
||||
sessions.ip_date_in as ip_date_in,
|
||||
sessions.`time` as session_time,
|
||||
urls.date_in as url_date_in
|
||||
from SessionsUrls sessions_urls
|
||||
join SessionsView sessions on sessions_urls.`session` = sessions.id
|
||||
join Urls urls on sessions_urls.url = urls.id
|
||||
where
|
||||
sessions_urls.date_out is null &&
|
||||
urls.date_out is null;^
|
||||
|
||||
delimiter ;
|
302
PHP/KStats.php
Executable file
302
PHP/KStats.php
Executable file
@ -0,0 +1,302 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
|
||||
class KStats{
|
||||
|
||||
private static $url = null;
|
||||
private static $default_settings = [
|
||||
"engine" => "mysql",
|
||||
"database" => "KStats",
|
||||
"host" => "localhost",
|
||||
"port" => 3306,
|
||||
"charset" => "utf8",
|
||||
"user" => "root",
|
||||
"password" => "",
|
||||
"connection_string" => "{engine}:dbname={database};host={host};port={port};charset={charset}",
|
||||
"allow_all" => false,
|
||||
"data_key" => "kstats_data",
|
||||
"ip_keys_ordered" => ["HTTP_CF_CONNECTING_IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_REAL_IP", "HTTP_CLIENT_IP", "REMOTE_ADDR"]
|
||||
];
|
||||
private $input = [];
|
||||
private $connection = null;
|
||||
private $token = null;
|
||||
private $type = null;
|
||||
private $method = null;
|
||||
private $mode = null;
|
||||
private $id = null;
|
||||
private $query = null;
|
||||
private $session = null;
|
||||
private $request_data = null;
|
||||
|
||||
public static function is_dictionary($value){
|
||||
return is_array($value) && array_values($value) != $value;
|
||||
}
|
||||
|
||||
public static function is_secure(){
|
||||
return (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") || $_SERVER["SERVER_PORT"] == 443;
|
||||
}
|
||||
|
||||
private static function get_url(){
|
||||
return self::$url ? self::$url : (self::$url = (
|
||||
isset($_SERVER["HTTP_REFERER"]) ?
|
||||
$_SERVER["HTTP_REFERER"] :
|
||||
"http" . (self::is_secure() ? "s" : "") . "://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]
|
||||
));
|
||||
}
|
||||
|
||||
public function default_value($default = null, $nulls = null){
|
||||
return $default !== null || (is_bool($nulls) ? $nulls : $this->settings("nulls", null, false, false)) ? $default : $this->settings(["default_value", "default"], null, null, true);
|
||||
}
|
||||
|
||||
private function settings($names = null, $inputs = null, $default = null, $nulls = null){
|
||||
if(!$names)
|
||||
return $this->default_value($default, $nulls);
|
||||
|
||||
!is_bool($nulls) && ($nulls = $this->settings("nulls", null, false, false));
|
||||
!is_array($names) && ($names = [$names]);
|
||||
|
||||
foreach(array_merge(is_array($inputs) ? (self::is_dictionary($inputs) ? [$input] : $input) : [], [$this->input, self::$default_settings]) as $input)
|
||||
if(self::is_dictionary($input))
|
||||
foreach($names as $name)
|
||||
if($name && isset($input[$name]) && ($nulls || $input[$name] !== null))
|
||||
return $input[$name];
|
||||
return $this->default_value($default, $nulls);
|
||||
}
|
||||
|
||||
public function get_ip(){
|
||||
foreach($this->settings("ip_keys_ordered") as $key){
|
||||
if(!empty($_SERVER[$key]))
|
||||
return explode(",", $_SERVER[$key])[0];
|
||||
if($ips = getenv($key))
|
||||
return explode(",", $ips)[0];
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
private function get_token(){
|
||||
return preg_replace('/^\/api\/([^\/]+)(\/.*)?$/', "$1", $_SERVER["REQUEST_URI"]);
|
||||
}
|
||||
|
||||
public static function string_variables($string, $variables = null, $default = null){
|
||||
|
||||
if(!is_array($variables))
|
||||
$variables = [];
|
||||
elseif(self::is_dictionary($variables))
|
||||
$variables = [$variables];
|
||||
|
||||
return preg_replace_callback('/\{([^\{\}]+)\}/', function($values) use($variables){
|
||||
foreach($variables as $set)
|
||||
if(isset($set[$values[1]]))
|
||||
return $set[$values[1]];
|
||||
return $values[0];
|
||||
}, $string);
|
||||
}
|
||||
|
||||
private function query($query, $variables){
|
||||
|
||||
$used = [];
|
||||
$results = [
|
||||
"tables" => [],
|
||||
"variables" => []
|
||||
];
|
||||
|
||||
if(!is_array($variables))
|
||||
$variables = [];
|
||||
elseif(self::is_dictionary($variables))
|
||||
$variables = [$variables];
|
||||
|
||||
preg_replace_callback('/\@([a-zA-Z0-9_]+)/', function($values) use(&$used){
|
||||
!in_array($values[1], $used) && ($used[] = $values[1]);
|
||||
}, is_array($variables) ? ($query = preg_replace_callback('/\{([^\{\}]+)\}/', function($values) use($variables){
|
||||
foreach($variables as $set)
|
||||
if(isset($set[$values[1]]))
|
||||
return (
|
||||
$set[$values[1]] === null ? "null" : (
|
||||
is_bool($set[$values[1]]) ? ($set[$values[1]] ? "true" : "false") : (
|
||||
is_string($set[$values[1]]) ? "'" . preg_replace('/([\\\\\'])/', "\\\\$1", $set[$values[1]]) . "'" : (
|
||||
$set[$values[1]]
|
||||
))));
|
||||
return "null";
|
||||
}, $query)) : $query);
|
||||
|
||||
if(!empty($used)){
|
||||
$subquery = "";
|
||||
foreach($used as $key)
|
||||
$subquery .= ($subquery ? "," : "") . " @" . $key . " as '" . $key . "'";
|
||||
$query .= (preg_match('/;$/', $query) ? "" : ";") . "select" . $subquery . ";";
|
||||
}
|
||||
|
||||
if(!$this->connection){
|
||||
$this->connection = new \PDO(self::string_variables($this->settings(["connection_string", "string_connection"]), [
|
||||
"engine" => $this->settings(["connection_engine", "engine"]),
|
||||
"database" => $this->settings(["connection_database", "database"]),
|
||||
"host" => $this->settings(["connection_host", "host"]),
|
||||
"port" => $this->settings(["connection_port", "port"]),
|
||||
"charset" => $this->settings(["connection_charset", "charset"])
|
||||
]), $this->settings(["connection_user", "user"]), $this->settings(["connection_password", "password"]));
|
||||
$this->connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
$this->connection->beginTransaction();
|
||||
};
|
||||
|
||||
$this->query = $query;
|
||||
|
||||
($statement = $this->connection->prepare($query))->execute();
|
||||
|
||||
do{
|
||||
try{
|
||||
$table = [];
|
||||
foreach($statement->rowCount() == 0 ? [] : $statement->fetchAll(\PDO::FETCH_ASSOC) as $new_row){
|
||||
$row = [];
|
||||
foreach($new_row as $key => $value){
|
||||
if($value && is_string($value) && in_array($value[0], ["[", "{"])){
|
||||
try{
|
||||
$row[$key] = json_decode(utf8_encode($value), true);
|
||||
}catch(\Exception $exception){}
|
||||
!$row[$key] && ($row[$key] = utf8_encode($value));
|
||||
}else
|
||||
$row[$key] = $value;
|
||||
};
|
||||
$table[] = $row;
|
||||
};
|
||||
$results["tables"][] = $table;
|
||||
}catch(\Exception $exception){};
|
||||
}while($statement->nextRowset());
|
||||
|
||||
if(preg_match('/(,\s+?|\()\@/', $query)){
|
||||
$l = count($results["tables"]) - 1;
|
||||
foreach($results["tables"][$l][0] as $key => $value)
|
||||
$results["variables"][$key] = $value;
|
||||
unset($results["tables"][$l]);
|
||||
};
|
||||
|
||||
$this->connection->commit();
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function save(){
|
||||
|
||||
$results = null;
|
||||
|
||||
if(!in_array($this->type, ["js", "ecma"]) || $this->settings("allow_all")){
|
||||
|
||||
// isset($_SERVER["HTTP_REFERER"]) &&
|
||||
$results = $this->query("call register({session}, {from}, {token}, {ip}, {url}, @error, @current_session, @id);", [
|
||||
"session" => $this->session ? $this->session : null,
|
||||
"from" => $this->id ? $this->id : null,
|
||||
"token" => $this->get_token(),
|
||||
"ip" => $this->get_ip(),
|
||||
"url" => $this->request_data && isset($this->request_data["url"]) ? $this->request_data["url"] : self::get_url()
|
||||
]);
|
||||
|
||||
$results &&
|
||||
($_SESSION["kstats_id"] = $results["variables"]["current_session"]);
|
||||
|
||||
};
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function print($data){
|
||||
|
||||
switch($this->type){
|
||||
case "js":
|
||||
header("content-type: text/javascript");
|
||||
echo file_get_contents(__DIR__ . "/../Public/js/KStats.js");
|
||||
break;
|
||||
case "ecma":
|
||||
header("content-type: text/javascript");
|
||||
echo file_get_contents(__DIR__ . "/../Public/ecma/KStats.ecma.js");
|
||||
break;
|
||||
case "image":
|
||||
case "img":
|
||||
header("content-type: image/png");
|
||||
echo file_get_contents(__DIR__ . "/../Public/images/min.png");
|
||||
break;
|
||||
case "css":
|
||||
header("content-type: text/css");
|
||||
echo "kstats-tag-link::after{content : '" . $data . "';}";
|
||||
break;
|
||||
case "json":
|
||||
header("content-type: application/json");
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"code" => 200,
|
||||
"data" => $data
|
||||
]);
|
||||
break;
|
||||
case "test":
|
||||
header("content-type: text/javascript");
|
||||
echo "console.log(" . json_encode([
|
||||
"session" => $_SESSION
|
||||
]) . ");console.log(document.cookie.split(';'));";
|
||||
break;
|
||||
default:
|
||||
header("content-type: text/plain");
|
||||
echo "";
|
||||
break;
|
||||
};
|
||||
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
||||
public function __construct($input = null){
|
||||
|
||||
is_array($input) && ($this->input = $input);
|
||||
|
||||
if(preg_match('/^\/api\/([^\/]+)\/([^\/]+)\/([^\/]+)\/([^\/\?]+)(\/([^\?]+))?/', $_SERVER["REQUEST_URI"], $matches)){
|
||||
|
||||
$data_key = $this->settings("data_key");
|
||||
|
||||
$this->token = $matches[1];
|
||||
$this->session = intval($matches[2]);
|
||||
$this->type = $matches[3];
|
||||
|
||||
foreach([$_POST, $_GET, $_COOKIE] as $set)
|
||||
if(isset($set[$data_key])){
|
||||
$this->request_data = json_decode(base64_decode(urldecode($set[$data_key])), true);
|
||||
break;
|
||||
};
|
||||
|
||||
// print_r(["request_data", $this->request_data, "get" => $_GET]);
|
||||
|
||||
switch($this->method = $matches[4]){
|
||||
case "set":
|
||||
isset($matches[6]) && $matches[6] && ($this->id = intval($matches[6]));
|
||||
$response = $this->save();
|
||||
$this->print(array_merge(is_array($response) ? $response : [], [
|
||||
"url" => self::get_url(),
|
||||
"query" => $this->query
|
||||
]));
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
$this->print(false);
|
||||
|
||||
}
|
||||
|
||||
public function close(){
|
||||
|
||||
if($this->connection){
|
||||
try{
|
||||
$this->connection->commit();
|
||||
}catch(\Exception $exception){
|
||||
try{
|
||||
$this->connection->rollback();
|
||||
}catch(\Exception $subexception){};
|
||||
};
|
||||
};
|
||||
$this->connection = null;
|
||||
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
|
||||
$this->close();
|
||||
|
||||
}
|
||||
|
||||
};
|
8
PHP/include.php
Executable file
8
PHP/include.php
Executable file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
foreach([
|
||||
"KStats",
|
||||
"KStats.Secrets"
|
||||
] as $file)
|
||||
if(file_exists($file = __DIR__ . "/" . $file . ".php"))
|
||||
include $file;
|
7
Public/.htaccess
Executable file
7
Public/.htaccess
Executable file
@ -0,0 +1,7 @@
|
||||
Header set Access-Control-Allow-Origin "*"
|
||||
RewriteEngine On
|
||||
#RewriteCond %{REQUEST_METHOD} OPTIONS
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
#RewriteCond %{REQUEST_URI} !^/index.php$
|
||||
RewriteRule ^api(.*)$ /api/index.php [NC,L,QSA]
|
5
Public/api/index.php
Executable file
5
Public/api/index.php
Executable file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
include __DIR__ . "/../../PHP/include.php";
|
||||
|
||||
$kstats = new KStats(KStats\Secrets::connection);
|
247
Public/ecma/KStats.ecma.js
Executable file
247
Public/ecma/KStats.ecma.js
Executable file
@ -0,0 +1,247 @@
|
||||
KStats = function(input){
|
||||
|
||||
const self = this,
|
||||
default_settings = {
|
||||
autostart : true,
|
||||
nulls : false,
|
||||
default_vaalue : null,
|
||||
ajax_timeout : 2000,
|
||||
settings_overwrite : false,
|
||||
kstats_url : "https://kstats.k3y.pw/api/uCDY3brWxEJrJywm2sFcKo1d8oaUdmxTTrv3VGuhpyRDpPYXyKeHWeknh/{session}/ecma/set",
|
||||
frames_per_second : 1,
|
||||
milliseconds_per_connection : 2000,
|
||||
session_cookie_name : "kstats_session_id",
|
||||
session_timeout : 60000,
|
||||
data_key : "kstats_data"
|
||||
},
|
||||
custom = {},
|
||||
threads = [];
|
||||
let started = false,
|
||||
thread = null,
|
||||
last_connection = 0,
|
||||
milliseconds_per_connection = null,
|
||||
register_thread = null,
|
||||
id = null,
|
||||
url = null,
|
||||
session = null,
|
||||
data_key = null;
|
||||
|
||||
const default_value = this.default_value = (_default, nulls) => _default !== undefined && (_default !== null || (typeof nulls == "boolean" ? nulls : settings("nulls", null, false, false))) ? _default : settings(["default_value", "default"], null, null, true);
|
||||
|
||||
const settings = this.settings = (names, inputs, _default, nulls) => {
|
||||
if(!names)
|
||||
return default_value(_default, nulls);
|
||||
|
||||
const l = (names.push ? names : names = [names]).length,
|
||||
m = (inputs = (inputs ? inputs.push ? inputs : [inputs] : []).concat([input, custom, default_settings])).length;
|
||||
|
||||
typeof nulls != "boolean" && (nulls = settings("nulls", null, false, false));
|
||||
|
||||
for(let j = 0; j < m; j ++)
|
||||
if(typeof inputs[j] == "object")
|
||||
for(let i = 0; i < l; i ++)
|
||||
if(names[i] && inputs[j][names[i]] !== undefined && (nulls || inputs[j][names[i]] !== null))
|
||||
return inputs[j][names[i]];
|
||||
return default_value(_default, nulls);
|
||||
};
|
||||
|
||||
const load = this.load = (url, callback) => {
|
||||
|
||||
let ended = false;
|
||||
const ajax = new XMLHttpRequest(),
|
||||
timeout = settings(["ajax_timeout", "load_timeout", "timeout"]),
|
||||
date = Date.now(),
|
||||
end = message => {
|
||||
if(ended)
|
||||
return;
|
||||
ended = true;
|
||||
typeof callback == "function" && callback(ajax.responseText, ajax.status, ajax.readyState, message == "OK", message);
|
||||
};
|
||||
|
||||
ajax.open("get", url, true);
|
||||
ajax.timeout = timeout;
|
||||
ajax.onreadystatechange = () => {
|
||||
if(ended)
|
||||
return;
|
||||
if(ajax.readyState == 4)
|
||||
end((ajax.status >= 200 && ajax.status < 300) || [301, 302, 304].includes(ajax.status) ? "OK" : "HTTP_ERROR");
|
||||
else if(Date.now() - date > timeout)
|
||||
end("FORCED_TIMEOUT");
|
||||
};
|
||||
ajax.send(null);
|
||||
|
||||
ajax.onabort = () => end("ABORTED"),
|
||||
ajax.onerror = () => end("ERROR");
|
||||
ajax.ontimeout = () => end("TIMEOUT");
|
||||
|
||||
return ajax;
|
||||
};
|
||||
|
||||
const settings_add_i = (items, overwrite, callback, i) => {
|
||||
|
||||
if(i >= items.length){
|
||||
typeof callback == "function" && callback();
|
||||
return;
|
||||
};
|
||||
|
||||
if(items[i]){
|
||||
if(typeof items[i] == "string"){
|
||||
|
||||
let json;
|
||||
|
||||
try{
|
||||
json = JSON.parse(items[i]);
|
||||
}catch(exception){};
|
||||
|
||||
if(json)
|
||||
settings_add_i(json.push ? json : [json], overwrite, end, 0);
|
||||
else
|
||||
load(json, response => {
|
||||
try{
|
||||
json = JSON.parse(response);
|
||||
}catch(exception){};
|
||||
if(json)
|
||||
settings_add_i(json.push ? json : [json], overwrite, end, 0);
|
||||
else
|
||||
end();
|
||||
});
|
||||
|
||||
return;
|
||||
};
|
||||
if(typeof items[i] == "object"){
|
||||
if(items[i].push){
|
||||
settings_add_i(items[i], overwrite, end, 0);
|
||||
return;
|
||||
};
|
||||
for(const key in items[i])
|
||||
(overwrite || custom[key] === undefined) && (custom[key] = items[i][key]);
|
||||
};
|
||||
};
|
||||
|
||||
end();
|
||||
|
||||
};
|
||||
|
||||
const settings_add = this.settings_add = (items, overwrite, callback) => settings_add_i(items ? items.push ? items : [items] : [], typeof overwrite == "boolean" ? overwrite : settings(["settings_overwrite", "overwrite"]), callback, 0);
|
||||
|
||||
const threads_method = () => threads.forEach(thread => thread && thread());
|
||||
|
||||
const threads_start = this.threads_start = () => thread === null && (thread = setInterval(threads_method, 1000 / settings(["frames_per_second", "fps"])));
|
||||
|
||||
this.threads_stop = () => {
|
||||
if(thread === null)
|
||||
return;
|
||||
|
||||
clearInterval(thread);
|
||||
thread = null;
|
||||
|
||||
};
|
||||
|
||||
const threads_add = this.threads_add = method => {
|
||||
if(typeof method != "function")
|
||||
return null;
|
||||
|
||||
let i = 0;
|
||||
const l = threads.length;
|
||||
|
||||
for(; i < l; i ++)
|
||||
if(!threads[i])
|
||||
break;
|
||||
|
||||
threads[i] = method;
|
||||
|
||||
return i;
|
||||
};
|
||||
|
||||
const threads_remove = this.threads_remove = i => !isNaN(i) && threads[i] && (threads[i] = null);
|
||||
|
||||
const string_variables = this.string_variables = (string, variables, _default) => {
|
||||
|
||||
if(!variables)
|
||||
variables = [];
|
||||
else if(!variables.push)
|
||||
variables = [variables];
|
||||
|
||||
for(let i = variables.length - 1; i >= 0; i --)
|
||||
typeof variables[i] != "object" && (variables = variables.splice(i, 1));
|
||||
|
||||
const l = variables.length;
|
||||
|
||||
return string.replace(/\{([^\{\}]+)\}/g, (...arguments) => {
|
||||
for(let i = 0; i < l; i ++)
|
||||
if(variables[i][arguments[1]] !== undefined)
|
||||
return variables[i][arguments[1]];
|
||||
return _default !== undefined ? _default : arguments[0];
|
||||
});
|
||||
};
|
||||
|
||||
const update = () => load(tmp = string_variables(url || (url = settings(["kstats_url", "url"])), {
|
||||
session : session
|
||||
}) + (id ? "/" + id : "") + "?" + (data_key || (data_key = settings("data_key"))) + "=" + btoa(JSON.stringify({
|
||||
url : window.location.href.replace(/^([^#]+)(\#.*)?$/, "$1")
|
||||
})), (...arguments) => {
|
||||
if(!arguments[0])
|
||||
return;
|
||||
|
||||
const data = JSON.parse(arguments[0]),
|
||||
current_session = Number(data.data.variables.current_session);
|
||||
|
||||
session != current_session && (document.cookie = settings("session_cookie_name") + "=" + (session = current_session) + ";expires=" + new Date(Date.now() + settings("session_timeout")).toUTCString() + ";path=/;SameSite=Lax");
|
||||
|
||||
if(id === null){
|
||||
id = data.data.variables.id;
|
||||
addEventListener("beforeunload", update);
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
const register_event = () => {
|
||||
|
||||
const date = Date.now();
|
||||
|
||||
if(date - last_connection > milliseconds_per_connection){
|
||||
last_connection = date;
|
||||
update();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
this.start = () => {
|
||||
|
||||
if(started)
|
||||
return;
|
||||
started = true;
|
||||
|
||||
settings_add(settings("settings_files"), true, () => {
|
||||
|
||||
const session_pattern = new RegExp("^" + settings("session_cookie_name") + "=(.+)$");
|
||||
|
||||
milliseconds_per_connection = settings("milliseconds_per_connection");
|
||||
|
||||
!decodeURIComponent(document.cookie).split(";").some(cookie => {
|
||||
|
||||
const matches = cookie.trim().match(session_pattern);
|
||||
|
||||
if(matches){
|
||||
session = Number(matches[1]);
|
||||
return true;
|
||||
};
|
||||
|
||||
}) && (session = 0);
|
||||
|
||||
threads_start();
|
||||
register_thread = threads_add(register_event);
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
const construct = () => {
|
||||
|
||||
settings("autostart") && self.start();
|
||||
|
||||
};
|
||||
|
||||
construct();
|
||||
|
||||
};
|
4
Public/git_update.php
Executable file
4
Public/git_update.php
Executable file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
header("content-type: text/plain");
|
||||
echo shell_exec("git pull 2>&1");
|
BIN
Public/images/min.png
Executable file
BIN
Public/images/min.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 546 B |
33
Public/tests/cookies.html
Executable file
33
Public/tests/cookies.html
Executable file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<title data-i18n="contact_book_title">ContactBook</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" charset="utf-8">
|
||||
|
||||
let session = null;
|
||||
|
||||
console.log(document.cookie);
|
||||
|
||||
!decodeURIComponent(document.cookie).split(";").some(cookie => {
|
||||
|
||||
const matches = cookie.trim().match(/^session_id_test\=(.*)$/);
|
||||
|
||||
if(matches){
|
||||
session = Number(matches[1]);
|
||||
return true;
|
||||
};
|
||||
|
||||
}) &&
|
||||
(document.cookie = "session_id_test=" + (session = Math.random() * 999999 >> 0) + ";expires=" + new Date(Date.now() + 60000).toUTCString() + ";path=/");
|
||||
|
||||
console.log(session);
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
23
Public/tests/sessions.php
Executable file
23
Public/tests/sessions.php
Executable file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
if(isset($_GET["del"])){
|
||||
session_destroy();
|
||||
// setcookie("id", null, time() - 3600, "/cookies/", "kstats.local", false, true);
|
||||
};
|
||||
if(!isset($_COOKIE["id"])){
|
||||
setcookie("id", random_int(0, 999999), [
|
||||
"expires" => time() + (86400 * 30),
|
||||
"path" => "/",
|
||||
"domain" => $_SERVER['SERVER_NAME'],
|
||||
"secure" => false,
|
||||
"httponly" => true,
|
||||
"samesite" => "Strict"
|
||||
]);
|
||||
echo "PASA<br />\n";
|
||||
print_r(array_keys($_COOKIE));
|
||||
};
|
||||
echo (
|
||||
(isset($_SESSION["id"]) ? $_SESSION["id"] : $_SESSION["id"] = random_int(0, 99999999)) . "<br />\n" .
|
||||
$_COOKIE["id"]
|
||||
);
|
29
Public/tests/test.html
Executable file
29
Public/tests/test.html
Executable file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<title data-i18n="contact_book_title">ContactBook</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
|
||||
<!-- <script data-type="text/javascript" data-language="EMCAScript 2015" src="https://kstats.k3y.pw/api/uCDY3brWxEJrJywm2sFcKo1d8oaUdmxTTrv3VGuhpyRDpPYXyKeHWeknh/{session}/ecma/set" data-crossorigin="anonymous" charset="utf-8"></script> -->
|
||||
<!-- <script data-type="text/javascript" data-language="EMCAScript 2015" src="/api/uCDY3brWxEJrJywm2sFcKo1d8oaUdmxTTrv3VGuhpyRDpPYXyKeHWeknh/{session}/ecma/set" data-crossorigin="anonymous" charset="utf-8"></script> -->
|
||||
<!-- <script data-type="text/javascript" data-language="EMCAScript 2015" src="https://kstats.k3y.pw/ecma/KStats.ecma.js" data-crossorigin="anonymous" charset="utf-8"></script> -->
|
||||
<script data-type="text/javascript" data-language="EMCAScript 2015" src="/ecma/KStats.ecma.js" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" charset="utf-8">
|
||||
|
||||
kstats = new KStats({
|
||||
// url : "https://kstats.k3y.pw/api/uCDY3brWxEJrJywm2sFcKo1d8oaUdmxTTrv3VGuhpyRDpPYXyKeHWeknh/{session}/json/set"
|
||||
url : "/api/uCDY3brWxEJrJywm2sFcKo1d8oaUdmxTTrv3VGuhpyRDpPYXyKeHWeknh/{session}/json/set"
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<!-- <script data-type="text/javascript" data-language="JavaScript 1.8.5" src="https://kstats.k3y.pw/api/uCDY3brWxEJrJywm2sFcKo1d8oaUdmxTTrv3VGuhpyRDpPYXyKeHWeknh/{session}/test/set" data-crossorigin="anonymous" charset="utf-8"></script> -->
|
||||
<!-- <script data-type="text/javascript" data-language="JavaScript 1.8.5" src="/api/uCDY3brWxEJrJywm2sFcKo1d8oaUdmxTTrv3VGuhpyRDpPYXyKeHWeknh/{session}/test/set" data-crossorigin="anonymous" charset="utf-8"></script> -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<a href="tests">Test</a>
|
||||
</body>
|
||||
</html>
|
6
Public/wmd.php
Executable file
6
Public/wmd.php
Executable file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
include __DIR__ . "/../../WMarkDown/PHP/include.php";
|
||||
include __DIR__ . "/../PHP/KStats.Secrets.php";
|
||||
|
||||
$wmd = new WMarkDown(KStats\Secrets::wmarkdown);
|
21
Public/wmd_scripts.php
Executable file
21
Public/wmd_scripts.php
Executable file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
include __DIR__ . "/../../WMarkDown/PHP/include.php";
|
||||
include __DIR__ . "/../PHP/KStats.Secrets.php";
|
||||
|
||||
$wmd = new WMarkDown(array_merge([
|
||||
"action" => "update_scripts",
|
||||
"author" => "KyMAN",
|
||||
"project" => "KStats",
|
||||
"class" => "KStats",
|
||||
"object" => "kstats",
|
||||
"url" => "https://kstats.k3y.pw",
|
||||
"project_author" => "KyMAN",
|
||||
"key_words" => "contact,book,contact book,kyman,secrets,notes",
|
||||
"logo" => "/images/KStats.png",
|
||||
"language" => "es",
|
||||
"wmd_file" => "/../WMarkDown/HTML/script.w.md",
|
||||
"wmd_file_empty" => "/../WMarkDown/HTML/file.w.md",
|
||||
"ignore_script_paths" => [],
|
||||
"only" => "/Public"
|
||||
], KStats\Secrets::wmarkdown));
|
24
WMD/dev/ECMAScript/index.w.md
Executable file
24
WMD/dev/ECMAScript/index.w.md
Executable file
@ -0,0 +1,24 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# ECMAScript
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/dev/Public/ecma/KStats.ecma.js.w.md]]
|
||||
|
||||
|
||||
|
||||
[[html_data {
|
||||
"title" : "ECMAScript - KStats",
|
||||
"url" : "https://kstats.k3y.pw/dev/ECMAScript/index.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "contact,book,contact book,kyman,secrets,notes,developt,desarrollo,programación,ecmascript",
|
||||
"description" : "Parte ECMAScript del KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
36
WMD/dev/PHP/index.w.md
Executable file
36
WMD/dev/PHP/index.w.md
Executable file
@ -0,0 +1,36 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# PHP
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/dev/Public/api/index.php.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/dev/Public/git_update.php.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/dev/Public/tests/sessions.php.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/dev/Public/wmd.php.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/dev/Public/wmd_scripts.php.w.md]]
|
||||
|
||||
|
||||
|
||||
[[html_data {
|
||||
"title" : "PHP - KStats",
|
||||
"url" : "https://kstats.k3y.pw/dev/PHP/index.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "contact,book,contact book,kyman,secrets,notes,developt,desarrollo,programación,php",
|
||||
"description" : "Parte PHP del KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
23
WMD/dev/Public/api/index.php.w.md
Executable file
23
WMD/dev/Public/api/index.php.w.md
Executable file
@ -0,0 +1,23 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# index.php
|
||||
|
||||
```txt
|
||||
/Public/api/index.php
|
||||
```
|
||||
|
||||
[[html_data {
|
||||
"title" : "index.php - KStats",
|
||||
"url" : "https://kstats.k3y.pw/Public/api/index.php.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "contact,book,contact book,kyman,secrets,notes,developt,desarrollo,programación,main",
|
||||
"description" : "index.php del KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
268
WMD/dev/Public/ecma/KStats.ecma.js.w.md
Executable file
268
WMD/dev/Public/ecma/KStats.ecma.js.w.md
Executable file
@ -0,0 +1,268 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# KStats.ecma.js
|
||||
|
||||
```txt
|
||||
/Public/ecma/KStats.ecma.js
|
||||
```
|
||||
|
||||
## [[plain KStats.default_value]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.default_value
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash a1841f42c4352bb7f9f7bb87f89ff6fb
|
||||
#_default - optional Parámetro _default
|
||||
#nulls - optional Parámetro nulls
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.settings]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.settings
|
||||
@see KStats.default_value
|
||||
@see KStats.settings
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash 97e5deffc108b21fd26d5aa45248e1e0
|
||||
#names - optional Parámetro names
|
||||
#inputs - optional Parámetro inputs
|
||||
#_default - optional Parámetro _default
|
||||
#nulls - optional Parámetro nulls
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.load]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.load
|
||||
@see KStats.settings
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash 5d29594ed33dec2bfa759d0f4dc71d16
|
||||
#url - optional Parámetro url
|
||||
#callback - optional Parámetro callback
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.settings_add_i]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.settings_add_i
|
||||
@see KStats.settings_add_i
|
||||
@see KStats.load
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access private
|
||||
@hash f91128cfea61bf0ad16c2d04ba1a1822
|
||||
#items - optional Parámetro items
|
||||
#overwrite - optional Parámetro overwrite
|
||||
#callback - optional Parámetro callback
|
||||
#i - optional Parámetro i
|
||||
]]
|
||||
|
||||
## [[plain KStats.settings_add]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.settings_add
|
||||
@see KStats.settings_add_i
|
||||
@see KStats.settings
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash e6787641e9592c9293090db05ce49585
|
||||
#items - optional Parámetro items
|
||||
#overwrite - optional Parámetro overwrite
|
||||
#callback - optional Parámetro callback
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.threads_method]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.threads_method
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access private
|
||||
@hash ab9bbde1ed980d410067bd829ca8d957
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.threads_start]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.threads_start
|
||||
@see KStats.settings
|
||||
@see KStats.threads_method
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash 1090cef55ff368e19f68fb0f13262eb0
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.threads_stop]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.threads_stop
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash c1b6d79c278d28a090faf96255fa0c34
|
||||
]]
|
||||
|
||||
## [[plain KStats.threads_add]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.threads_add
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash 7b36976fb1531ed998a2a76196d98172
|
||||
#method - optional Parámetro method
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.threads_remove]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.threads_remove
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash e005119bc808e1eefdbfec228fac6441
|
||||
#i - optional Parámetro i
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.string_variables]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.string_variables
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash e372ccebccaf8f8d06c24f79d629e7a6
|
||||
#string - optional Parámetro string
|
||||
#variables - optional Parámetro variables
|
||||
#_default - optional Parámetro _default
|
||||
]]
|
||||
|
||||
## [[plain KStats.update]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.update
|
||||
@see KStats.load
|
||||
@see KStats.string_variables
|
||||
@see KStats.settings
|
||||
@see KStats.update
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access private
|
||||
@hash 735287af679b35ef121b59e52ba3dbab
|
||||
#return - - Retorno.
|
||||
]]
|
||||
|
||||
## [[plain KStats.register_event]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.register_event
|
||||
@see KStats.update
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access private
|
||||
@hash b6094c4945ffa697ddde38d0158e4f7e
|
||||
]]
|
||||
|
||||
## [[plain KStats.start]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.start
|
||||
@see KStats.settings_add
|
||||
@see KStats.settings
|
||||
@see KStats.threads_start
|
||||
@see KStats.threads_add
|
||||
@see KStats.register_event
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access public
|
||||
@hash 0414214855b51d79636becf6f5b3bdc1
|
||||
]]
|
||||
|
||||
## [[plain KStats.construct]]
|
||||
|
||||
[[wdoc
|
||||
Método object.
|
||||
@name KStats.construct
|
||||
@see KStats.settings
|
||||
@see KStats.start
|
||||
@lang ECMAScript
|
||||
@author KyMAN
|
||||
@since 20220320
|
||||
@version 20220320
|
||||
@access private
|
||||
@hash 88422b1f098ab1ff14b3b73c5b3f48f5
|
||||
]]
|
||||
|
||||
[[html_data {
|
||||
"title" : "KStats.ecma.js - KStats",
|
||||
"url" : "https://kstats.k3y.pw/Public/ecma/KStats.ecma.js.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "contact,book,contact book,kyman,secrets,notes,developt,desarrollo,programación,cma",
|
||||
"description" : "KStats.ecma.js del KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
23
WMD/dev/Public/git_update.php.w.md
Executable file
23
WMD/dev/Public/git_update.php.w.md
Executable file
@ -0,0 +1,23 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# git_update.php
|
||||
|
||||
```txt
|
||||
/Public/git_update.php
|
||||
```
|
||||
|
||||
[[html_data {
|
||||
"title" : "git_update.php - KStats",
|
||||
"url" : "https://kstats.k3y.pw/Public/git_update.php.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "contact,book,contact book,kyman,secrets,notes,developt,desarrollo,programación,main",
|
||||
"description" : "git_update.php del KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
23
WMD/dev/Public/tests/sessions.php.w.md
Executable file
23
WMD/dev/Public/tests/sessions.php.w.md
Executable file
@ -0,0 +1,23 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# sessions.php
|
||||
|
||||
```txt
|
||||
/Public/tests/sessions.php
|
||||
```
|
||||
|
||||
[[html_data {
|
||||
"title" : "sessions.php - KStats",
|
||||
"url" : "https://kstats.k3y.pw/Public/tests/sessions.php.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "contact,book,contact book,kyman,secrets,notes,developt,desarrollo,programación,main",
|
||||
"description" : "sessions.php del KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
23
WMD/dev/Public/wmd.php.w.md
Executable file
23
WMD/dev/Public/wmd.php.w.md
Executable file
@ -0,0 +1,23 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# wmd.php
|
||||
|
||||
```txt
|
||||
/Public/wmd.php
|
||||
```
|
||||
|
||||
[[html_data {
|
||||
"title" : "wmd.php - KStats",
|
||||
"url" : "https://kstats.k3y.pw/Public/wmd.php.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "contact,book,contact book,kyman,secrets,notes,developt,desarrollo,programación,main",
|
||||
"description" : "wmd.php del KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
23
WMD/dev/Public/wmd_scripts.php.w.md
Executable file
23
WMD/dev/Public/wmd_scripts.php.w.md
Executable file
@ -0,0 +1,23 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# wmd_scripts.php
|
||||
|
||||
```txt
|
||||
/Public/wmd_scripts.php
|
||||
```
|
||||
|
||||
[[html_data {
|
||||
"title" : "wmd_scripts.php - KStats",
|
||||
"url" : "https://kstats.k3y.pw/Public/wmd_scripts.php.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "contact,book,contact book,kyman,secrets,notes,developt,desarrollo,programación,main",
|
||||
"description" : "wmd_scripts.php del KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
0
WMD/dev/index.w.md
Executable file
0
WMD/dev/index.w.md
Executable file
52
WMD/es/bugs.w.md
Executable file
52
WMD/es/bugs.w.md
Executable file
@ -0,0 +1,52 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220402,
|
||||
"version" : 20220402
|
||||
}]]
|
||||
# Bugs y errores
|
||||
|
||||
En esta sección de la Web se detallarán los errores y Bugs encontrados durante el desarrollo y uso
|
||||
de la herramienta.
|
||||
|
||||
## 2022040200 - Redirección IP con Cloudflare y Nginx
|
||||
|
||||
A la hora de capturar la dirección IP del usuario sobre Cloudflare nos encontramos con un problema
|
||||
el cual, el paquete de datos HTTP altera la cabecera al paso por Cloudflare, siendo el cliente
|
||||
Cloudflare y no el cliente real al que hacemos referencia. Las variables de los datos META también
|
||||
son alterados, incluyendo el REMOTE_ADDR.
|
||||
|
||||
[X] Arreglar el problema con la configuración actual sobre Nginx contra Cloudflare.
|
||||
|
||||
> [[! note NOTA]]: Cloudflare agrega un nuevo valor en los META del paquete HTTP llamado
|
||||
HTTP_CF_CONNECTING_IP, el cual puede ser recogido directamente por PHP mediante $_SERVER o cargado
|
||||
indirectamente con los datos de cabecera. Se pueden alterar los datos de entrada del REMOTE_ADDR
|
||||
desde Nginx poniendo como valor dicha cabecera pero al ser accesible desde PHP de esta forma,
|
||||
simplemente se alterará la cadena de llaves de acceso a las IPs.
|
||||
|
||||
```php
|
||||
|
||||
$ip = null;
|
||||
|
||||
foreach(["HTTP_CF_CONNECTING_IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_REAL_IP", "HTTP_CLIENT_IP", "REMOTE_ADDR"] as $key){
|
||||
if(!empty($_SERVER[$key]))
|
||||
$ip = explode(",", $_SERVER[$key])[0];
|
||||
if($ips = getenv($key))
|
||||
$ip = explode(",", $ips)[0];
|
||||
};
|
||||
|
||||
echo $ip;
|
||||
|
||||
```
|
||||
|
||||
[[html_data {
|
||||
"title" : "KStats - Bugs",
|
||||
"url" : "https://kstats.k3y.pw/es/bugs.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220402,
|
||||
"version" : 20220402,
|
||||
"key_words" : "kstats,stats,statistics,kyman,wmd,wmarkdown,documentación,bugs,fallos,errores,arreglos,problemas,fix",
|
||||
"description" : "Bugs y errores del proyecto KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "https://kstats.k3y.pw/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
37
WMD/es/index.w.md
Executable file
37
WMD/es/index.w.md
Executable file
@ -0,0 +1,37 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220316,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# KStats
|
||||
|
||||
Documentación del proyecto KStats, proyecto que hace registros masivos de movimientos de los
|
||||
usuarios dentro de las Webs registradas por los Tokens.
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/project.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/work.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/projects.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/bugs.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/targets.w.md]]
|
||||
|
||||
[[html_data {
|
||||
"title" : "KStats - Documentación",
|
||||
"url" : "https://kstats.k3y.pw/es/",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220316,
|
||||
"version" : 20220320,
|
||||
"key_words" : "kstats,stats,statistics,kyman,wmd,wmarkdown,documentación",
|
||||
"description" : "Documentación del proyecto KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "https://kstats.k3y.pw/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
24
WMD/es/project.w.md
Executable file
24
WMD/es/project.w.md
Executable file
@ -0,0 +1,24 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220316,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# KStats
|
||||
|
||||
El proyecto KStats no es más que un proyecto de gestión estadística de proceso paralelo a la
|
||||
ejecución de la Web el cual centraliza los datos en una base de datos común, lo que permite que un
|
||||
proyecto KStats levantado gestione más de un sitio Web. Requiere del CORS deshabilitado en el
|
||||
entorno API.
|
||||
|
||||
[[html_data {
|
||||
"title" : "KStats - Idioma",
|
||||
"url" : "https://kstats.k3y.pw/es/projects.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220316,
|
||||
"version" : 20220320,
|
||||
"key_words" : "kstats,stats,statistics,kyman,wmd,wmarkdown,documentación",
|
||||
"description" : "Documentación del proyecto KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "https://kstats.k3y.pw/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
54
WMD/es/projects.w.md
Executable file
54
WMD/es/projects.w.md
Executable file
@ -0,0 +1,54 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# Proyectos
|
||||
|
||||
En esta sección se mostrarán los proyectos dependientes ya sea del KStats, como el KStats de otros
|
||||
proyectos. Para empezar dicha lista, empezaremos con los proyectos de los cuales depende el KStats,
|
||||
los cuales son los siguientes:
|
||||
|
||||
[[links_group [{
|
||||
"images" : ["https://wmarkdown.k3y.pw/images/wmarkdown.png"],
|
||||
"link" : "https://wmarkdown.k3y.pw/",
|
||||
"text" : "WMarkDown"
|
||||
}, {
|
||||
"images" : ["https://wdictionaries.k3y.pw/images/wdictionaries.png"],
|
||||
"link" : "https://wdictionaries.k3y.pw/",
|
||||
"text" : "WDictionaries"
|
||||
}] ]]
|
||||
|
||||
Los siguientes proyectos usan este proyecto para llevar una gestión estadística de uso por páginas
|
||||
Web.
|
||||
|
||||
[[links_group [{
|
||||
"images" : ["https://wmarkdown.k3y.pw/images/wmarkdown.png"],
|
||||
"link" : "https://wmarkdown.k3y.pw/",
|
||||
"text" : "WMarkDown"
|
||||
}, {
|
||||
"images" : ["https://wdictionaries.k3y.pw/images/wdictionaries.png"],
|
||||
"link" : "https://wdictionaries.k3y.pw/",
|
||||
"text" : "WDictionaries"
|
||||
}, {
|
||||
"images" : ["https://kyman.k3y.pw/images/KyMAN.png"],
|
||||
"link" : "https://kyman.k3y.pw/",
|
||||
"text" : "KyMAN"
|
||||
}, {
|
||||
"images" : ["https://anp.k3y.pw/images/AnP.png"],
|
||||
"link" : "https://anp.k3y.pw/",
|
||||
"text" : "AnP"
|
||||
}] ]]
|
||||
|
||||
[[html_data {
|
||||
"title" : "KStats - Proyectos",
|
||||
"url" : "https://kstats.k3y.pw/es/",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "kstats,stats,statistics,kyman,wmd,wmarkdown,documentación,projects,proyectos",
|
||||
"description" : "Proyectos con el KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "https://kstats.k3y.pw/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
45
WMD/es/targets.w.md
Executable file
45
WMD/es/targets.w.md
Executable file
@ -0,0 +1,45 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220402
|
||||
}]]
|
||||
# Objetivos
|
||||
|
||||
En esta sección se mostrarán los objetivos a llevar a cabo dentro de este proyecto. Todos ellos
|
||||
serán realizados por KyMAN.
|
||||
|
||||
- [X] Crear proyecto y base del mismo.
|
||||
- [X] Crear base de datos con el procedimiento almacenado de inserción de registro.
|
||||
- [X] Crear entorno servidor en PHP. Intentar capturar la URL desde el propio PHP y gestionar
|
||||
sesión en entorno servidor.
|
||||
- [X] Añadir campo de habilitado o deshabilitado a los Tokens.
|
||||
- [X] Añadir campo de comprobación de URLs para evitar que cojan el Token para registrar sitios
|
||||
no esperados.
|
||||
- [X] Probar entorno CORS contra CSS.
|
||||
- [X] Crear lado privado de los Tokens para coger los datos de los Tokens públicos.
|
||||
- *Un Token privado puede tener más de un Token público.*
|
||||
- *Un Token público no tiene porqué tener un Token privado.*
|
||||
- [X] Añadir campo Observaciones a los Tokens.
|
||||
- [X] Cambiar método de registro mediante ECMA/JS vía CORS.
|
||||
- [-] Programar automatismo de Geolocalización de IPs.
|
||||
- https://api.iplocation.net/
|
||||
- [-] Analizar los datos de las URLs de geolocalización añadidas a
|
||||
https://kyman.k3y.pw/wlog/info.html#Geolocation.
|
||||
- [X] Publicar versión funcional del proyecto.
|
||||
- [-] Documentar.
|
||||
- [-] Adaptar la documentación a que se genere en el servidor y mantener estadísticas de desarrollo
|
||||
en el GitLab.
|
||||
- [X] Arreglar Bug 2022040200.
|
||||
|
||||
[[html_data {
|
||||
"title" : "KStats - Objetivos",
|
||||
"url" : "https://kstats.k3y.pw/es/targets.html",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220402,
|
||||
"key_words" : "kstats,stats,statistics,kyman,wmd,wmarkdown,documentación,targets,objetivos",
|
||||
"description" : "Objetivos del proyecto KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "https://kstats.k3y.pw/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
195
WMD/es/work.w.md
Executable file
195
WMD/es/work.w.md
Executable file
@ -0,0 +1,195 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# Funcionamiento
|
||||
|
||||
El funcionamiento del KStats está dividido en dos partes: cliente y servidor. Para empezar por la
|
||||
parte más común, nos vamos a ir por la parte del lado cliente. Pero antes de empezar, es importante
|
||||
mencionar que el entorno cliente es un entorno ECMAScript el cual ha de ser ejecutado para que
|
||||
funcione sobre el lado servidor, y el lado servidor ha de estar activo.
|
||||
|
||||
## Cliente
|
||||
|
||||
El lado cliente se basa dos partes diferenciadas: en la creación del Token; y la instalación cliente
|
||||
del mismo.
|
||||
|
||||
> [[! important IMPORTANTE]]: El KStats funciona de dos formas diferentes cara el cliente:
|
||||
registrando un histórico completo mediante ECMA/JS; y registrando accesos mediante petición URL.
|
||||
|
||||
### Creación del Token
|
||||
|
||||
Empezando por la creación del Token, nos encontramos en la base de datos, en caso de no tener acceso
|
||||
por favor, pónganse en contacto con el administrador del sitio, y hay que ejecutar un procedimiento
|
||||
almacenado llamado "token_create" el cual tiene los siguientes parámetros:
|
||||
|
||||
- **$public (_entrada_)**: Parámetro de entrada que indica si el Token es público o no. Al estar
|
||||
sobre el lado cliente éste ha de ser siempre "true".
|
||||
- **$pattern (_entrada_)**: Parámetro de entrada que permite restringir los registros de URLs a un
|
||||
patrón regular, el cual puede tener más de un radical, como por ejemplo el caso de la Web de KyMAN.
|
||||
- **$remarks (_entrada_)**: Parámetro de entrada de texto libre con límite en 2048 caracteres que
|
||||
sirve para describir el Token, finalidad, etc. Así como establecer notas, observaciones o cualquier
|
||||
otro elemento textual que pertenezca al mismo.
|
||||
- **$error (_salida_)**: Parámetro de salida que mostrará un código de error en formato numérico
|
||||
entero donde cada bit representa lo siguiente según posición:
|
||||
0. Excepción SQL.
|
||||
1. El valor '$public' es nulo.
|
||||
2. El valor '$pattern' es nulo.
|
||||
3. El valor '$pattern' está vacío.
|
||||
4. El valor '$remarks' es nulo.
|
||||
5. El valor '$remarks' está vacío.
|
||||
- **$id (_salida_)**: Parámetro de salida que retorna el ID del nuevo Token creado.
|
||||
- **$token (_salida_)**: Parámetro de salida que retorna el nuevo Token creado.
|
||||
|
||||
Ejemplos:
|
||||
|
||||
```sql
|
||||
|
||||
-- Para crear el Token de KSTats.
|
||||
call token_create(true, '^https?\\:\\/{2}kstats\\.k3y\\.pw\\/?', 'Token for KStats project.', @error, @id, @token);
|
||||
select @error, @id, @token;
|
||||
|
||||
-- Para crear el Token de KyMAN y MiguelBST.
|
||||
call token_create(true, '^https?\\:\\/{2}(kyman|m(iguel)?bst)\\.k3y\\.pw\\/?', 'Token for KyMAN|MBST project.', @error, @id, @token);
|
||||
select @error, @id, @token;
|
||||
|
||||
```
|
||||
|
||||
### Adjuntar KStats para ECMA/JS
|
||||
|
||||
Una vez tenemos los Tokens creados, podemos ir al entorno cliente propiamente dicho donde hemos de
|
||||
agregar en cada página Web donde queramos registrar los Stats el siguiente fragment HTML y ECMA.
|
||||
|
||||
```html
|
||||
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" src="https://kstats.k3y.pw/ecma/KStats.ecma.js" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
|
||||
<script>
|
||||
|
||||
kstats = new KStats({url : "https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/json/set"});
|
||||
|
||||
</script>
|
||||
|
||||
```
|
||||
|
||||
La primera etiqueta adjunta a nuestra página Web el Script que gestiona el Script ECMA que nos hace
|
||||
falta para poder ejecutar el KStats; mientras que el segundo crea el objeto KStats con la URL
|
||||
concreta que identifica tu sitio Web dentro del KStats con su Token concreto. Es importante saber la
|
||||
estructura de la URL de petición.
|
||||
|
||||
Los parámetros de entrada que se le pueden dar a ese diccionario donde metemos la URL son los
|
||||
siguientes:
|
||||
|
||||
- **autostart**: Valor que determina si el objeto se inicia de forma automática (true) o se hace de
|
||||
forma manual (false). Por defecto es true.
|
||||
- **nulls**: Valor Booleano que determina si se admiten retornos nulos o no. Por defecto es false.
|
||||
- **default_value**: Valor por defecto a retornar en caso de no tener opciones de valor. Por defecto
|
||||
es null.
|
||||
- **ajax_timeout**: Tiempo límite de ejecución de una petición asícrona AJAX (XMLHttpRequest) en
|
||||
miliseguncos. Por defecto son 2000 milisegundos.
|
||||
- **settings_overwrite**: Valor Booleano que determina si se sobreescriben los valores de la
|
||||
configuración a la hora de añadirlos (true), en base a sus llaves, o no (false). Por defecto es false.
|
||||
- **kstats_url**: URL por defecto a la cual atacar. Por defecto es
|
||||
"https://kstats.k3y.pw/api/uCDY3brWxEJrJywm2sFcKo1d8oaUdmxTTrv3VGuhpyRDpPYXyKeHWeknh/{session}/ecma/set".
|
||||
- **frames_per_second** o **fps**: Fotogramas por segundo o tasa de refrescos por segundo cara los
|
||||
hilos. Por defecto son 1 fotograma por segundo.
|
||||
- **milliseconds_per_connection**: Tiempo de espera entre una conexión y otra para actualizar el
|
||||
estado actual del usuario en milisegundos. Por defecto son 2000.
|
||||
- **session_cookie_name**: Nombre de llave de la Cookie que almacena la sesión del servidor de forma
|
||||
cruzada. Por defecto es "kstats_session_id".
|
||||
- **session_timeout**: Tiempo límite de inactividad de la sesión en milisegundos. Por defecto es de
|
||||
60000. *Este valor no tiene efecto inicialmente*.
|
||||
- **data_key**: Nombre de llave de variable por donde se enviarán los datos al servidor. Por defecto
|
||||
es "kstats_data". **Tiene que ser el mismo que la del servidor.**
|
||||
|
||||
### Registro por petición URL
|
||||
|
||||
Este método permite hacer registro a partir de una llamada, tanto manual como automática, al
|
||||
servidor. A continuación se presentarán ejemplos de llamadas automáticas:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<!-- Llamada desde un ECMA -->
|
||||
<script data-type="text/javascript" data-language="ECMAScript 2015" src="https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/ecma/set" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
|
||||
<!-- Llamada desde un JS -->
|
||||
<script data-type="text/javascript" data-language="JavaScript 1.8.5" src="https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/js/set" data-crossorigin="anonymous" charset="utf-8"></script>
|
||||
|
||||
<!-- Llamada desde un CSS -->
|
||||
<link type="text/css" data-language="CSS3" rel="stylesheet" href="https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/css/set" data-crossorigin="anonymous" charset="utf-8" />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Llamada desde una imagen -->
|
||||
<img src="https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/img/set" alt="KStats" title="KStats" />
|
||||
<img src="https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/image/set" alt="KStats" title="KStats" />
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Y a continuación como se haría de forma manual desde HTML.
|
||||
|
||||
```html
|
||||
|
||||
<!-- Llamada mediante Link -->
|
||||
<a href="https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/text/set" target="_blank" title="KStats">KStats</a>
|
||||
|
||||
<!-- Llamada mediante formulario -->
|
||||
<form method="get" action="https://kstats.k3y.pw/api/SbfXgp4r3fAtuthpzXdZw2JTLKZqZFYzLhWTkQiQr4kYWsrcZvvsbKrHt/{session}/text/set"></form>
|
||||
|
||||
```
|
||||
|
||||
### Estructura de la URL
|
||||
|
||||
La estructura de la URL se compone de varias variables las cuales las encapsulamos a continuación entre llaves:
|
||||
|
||||
```txt
|
||||
https://{domain}/api/{token}/{session}/{response}/{action}/{id}
|
||||
```
|
||||
|
||||
Cada una de estas variables indica lo siguiente:
|
||||
|
||||
- **domain**: Parámetro obligatorio que indica el dominio donde se encuentra el sitio Web del
|
||||
servidor KStats al que estamos atacando.
|
||||
- **token**: Parámetro obligatorio que indica el Token a usar contra el servidor KStats.
|
||||
- **session**: Parámetro obligatorio pero automático donde sólo hemos de indicar la variable, el
|
||||
cual contendrá el ID de la sesión actual a partir de una Cookie local evitando que éstas se crucen
|
||||
entre distintos dominios.
|
||||
- **response**: Modo de respuesta tras la acción de registrar la petición. Estos modos son los
|
||||
siguientes:
|
||||
- **[[ignore js]]**: Retorna el Script KStats en formato JavaScript 1.8.5.
|
||||
- **[[ignore ecma]]**: Retorna el Script KStats en formato ECMA 2015.
|
||||
- **img** o **image**: Retorna una simple imagen de 1x1 de forma simbólica para no dar error
|
||||
contra una etiqueta HTML IMG.
|
||||
- **[[ignore css]]**: Retorna un contenido CSS para poder usar la etiqueta HTML LINK.
|
||||
- **[[ignore json]]**: Retorna el resultado del proceso en formato JSON.
|
||||
- **test**: Hace un retornos sobre un entorno de pruebas.
|
||||
- **action**: Método o acción a ejecutar en el servidor. Dichos métodos son los siguientes:
|
||||
- **set**: Establece un nuevo registro de conexión o actualiza uno ya existente.
|
||||
- **id**: ID de registro actual o existente que se usará para determinar el tiempo de conexión en
|
||||
esa página Web concreta. *No analizar tiempo de inactividad*.
|
||||
|
||||
> [[! note NOTA]]: En caso de no tener ninguno de estos tipos de valor en la variable 'response',
|
||||
éste retornará siempre un texto plano vacío.
|
||||
|
||||
> [[! importante]]: El servidor ha de tener firma SSL para poder realizar la operación asíncrona
|
||||
segura por defecto.
|
||||
|
||||
[[html_data {
|
||||
"title" : "KStats - Funcionamiento",
|
||||
"url" : "https://kstats.k3y.pw/es/",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220320,
|
||||
"version" : 20220320,
|
||||
"key_words" : "kstats,stats,statistics,kyman,wmd,wmarkdown,documentación,funcionamiento",
|
||||
"description" : "Funcionamiento del proyecto KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "https://kstats.k3y.pw/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
40
WMD/index.w.md
Executable file
40
WMD/index.w.md
Executable file
@ -0,0 +1,40 @@
|
||||
[[post_data {
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220316,
|
||||
"version" : 20220320
|
||||
}]]
|
||||
# KStats
|
||||
|
||||
Seleccione un idioma para acceder a la documentación del proyecto.
|
||||
|
||||
[[links_group [{
|
||||
"images" : ["https://i.imgur.com/im1o0gc.png"],
|
||||
"link" : "/es/",
|
||||
"text" : "Español",
|
||||
"self" : true
|
||||
}] ]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/project.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/projects.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/bugs.w.md]]
|
||||
|
||||
[[header_level 0]]
|
||||
[[include /WMD/es/targets.w.md]]
|
||||
|
||||
[[html_data {
|
||||
"title" : "KStats - Idioma",
|
||||
"url" : "https://kstats.k3y.pw/",
|
||||
"author" : "KyMAN",
|
||||
"since" : 20220316,
|
||||
"version" : 20220320,
|
||||
"key_words" : "kstats,stats,statistics,kyman,wmd,wmarkdown,documentación",
|
||||
"description" : "Documentación del proyecto KStats.",
|
||||
"project" : "KStats",
|
||||
"logo" : "https://kstats.k3y.pw/images/KStats.png",
|
||||
"language" : "es"
|
||||
}]]
|
Loading…
Reference in New Issue
Block a user