Skip to content

Commit

Permalink
Added new endpoint to only send updated parties to server
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon committed Aug 25, 2024
1 parent 3ba75d8 commit 2e33f58
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 18 deletions.
65 changes: 64 additions & 1 deletion GuildWarsPartySearch.NodeJSServer/server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {is_numeric, is_uuid, json_parse, to_number} from "./src/js/string_functi
import express from "express";
import bodyParser from "body-parser";
import {is_quarantine_hit} from "./src/js/spam_filter.mjs";
import {PartySearch} from "./src/js/PartySearch.class.mjs";
import {party_json_keys, PartySearch} from "./src/js/PartySearch.class.mjs";
import {start_websocket_server} from "./src/js/websocket_server.mjs";
import {assert} from "./src/js/assert.mjs";
import * as http from "http";
Expand Down Expand Up @@ -143,6 +143,8 @@ function send_map_parties(map_id, request_or_websocket = null) {
* @param party {PartySearch}
*/
function remove_party(party) {
if(!party)
return;
const now = new Date();
let idx = all_parties.indexOf(party);
if (idx !== -1) {
Expand Down Expand Up @@ -422,6 +424,55 @@ function on_recv_parties(ws, data) {
reassign_bot_clients();
}

/**
* Sent from bot clients to update existing map data instead of the whole lot.
* On error, any connected client should then send "client_parties" to refresh the list
* @param ws
* @param data
*/
function on_updated_parties(ws, data) {
const client_id = get_client_id(ws);
assert(client_id, "on_updated_parties: no client_id");
const bot_client = get_bot_client(ws);
assert(bot_client, "on_updated_parties: get_bot_client failed");
assert(is_numeric(bot_client.map_id) && is_numeric(bot_client.district_region),"on_updated_parties: no bot district or region");

const existing_parties = all_parties.filter((party) => {
return party.client_id === client_id;
});

let map_count_changed = false;

data.parties.filter((changed_party_info) => {
return !is_quarantine_hit(changed_party_info.message || '');
}).forEach((changed_party_info) => {
const party_id = to_number(changed_party_info.party_id || changed_party_info[party_json_keys['i']]);
let existing_party = existing_parties.find((party) => {
return party.party_id === party_id;
});
if(changed_party_info.r) {
remove_party(existing_party);
map_count_changed = true;
return;
}
if(!existing_party) {
changed_party_info.client_id = client_id;
changed_party_info.district_region = bot_client.district_region;
changed_party_info.map_id = bot_client.map_id;
const new_party = new PartySearch(changed_party_info);
add_party(new_party);
map_count_changed = true;
return;
}
existing_party.update(changed_party_info);
});

// Broadcast to other connections
if(map_count_changed)
send_available_maps();
send_map_parties(to_number(bot_client.map_id));
}

/**
* Send a summary list of map_ids that have available parties to a http request or endpoint
* @param request_or_websocket {WebSocket|Request}
Expand Down Expand Up @@ -511,6 +562,18 @@ async function on_request_message(request, data) {
assert(request.is_bot_client, "Not a client");
on_recv_parties(request, data);
break;
case "updated_parties":
assert(request.is_bot_client, "Not a client");
try {
on_updated_parties(request,data);
} catch(e) {
send_header(request, 500, e.message);
// On error (whatever it may be!) request client to send all parties
send_json(request, {
type: "server_requested_client_parties"
});
}
break;
case "available_maps":
send_available_maps(request);
break;
Expand Down
58 changes: 41 additions & 17 deletions GuildWarsPartySearch.NodeJSServer/src/js/PartySearch.class.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "./gw_constants.mjs";
import {to_number} from "./string_functions.mjs";

const json_keys = {
export const party_json_keys = {
'party_id':'i',
'party_size':'ps',
'sender':'s',
Expand All @@ -30,26 +30,50 @@ const json_keys = {
export class PartySearch {
constructor(json) {
this.client_id = json.client_id || '';
this.message = json.message || json[json_keys['message']] || '';
this.sender = json.sender || json[json_keys['sender']] || '';
this.party_id = to_number(json.party_id || json[json_keys['i']] || 0);
this.hardmode = to_number(json.hardmode || json[json_keys['hardmode']] || 0);
this.party_size = to_number(json.party_size || json[json_keys['party_size']] || 1);
this.hero_count = to_number(json.hero_count || json[json_keys['hero_count']] || 0);
this.level = to_number(json.level || json[json_keys['level']] || 20);
this.search_type = to_number(json.search_type || json[json_keys['search_type']]);
this.primary = to_number(json.primary || json[json_keys['primary']] || 0);
this.secondary = to_number(json.secondary || json[json_keys['secondary']] || 0);
this.district_number = to_number(json.district_number || json[json_keys['district_number']] || 1);
this.district_region = to_number(json.district_region || json[json_keys['district_region']] || 0);
this.district_language = to_number(json.district_language || json.language || json[json_keys['district_language']] || 0);
this.map_id = to_number(json.map_id || json[json_keys['map_id']] || 0);
this.message = json.message || json[party_json_keys['message']] || '';
this.sender = json.sender || json[party_json_keys['sender']] || '';
this.party_id = to_number(json.party_id || json[party_json_keys['i']] || 0);
this.hardmode = to_number(json.hardmode || json[party_json_keys['hardmode']] || 0);
this.party_size = to_number(json.party_size || json[party_json_keys['party_size']] || 1);
this.hero_count = to_number(json.hero_count || json[party_json_keys['hero_count']] || 0);
this.level = to_number(json.level || json[party_json_keys['level']] || 20);
this.search_type = to_number(json.search_type || json[party_json_keys['search_type']]);
this.primary = to_number(json.primary || json[party_json_keys['primary']] || 0);
this.secondary = to_number(json.secondary || json[party_json_keys['secondary']] || 0);
this.district_number = to_number(json.district_number || json[party_json_keys['district_number']] || 1);
this.district_region = to_number(json.district_region || json[party_json_keys['district_region']] || 0);
this.district_language = to_number(json.district_language || json.language || json[party_json_keys['district_language']] || 0);
this.map_id = to_number(json.map_id || json[party_json_keys['map_id']] || 0);

this.validate();

this.district = json.district || json[json_keys['district']] || district_from_region(this.district_region);
this.district = json.district || json[party_json_keys['district']] || district_from_region(this.district_region);
}
toJSON() {

update(json) {
Object.keys(party_json_keys).forEach((full_key) => {
const abbr_key = party_json_keys[full_key];
if(json.hasOwnProperty(abbr_key))
json[full_key] = json[abbr_key];
});
if(json.hasOwnProperty('message'))
this.message = json.message;
if(json.hasOwnProperty('sender'))
this.sender = json.sender;
// NB: Map and district can't change in practive without the party being removed anyway
['hardmode','parry_size','hero_count','level','search_type','primary','secondary'].forEach((key) => {
if(json.hasOwnProperty(key))
this[key] = to_number(json[key]);
});
this.validate();
}

/**
*
* @param full
* @return {{}}
*/
toJSON(full = false) {
const json_to_set = [
'message',
'sender',
Expand Down

0 comments on commit 2e33f58

Please sign in to comment.