Skip to content

Commit

Permalink
update different server info types in parallel, make things go fast
Browse files Browse the repository at this point in the history
  • Loading branch information
AmyrAhmady committed Nov 15, 2023
1 parent f06661c commit c65c562
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 134 deletions.
22 changes: 3 additions & 19 deletions src/hooks/query.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { useEffect, useRef } from "react";
import { usePersistentServers, useServers } from "../states/servers";
import { useServers } from "../states/servers";
import { queryServer } from "../utils/query";
import { Server } from "../utils/types";

export const useQuery = () => {
const queryTimer = useRef<number | undefined>(undefined);

const { selected, updateServer, setSelected } = useServers();
const { updateInFavoritesList, updateInRecentlyJoinedList } =
usePersistentServers();
const { selected, setSelected } = useServers();
const selectedServer = useRef<Server | undefined>(selected);

useEffect(() => {
Expand Down Expand Up @@ -37,21 +35,7 @@ export const useQuery = () => {
};

const getServerInfo = (srv: Server) => {
queryServer(srv)
.then((server) => {
if (server && selectedServer.current) {
if (
server.ip == selectedServer.current.ip &&
server.port == selectedServer.current.port
) {
updateServer(server);
updateInFavoritesList(server);
updateInRecentlyJoinedList(server);
setSelected(server);
}
}
})
.catch((e) => console.log(e));
queryServer(srv);
};

return {
Expand Down
1 change: 0 additions & 1 deletion src/states/servers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,3 @@ const usePersistentServers = create<ServersPersistentState>()(
);

export { usePersistentServers, useServers };

21 changes: 3 additions & 18 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { invoke, process, shell } from "@tauri-apps/api";
import { getVersion } from "@tauri-apps/api/app";

import { exists } from "@tauri-apps/api/fs";
import { type } from "@tauri-apps/api/os";
import { t } from "i18next";
Expand Down Expand Up @@ -41,23 +40,15 @@ export const mapAPIResponseServerListToAppStructure = (

export const fetchServers = async (cached: boolean = true) => {
if (cached) {
const { updateServer } = useServers.getState();
const { updateInFavoritesList, updateInRecentlyJoinedList, favorites } =
usePersistentServers.getState();
const { favorites } = usePersistentServers.getState();

if (Array.isArray(favorites)) {
// let's query servers from server list so players have updated data
for (let i = 0; i < favorites.length; i += 10) {
setTimeout(() => {
for (let offset = 0; offset < 10; offset++) {
if (favorites[i + offset]) {
queryServer(favorites[i + offset])
.then((server) => {
updateServer(server);
updateInFavoritesList(server);
updateInRecentlyJoinedList(server);
})
.catch((e) => console.log(e));
queryServer(favorites[i + offset], "favorites");
}
}
}, 500 + (i % 10) * 1000);
Expand All @@ -74,13 +65,7 @@ export const fetchServers = async (cached: boolean = true) => {
setTimeout(() => {
for (let offset = 0; offset < 15; offset++) {
if (response.servers[i + offset])
queryServer(response.servers[i + offset])
.then((server) => {
updateServer(server);
updateInFavoritesList(server);
updateInRecentlyJoinedList(server);
})
.catch((e) => console.log(e));
queryServer(response.servers[i + offset], "internet");
}
}, 500 + (i / 15) * 1000);
}
Expand Down
278 changes: 182 additions & 96 deletions src/utils/query.ts
Original file line number Diff line number Diff line change
@@ -1,122 +1,208 @@
import { invoke } from "@tauri-apps/api";
import { Player, Server } from "./types";

export const queryServer = async (server: Server) => {
return new Promise<Server>(async (resolve, reject) => {
try {
const { ip, port } = server;
let newSrv: Server = { ...server };

newSrv = { ...newSrv, ...(await getServerInfo(ip, port)) };
newSrv.ip = ip;
newSrv.port = port;
const players = await getServerPlayers(ip, port);
if (players === false) {
newSrv.players = server.players;
} else {
newSrv.players = [...players];
}
import { usePersistentServers, useServers } from "../states/servers";
import { ListType, Server } from "./types";

export const queryServer = (
server: Server,
listType: ListType = "internet"
) => {
try {
const { ip, port } = server;

getServerInfo(ip, port, listType);
getServerPlayers(ip, port, listType);
getServerRules(ip, port, listType);
getServerOmpStatus(ip, port, listType);
getServerPing(ip, port, listType);
} catch (error) {
console.log("[query.ts: queryServer]", error);
}
};

newSrv.rules = await getServerRules(ip, port);
newSrv.usingOmp = await getServerOmpStatus(ip, port);
const ping = await getServerPing(ip, port);
newSrv.ping = ping == 0 ? server.ping : ping;
const getServerInfo = async (ip: string, port: number, listType: ListType) => {
try {
const serverInfo = await invoke<string>("request_server_info", {
ip: ip,
port: port,
});

if (serverInfo === "no_data") {
return console.log(
"[query.ts: getServerInfo]",
"There was a problem getting server main info"
);
}

return resolve(newSrv);
} catch (error) {
reject(error);
let queryObj = JSON.parse(serverInfo);
const data = {
hasPassword: queryObj.password,
playerCount: queryObj.players,
maxPlayers: queryObj.max_players,
hostname: queryObj.hostname,
gameMode: queryObj.gamemode,
language: queryObj.language,
};

let server = getServerFromList(ip, port, listType);
if (server) {
server = { ...server, ...data };

updateServerEveryWhere(server);
}
});
} catch (e) {
console.log("[query.ts: getServerInfo]", e);
}
};

const getServerInfo = async (ip: string, port: number) => {
const serverInfo = await invoke<string>("request_server_info", {
ip: ip,
port: port,
});
const getServerPlayers = async (
ip: string,
port: number,
listType: ListType
) => {
try {
const serverPlayers = await invoke<string>("request_server_players", {
ip: ip,
port: port,
});

if (serverPlayers === "no_data") {
return console.log(
"[query.ts: getServerPlayers]",
"There was a problem getting server player list"
);
}

let server = getServerFromList(ip, port, listType);

if (serverInfo === "no_data") {
throw new Error("[Query] There was a problem getting server main info");
}
if (server) {
let queryObj = JSON.parse(serverPlayers);

let queryObj = JSON.parse(serverInfo);
const server = {
hasPassword: queryObj.password,
playerCount: queryObj.players,
maxPlayers: queryObj.max_players,
hostname: queryObj.hostname,
gameMode: queryObj.gamemode,
language: queryObj.language,
};

return server;
if (queryObj.error) {
server = { ...server };
updateServerEveryWhere(server);
} else if (Array.isArray(queryObj)) {
server = { ...server, players: [...queryObj] };
updateServerEveryWhere(server);
}
}
} catch (e) {
console.log("[query.ts: getServerPlayers]", e);
}
};

const getServerPlayers = async (ip: string, port: number) => {
const serverPlayers = await invoke<string>("request_server_players", {
ip: ip,
port: port,
});
const getServerRules = async (ip: string, port: number, listType: ListType) => {
try {
const serverRules = await invoke<string>("request_server_rules", {
ip: ip,
port: port,
});

if (serverRules === "no_data" || !Array.isArray(JSON.parse(serverRules))) {
return console.log(
"[query.ts: getServerRules]",
"There was a problem getting server rule list"
);
}

if (serverPlayers === "no_data") {
throw new Error("[Query] There was a problem getting server player list");
}
let server = getServerFromList(ip, port, listType);

let queryObj = JSON.parse(serverPlayers);
if (queryObj.error) {
return false;
} else if (Array.isArray(queryObj)) {
const players: Player[] = [...queryObj];
return players;
}
return [];
};
if (server) {
let queryObj = JSON.parse(serverRules);
const rules: Server["rules"] = {} as Server["rules"];

const getServerRules = async (ip: string, port: number) => {
const serverRules = await invoke<string>("request_server_rules", {
ip: ip,
port: port,
});
queryObj.forEach((rule: [string, string]) => {
rules[rule[0]] = rule[1];
});

if (serverRules === "no_data" || !Array.isArray(JSON.parse(serverRules))) {
throw new Error("[Query] There was a problem getting server rule list");
server = { ...server, rules: rules };
updateServerEveryWhere(server);
}
} catch (e) {
console.log("[query.ts: getServerRules]", e);
}
};

let queryObj = JSON.parse(serverRules);
const rules: Server["rules"] = {} as Server["rules"];
const getServerOmpStatus = async (
ip: string,
port: number,
listType: ListType
) => {
try {
const serverOmpStatus = await invoke<string>("request_server_is_omp", {
ip: ip,
port: port,
});

let server = getServerFromList(ip, port, listType);
if (server) {
if (
serverOmpStatus === "no_data" ||
JSON.parse(serverOmpStatus).isOmp == undefined
) {
server = { ...server, usingOmp: false };
updateServerEveryWhere(server);
return;
}

queryObj.forEach((rule: [string, string]) => {
rules[rule[0]] = rule[1];
});
server = {
...server,
usingOmp: JSON.parse(serverOmpStatus).isOmp as boolean,
};
updateServerEveryWhere(server);
}
} catch (e) {}
};

const getServerPing = async (ip: string, port: number, listType: ListType) => {
try {
const serverPing = await invoke<string>("ping_server", {
ip: ip,
port: port,
});

let server = getServerFromList(ip, port, listType);
if (server) {
let ping = server.ping;
if (typeof serverPing === "number" && serverPing !== 9999) {
ping = serverPing;
}

return rules;
server = {
...server,
ping: ping,
};
updateServerEveryWhere(server);
}
} catch (e) {}
};

const getServerOmpStatus = async (ip: string, port: number) => {
const serverOmpStatus = await invoke<string>("request_server_is_omp", {
ip: ip,
port: port,
});

if (
serverOmpStatus === "no_data" ||
JSON.parse(serverOmpStatus).isOmp == undefined
) {
return false;
}
const getListBasedOnType = (listType: ListType) => {
const { servers } = useServers.getState();
const { favorites, recentlyJoined } = usePersistentServers.getState();

return JSON.parse(serverOmpStatus).isOmp as boolean;
if (listType === "internet" || listType === "partners") return servers;
else if (listType === "favorites") return favorites;
else if (listType === "recentlyjoined") return recentlyJoined;
else return servers;
};

const getServerPing = async (ip: string, port: number) => {
const serverPing = await invoke<string>("ping_server", {
ip: ip,
port: port,
});
const getServerFromList = (ip: string, port: number, listType: ListType) => {
const list = getListBasedOnType(listType);
return list.find((server) => server.ip === ip && server.port === port);
};

if (typeof serverPing !== "number") {
return 0;
}
const updateServerEveryWhere = (server: Server) => {
const { updateServer, selected, setSelected } = useServers.getState();
const { updateInFavoritesList, updateInRecentlyJoinedList } =
usePersistentServers.getState();

return serverPing;
updateServer(server);
updateInFavoritesList(server);
updateInRecentlyJoinedList(server);

if (selected) {
if (server.ip == selected.ip && server.port == selected.port) {
setSelected(server);
}
}
};

0 comments on commit c65c562

Please sign in to comment.