ai-adventure-labs/server/frontend/public/js/connect/api.js
2025-03-23 03:34:41 +03:00

177 lines
4.3 KiB
JavaScript

import { ServerAuth } from "/js/connect/auth.js";
function randint(min, max) {
return Math.ceil((Math.random() * (max - min)) + min);
}
function getTraceId() {
const dict = "1234567890abcdefABCDEF";
return [...new Array(16)]
.map(() => dict[randint(0, dict.length - 1)])
.join("");
}
const curUrl = new URL(location.href);
const [address, port] = curUrl.searchParams.get("server").split(/:/);
const isTLSmode = curUrl.searchParams.get("encrypted") === "true";
class ProtoApiMethods {
constructor (api) {
this.api = api;
}
async _protoMethod (rqdata, threadcb = null) {
const socket = this.api.socket;
const trace_id = getTraceId()
const promise = new Promise((rs, rj) => {
socket.onmessage = (ev) => {
ev = JSON.parse(ev.data);
const data = ev.result;
console.debug("Method sended:", ev);
if (ev.trace_id === trace_id)
if (ev.warning)
console.warn("Method warning:", ev.warning, "\ndetails:", ev);
if (!!ev.ended)
return rs(data);
if (typeof threadcb === 'function')
threadcb(data);
};
socket.onerror = (err) => rj(err);
});
console.debug("Client send:", { trace_id, ...rqdata });
socket.send(
JSON.stringify({ trace_id, ...rqdata }),
);
return await promise;
}
}
class ApiMethods extends ProtoApiMethods {
async _protoMethod (rqdata) {
throw new Error("_protoMethod allowed only into abstract class");
}
constructor (api) {
super(api);
}
async info () {
return await super._protoMethod({
method: "info",
});
}
async authed () {
return await super._protoMethod({
method: "authed",
});
}
async token (token) {
return await super._protoMethod({
method: "token", token
});
}
async login (username, password, gtf = false) {
return await super._protoMethod({
method: "login",
username, password,
gtf
});
}
}
class ApiHTML {
constructor (api) {
this.api = api;
}
async renderMainMenu (user, bgUrl = null) {
bgUrl = bgUrl ?? "assets/hello/1.png";
document.body.style.backgroundImage = `url(${
JSON.stringify(bgUrl)
})`;
document.body.style.backgroundSize = `${screen.width}px ${screen.height}px`;
document.getElementById("server.area").innerHTML = '';
//$(document.getElementById("server.area")).append(ServerAuth.authForm);
}
async renderAuth (authMode, bgUrl = null) {
bgUrl = bgUrl ?? "assets/hello/1.png";
document.body.style.backgroundImage = `url(${
JSON.stringify(bgUrl)
})`;
document.body.style.backgroundSize = `${screen.width}px ${screen.height}px`;
document.getElementById("server.area").innerHTML = '';
$(document.getElementById("server.area")).append(ServerAuth.authForm);
$.find("#server-code-form")[0].hidden = authMode !== "password";
[...$.find(".auth-act-item")].forEach(authEl => {
const authElJQ = $(authEl);
const isHidden = authEl.hidden;
authEl.hidden = false;
const buttonBlock = authElJQ.find(".btn-auth-block")[0];
const paramsBlock = authElJQ.find(".params-auth")[0];
buttonBlock.style.marginTop = `calc(100% - ${paramsBlock.offsetHeight}px)`;
authEl.hidden = isHidden;
});
$.find("#menu-log-in")[0].onclick = function () {
$.find("#log-in")[0].hidden = false;
$.find("#register")[0].hidden = true;
}
$.find("#menu-register")[0].onclick = function () {
$.find("#log-in")[0].hidden = true;
$.find("#register")[0].hidden = false;
}
$.find("#auth-btn")[0].onclick = () => {
this.api.methods.login(
$.find("#username")[0].value,
$.find("#password")[0].value,
true
)
.then(user => {
const { token } = user;
localStorage.setItem(`my-token>${!isTLSmode ? "ws" : "wss"}://${address}:${port}`, token);
this.renderMainMenu(user, bgUrl);
});
}
$.find("#reg-btn")[0].onclick = () => { }
}
}
export class ApiSocket {
constructor ({
isTLSmode, address, port
}) {
this.tlsMode = isTLSmode;
this.address = address;
this.port = port;
this.socket = new WebSocket(`${!isTLSmode ? "ws" : "wss"}://${address}:${port}`);
this.methods = new ApiMethods(this);
this.user = null;
this.html = new ApiHTML(this);
}
async run () {
const socket = this.socket;
const promise = new Promise((rs, rj) => {
socket.onopen = () => this.methods.info().then(data => rs(data));
socket.onerror = (err) => rj(err);
});
return await promise;
}
}