mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
More work on login connection logic
This commit is contained in:
parent
2cb3287d1f
commit
f5aca98e49
@ -23,4 +23,12 @@
|
||||
|
||||
.z-ui-2 {
|
||||
z-index: 2002;
|
||||
}
|
||||
|
||||
.z-ui-3 {
|
||||
z-index: 2003;
|
||||
}
|
||||
|
||||
.z-ui-4 {
|
||||
z-index: 2004;
|
||||
}
|
||||
@ -41,8 +41,8 @@ import { navyUnitDatabase } from "./unit/databases/navyunitdatabase";
|
||||
//import { ContextManager } from "./context/contextmanager";
|
||||
//import { Context } from "./context/context";
|
||||
export var VERSION = "{{OLYMPUS_VERSION_NUMBER}}";
|
||||
export var IP = "{{IP ADDRESS OF SERVER}}";
|
||||
export var connectedToServer = true;
|
||||
export var IP = window.location.toString();
|
||||
export var connectedToServer = true; // Temporary
|
||||
|
||||
export class OlympusApp {
|
||||
/* Global data */
|
||||
@ -271,6 +271,7 @@ export class OlympusApp {
|
||||
})
|
||||
|
||||
/* Load the config file from the server */
|
||||
// Temporary
|
||||
const configRequest = new Request("http://localhost:3000/" + "resources/config");
|
||||
fetch(configRequest).then((response) => {
|
||||
if (response.status === 200) {
|
||||
|
||||
@ -12,7 +12,7 @@ export class ServerManager {
|
||||
#connected: boolean = false;
|
||||
#paused: boolean = false;
|
||||
#REST_ADDRESS = "http://localhost:3001/olympus";
|
||||
#username = "";
|
||||
#username = "no-username";
|
||||
#password = "";
|
||||
#sessionHash: string | null = null;
|
||||
#lastUpdateTimes: { [key: string]: number } = {}
|
||||
@ -30,12 +30,15 @@ export class ServerManager {
|
||||
this.#lastUpdateTimes[MISSION_URI] = Date.now();
|
||||
}
|
||||
|
||||
setCredentials(newUsername: string, newPassword: string) {
|
||||
setUsername(newUsername: string) {
|
||||
this.#username = newUsername;
|
||||
}
|
||||
|
||||
setPassword(newPassword: string) {
|
||||
this.#password = newPassword;
|
||||
}
|
||||
|
||||
GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType: string = 'text', force: boolean = false) {
|
||||
GET(callback: CallableFunction, errorCallback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType: string = 'text', force: boolean = false) {
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
|
||||
/* If a request on this uri is still pending (meaning it's not done or did not yet fail), skip the request, to avoid clogging the TCP workers */
|
||||
@ -84,15 +87,18 @@ export class ServerManager {
|
||||
/* Bad credentials */
|
||||
console.error("Incorrect username/password");
|
||||
getApp().setLoginStatus("failed");
|
||||
errorCallback && errorCallback(xmlHttp.status);
|
||||
} else {
|
||||
/* Failure, probably disconnected */
|
||||
this.setConnected(false);
|
||||
errorCallback && errorCallback(xmlHttp.status);
|
||||
}
|
||||
};
|
||||
xmlHttp.onreadystatechange = (res) => {
|
||||
if (xmlHttp.readyState == 4 && xmlHttp.status === 0) {
|
||||
console.error("An error occurred during the XMLHttpRequest");
|
||||
this.setConnected(false);
|
||||
errorCallback && errorCallback(xmlHttp.status);
|
||||
}
|
||||
};
|
||||
xmlHttp.send(null);
|
||||
@ -131,32 +137,32 @@ export class ServerManager {
|
||||
console.log(`Setting REST address to ${this.#REST_ADDRESS}`)
|
||||
}
|
||||
|
||||
getAirbases(callback: CallableFunction) {
|
||||
this.GET(callback, AIRBASES_URI);
|
||||
getAirbases(callback: CallableFunction, errorCallback: CallableFunction = () => {}) {
|
||||
this.GET(callback, errorCallback, AIRBASES_URI);
|
||||
}
|
||||
|
||||
getBullseye(callback: CallableFunction) {
|
||||
this.GET(callback, BULLSEYE_URI);
|
||||
getBullseye(callback: CallableFunction, errorCallback: CallableFunction = () => {}) {
|
||||
this.GET(callback, errorCallback, BULLSEYE_URI);
|
||||
}
|
||||
|
||||
getLogs(callback: CallableFunction, refresh: boolean = false) {
|
||||
this.GET(callback, LOGS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[LOGS_URI] }, 'text', refresh);
|
||||
getLogs(callback: CallableFunction, refresh: boolean = false, errorCallback: CallableFunction = () => {}) {
|
||||
this.GET(callback, errorCallback, LOGS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[LOGS_URI] }, 'text', refresh);
|
||||
}
|
||||
|
||||
getMission(callback: CallableFunction) {
|
||||
this.GET(callback, MISSION_URI);
|
||||
getMission(callback: CallableFunction, errorCallback: CallableFunction = () => {}) {
|
||||
this.GET(callback, errorCallback, MISSION_URI);
|
||||
}
|
||||
|
||||
getUnits(callback: CallableFunction, refresh: boolean = false) {
|
||||
this.GET(callback, UNITS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[UNITS_URI] }, 'arraybuffer', refresh);
|
||||
getUnits(callback: CallableFunction, refresh: boolean = false, errorCallback: CallableFunction = () => {}) {
|
||||
this.GET(callback, errorCallback, UNITS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[UNITS_URI] }, 'arraybuffer', refresh);
|
||||
}
|
||||
|
||||
getWeapons(callback: CallableFunction, refresh: boolean = false) {
|
||||
this.GET(callback, WEAPONS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer', refresh);
|
||||
getWeapons(callback: CallableFunction, refresh: boolean = false, errorCallback: CallableFunction = () => {}) {
|
||||
this.GET(callback, errorCallback, WEAPONS_URI, { time: refresh ? 0 : this.#lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer', refresh);
|
||||
}
|
||||
|
||||
isCommandExecuted(callback: CallableFunction, commandHash: string) {
|
||||
this.GET(callback, COMMANDS_URI, { commandHash: commandHash });
|
||||
isCommandExecuted(callback: CallableFunction, commandHash: string, errorCallback: CallableFunction = () => {}) {
|
||||
this.GET(callback, errorCallback, COMMANDS_URI, { commandHash: commandHash });
|
||||
}
|
||||
|
||||
addDestination(ID: number, path: any, callback: CallableFunction = () => { }) {
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
/* Types definition */
|
||||
export type MapMarkerVisibilityControl = {
|
||||
"category"?: string;
|
||||
|
||||
@ -5,7 +5,7 @@ export function Modal(props: {
|
||||
children?: JSX.Element | JSX.Element[],
|
||||
className?: string
|
||||
}) {
|
||||
return <div className={props.className + "fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-48%] z-ui-2 rounded-xl border-solid border-[1px] border-gray-500 drop-shadow"}>
|
||||
return <div className={props.className + "fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-48%] z-ui-4 rounded-xl border-solid border-[1px] border-gray-500 drop-shadow"}>
|
||||
{props.children}
|
||||
</div>
|
||||
}
|
||||
@ -8,11 +8,15 @@ import { VERSION, connectedToServer } from '../../olympusapp'
|
||||
export function LoginModal(props: {
|
||||
checkingPassword: boolean,
|
||||
loginError: boolean,
|
||||
onLogin: (password: string) => void
|
||||
commandMode: string | null,
|
||||
onLogin: (password: string) => void,
|
||||
onContinue: (username: string) => void,
|
||||
onBack: () => void
|
||||
}) {
|
||||
const [password, setPassword] = useState("");
|
||||
const [displayName, setDisplayName] = useState("");
|
||||
|
||||
return <Modal className="flex inline-flex max-h-[600px] overflow-y-auto h-[75%] scroll-smooth w-[80%] bg-white dark:bg-olympus-800 ">
|
||||
return <Modal className="inline-flex max-h-[600px] overflow-y-auto h-[75%] scroll-smooth w-[80%] bg-white dark:bg-olympus-800 ">
|
||||
<div className='absolute gap-8 flex flex-col p-16 max-lg:p-12 w-full'>
|
||||
<div className="flex flex-row max-lg:flex-col w-full gap-6">
|
||||
<div className="flex flex-grow flex-col gap-5 w-[40%] max-lg:w-[100%] content-center justify-start">
|
||||
@ -30,18 +34,37 @@ export function LoginModal(props: {
|
||||
{
|
||||
!props.loginError ?
|
||||
<>
|
||||
<div className="flex flex-col items-start gap-2">
|
||||
<label className=" text-gray-800 dark:text-white text-md">Password</label>
|
||||
<input type="text" onChange={(ev) => setPassword(ev.currentTarget.value)} className="w-full max-w-80 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Enter password" required />
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<button type="button" onClick={() => props.onLogin(password)} className="flex content-center items-center gap-2 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800 rounded-sm">
|
||||
Login <FontAwesomeIcon className="my-auto" icon={faArrowRight} />
|
||||
</button>
|
||||
<button type="button" className="flex content-center items-center gap-2 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium text-sm px-5 py-2.5 me-2 mb-2 dark:bg-gray-800 dark:hover:bg-gray-700 focus:outline-none dark:focus:ring-blue-800 rounded-sm dark:border-gray-600 border-[1px] dark:text-gray-400">
|
||||
View Guide <FontAwesomeIcon className="my-auto" icon={faExternalLink} />
|
||||
</button>
|
||||
</div>
|
||||
{ props.commandMode === null?
|
||||
<>
|
||||
<div className="flex flex-col items-start gap-2">
|
||||
<label className=" text-gray-800 dark:text-white text-md">Password</label>
|
||||
<input type="text" onChange={(ev) => setPassword(ev.currentTarget.value)} className="w-full max-w-80 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Enter password" required />
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<button type="button" onClick={() => props.onLogin(password)} className="flex content-center items-center gap-2 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800 rounded-sm">
|
||||
Login <FontAwesomeIcon className="my-auto" icon={faArrowRight} />
|
||||
</button>
|
||||
<button type="button" className="flex content-center items-center gap-2 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium text-sm px-5 py-2.5 me-2 mb-2 dark:bg-gray-800 dark:hover:bg-gray-700 focus:outline-none dark:focus:ring-blue-800 rounded-sm dark:border-gray-600 border-[1px] dark:text-gray-400">
|
||||
View Guide <FontAwesomeIcon className="my-auto" icon={faExternalLink} />
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
:
|
||||
<>
|
||||
<div className="flex flex-col items-start gap-2">
|
||||
<label className=" text-gray-800 dark:text-white text-md">Set display name</label>
|
||||
<input type="text" onChange={(ev) => setDisplayName(ev.currentTarget.value)} className="w-full max-w-80 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Enter display name" required />
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<button type="button" onClick={() => props.onContinue(displayName)} className="flex content-center items-center gap-2 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800 rounded-sm">
|
||||
Continue <FontAwesomeIcon className="my-auto" icon={faArrowRight} />
|
||||
</button>
|
||||
<button type="button" className="flex content-center items-center gap-2 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium text-sm px-5 py-2.5 me-2 mb-2 dark:bg-gray-800 dark:hover:bg-gray-700 focus:outline-none dark:focus:ring-blue-800 rounded-sm dark:border-gray-600 border-[1px] dark:text-gray-400">
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
:
|
||||
<div>
|
||||
|
||||
@ -28,6 +28,7 @@ export type OlympusState = {
|
||||
}
|
||||
|
||||
export function UI() {
|
||||
var [loginModalVisible, setLoginModalVisible] = useState(true);
|
||||
var [mainMenuVisible, setMainMenuVisible] = useState(false);
|
||||
var [spawnMenuVisible, setSpawnMenuVisible] = useState(false);
|
||||
var [unitControlMenuVisible, setUnitControlMenuVisible] = useState(false);
|
||||
@ -60,7 +61,7 @@ export function UI() {
|
||||
function checkPassword(password: string) {
|
||||
setCheckingPassword(true);
|
||||
var hash = sha256.create();
|
||||
getApp().getServerManager().setCredentials("no-username", hash.update(password).hex());
|
||||
getApp().getServerManager().setPassword(hash.update(password).hex());
|
||||
getApp().getServerManager().getMission((response) => {
|
||||
const commandMode = response.mission.commandModeOptions.commandMode;
|
||||
try {
|
||||
@ -69,7 +70,18 @@ export function UI() {
|
||||
setLoginError(true);
|
||||
}
|
||||
setCheckingPassword(false);
|
||||
})
|
||||
},
|
||||
() => {
|
||||
setLoginError(true);
|
||||
setCheckingPassword(false);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
function connect(username: string) {
|
||||
getApp().getServerManager().setUsername(username);
|
||||
getApp().getServerManager().startUpdate();
|
||||
setLoginModalVisible(false);
|
||||
}
|
||||
|
||||
return (
|
||||
@ -103,11 +115,19 @@ export function UI() {
|
||||
<div className='absolute top-0 left-0 h-full w-full flex flex-col'>
|
||||
<Header />
|
||||
<div className='flex h-full'>
|
||||
<LoginModal
|
||||
onLogin={(password) => { checkPassword(password) }}
|
||||
checkingPassword={checkingPassword}
|
||||
loginError={loginError}
|
||||
/>
|
||||
{loginModalVisible &&
|
||||
<>
|
||||
<div className="fixed top-0 left-0 w-full h-full z-ui-3 bg-black opacity-60"></div>
|
||||
<LoginModal
|
||||
onLogin={(password) => { checkPassword(password) }}
|
||||
onContinue={(username) => { connect(username) }}
|
||||
onBack={() => { setCommandMode(null) }}
|
||||
checkingPassword={checkingPassword}
|
||||
loginError={loginError}
|
||||
commandMode={commandMode}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
<SideBar />
|
||||
<MainMenu
|
||||
open={mainMenuVisible}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user