mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Fuck this shit
Merge branch 'release' of https://github.com/VOREStation/VOREStation # Conflicts: # code/controllers/autotransfer.dm # code/controllers/subsystems/inactivity.dm # code/game/area/Away Mission areas.dm # code/game/area/Space Station 13 areas.dm # code/game/jobs/job/captain.dm # code/game/jobs/job/civilian.dm # code/game/jobs/job/security.dm # code/game/jobs/jobs.dm # code/game/machinery/air_alarm.dm # code/game/machinery/suit_storage_unit.dm # code/game/machinery/suit_storage_unit_vr.dm # code/game/mecha/combat/gorilla.dm # code/game/turfs/simulated/dungeon/wall.dm # code/game/turfs/simulated/wall_types.dm # code/modules/client/preference_setup/loadout/loadout_utility_vr.dm # code/modules/clothing/glasses/glasses.dm # code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm # code/modules/clothing/spacesuits/void/void_vr.dm # code/modules/clothing/under/accessories/holster.dm # code/modules/mob/language/station_vr.dm # code/modules/mob/living/carbon/human/emote_vr.dm # code/modules/mob/living/carbon/human/species/station/station_vr.dm # code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm # code/modules/mob/new_player/sprite_accessories_vr.dm # code/modules/power/apc.dm # code/modules/power/lighting.dm # code/modules/resleeving/machines.dm # config/jobwhitelist.txt # icons/mob/species/seromi/head.dmi # icons/mob/species/seromi/suit.dmi # icons/mob/species/vulpkanin/helmet.dmi # icons/mob/species/vulpkanin/suit.dmi # maps/tether/submaps/_tether_submaps.dm # maps/tether/tether_areas2.dm # maps/tether/tether_defines.dm # maps/tether/tether_shuttles.dm # nano/templates/apc.tmpl # vorestation.dme
This commit is contained in:
@@ -18,8 +18,8 @@
|
||||
|
||||
<body>
|
||||
<div id="loader">
|
||||
<p>VChat is still loading. If you see this for a very long time, try the OOC 'Reload VChat' verb, or reconnecting.</p>
|
||||
<p>Sometimes if you're still caching resources, it will take longer than usual.</p>
|
||||
<p>You probably shouldn't see this page. This generally means chat is very broken.</p>
|
||||
<p>You can wait a few seconds to see if it loads, or try OOC > Reload VChat.</p>
|
||||
</div>
|
||||
<div id="app" @mouseup="on_mouseup" style="display: none;" :class="{ inverted: inverted }">
|
||||
|
||||
@@ -41,7 +41,13 @@
|
||||
<div class="item" @click="editmode" title="Edit Mode">
|
||||
<i class="icon-cog-outline" :class="{ blinkwarn: editing }"></i>
|
||||
</div>
|
||||
<div class="item"><span class="ui circular label" title="VChat Latency (Not exactly network latency)" :class="ping_classes">{{latency}}ms</span></div>
|
||||
<div class="item" title="Click to test latency">
|
||||
<span class="ui circular label" :class="ping_classes" @click="do_latency_test">
|
||||
<template v-if="latency">
|
||||
{{latency}}ms
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -78,7 +84,6 @@
|
||||
</div>
|
||||
<div class="eight wide column">
|
||||
<h3>Global Settings</h3>
|
||||
<p>Clicking anywhere in VChat saves your settings.</p>
|
||||
<div class="ui form" :class="{ inverted: inverted }">
|
||||
<div class="grouped fields">
|
||||
<div class="field">
|
||||
@@ -116,19 +121,19 @@
|
||||
<div class="inline fields">
|
||||
<div class="field" title="Font size (Min 0.2, Max 5, Default 0.9)">
|
||||
<label>Font Scale</label>
|
||||
<input class="inputbox" type="number" name="fontsize" placeholder="0.9" v-model.lazy.number="fontsize" required>
|
||||
<input class="inputbox" type="number" name="fontsize" placeholder="0.9" v-model.lazy.number="fontsize" required @keyup.enter="blur_this($event)">
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline fields">
|
||||
<div class="field" title="Line height % (Min 100, Max 200, Default 130)">
|
||||
<label>Line Height %</label>
|
||||
<input class="inputbox" type="number" name="lineheight" placeholder="130" v-model.lazy.number="lineheight" required>
|
||||
<input class="inputbox" type="number" name="lineheight" placeholder="130" v-model.lazy.number="lineheight" required @keyup.enter="blur_this($event)">
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline fields">
|
||||
<div class="field" title="Hides messages for performance (Min 50, Max 2000, Default 200)">
|
||||
<label># Stored Messages</label>
|
||||
<input class="inputbox" type="number" name="showingnum" placeholder="200" v-model.lazy.number="showingnum" required>
|
||||
<input class="inputbox" type="number" name="showingnum" placeholder="200" v-model.lazy.number="showingnum" required @keyup.enter="blur_this($event)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
//Options for vchat
|
||||
var vchat_opts = {
|
||||
pingThisOften: 10000, //ms
|
||||
pingDropsAllowed: 2,
|
||||
msBeforeDropped: 30000, //No ping for this long, and the server must be gone
|
||||
cookiePrefix: "vst-", //If you're another server, you can change this if you want.
|
||||
alwaysShow: ["vc_looc", "vc_system"] //Categories to always display on every tab
|
||||
alwaysShow: ["vc_looc", "vc_system"], //Categories to always display on every tab
|
||||
vchatTabsVer: 1.0 //Version of vchat tabs save 'file'
|
||||
};
|
||||
|
||||
var DARKMODE_COLORS = {
|
||||
@@ -75,11 +75,8 @@ var vchat_state = {
|
||||
byond_ckey: null,
|
||||
|
||||
//Ping status
|
||||
lastPingAttempt: 0,
|
||||
lastPingReply: 0,
|
||||
missedPings: 0,
|
||||
latency: 0,
|
||||
reconnecting: false,
|
||||
lastPingReceived: 0,
|
||||
latency_sent: 0,
|
||||
|
||||
//Last ID
|
||||
lastId: 0
|
||||
@@ -99,8 +96,7 @@ function start_vchat() {
|
||||
doWinset("chatloadlabel", {"is-visible": false});
|
||||
|
||||
//Commence the pingening
|
||||
send_ping();
|
||||
setInterval(send_ping, vchat_opts.pingThisOften);
|
||||
setInterval(check_ping, vchat_opts.msBeforeDropped);
|
||||
|
||||
//For fun
|
||||
send_debug("VChat Loaded!");
|
||||
@@ -125,6 +121,7 @@ function start_vue() {
|
||||
editing: false, //If we're in settings edit mode
|
||||
paused: false, //Autoscrolling
|
||||
latency: 0, //Not necessarily network latency, since the game server has to align the responses into ticks
|
||||
reconnecting: false, //If we've lost our connection
|
||||
ext_styles: "", //Styles for chat downloaded files
|
||||
is_admin: false,
|
||||
|
||||
@@ -155,7 +152,7 @@ function start_vue() {
|
||||
admin: false
|
||||
},
|
||||
{
|
||||
matches: ".notice, .adminnotice, .info, .sinister, .cult",
|
||||
matches: ".notice:not(.pm), .adminnotice, .info, .sinister, .cult",
|
||||
becomes: "vc_info",
|
||||
pretty: "Notices",
|
||||
tooltip: "Non-urgent messages from the game and items",
|
||||
@@ -163,7 +160,7 @@ function start_vue() {
|
||||
admin: false
|
||||
},
|
||||
{
|
||||
matches: ".critical, .danger, .userdanger, .warning, .italics",
|
||||
matches: ".critical, .danger, .userdanger, .warning:not(.pm), .italics",
|
||||
becomes: "vc_warnings",
|
||||
pretty: "Warnings",
|
||||
tooltip: "Urgent messages from the game and items",
|
||||
@@ -261,6 +258,13 @@ function start_vue() {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
reconnecting: function(newSetting, oldSetting) {
|
||||
if(newSetting == true && oldSetting == false) {
|
||||
this.internal_message("Your client has lost connection to the server, or there is severe lag. Your client will reconnect if possible.");
|
||||
} else if (newSetting == false && oldSetting == true) {
|
||||
this.internal_message("Your client has reconnected to the server.");
|
||||
}
|
||||
},
|
||||
//Save the inverted setting to LS
|
||||
inverted: function (newSetting) {
|
||||
set_storage("darkmode",newSetting);
|
||||
@@ -335,11 +339,15 @@ function start_vue() {
|
||||
},
|
||||
//What color does the latency pip get?
|
||||
ping_classes: function() {
|
||||
if(this.latency === 0) { return "grey"; }
|
||||
if(!this.latency) {
|
||||
return this.reconnecting ? "red" : "green"; //Standard
|
||||
}
|
||||
|
||||
if (this.latency == "?") { return "grey"; } //Waiting for latency test reply
|
||||
else if(this.latency < 0 ) {return "red"; }
|
||||
else if(this.latency <= 200) { return "green"; }
|
||||
else if(this.latency <= 400) { return "yellow"; }
|
||||
else { return "red"; }
|
||||
else { return "grey"; }
|
||||
},
|
||||
current_categories: function() {
|
||||
if(this.active_tab == this.tabs[0]) {
|
||||
@@ -361,6 +369,50 @@ function start_vue() {
|
||||
|
||||
if(isNaN(this.crushing)){this.crushing = 3;} //This used to be a bool (03-02-2020)
|
||||
if(isNaN(this.fontsize)){this.fontsize = 0.9;} //This used to be a string (03-02-2020)
|
||||
|
||||
this.load_tabs();
|
||||
},
|
||||
load_tabs: function() {
|
||||
var loadstring = get_storage("tabs")
|
||||
if(!loadstring)
|
||||
return;
|
||||
var loadfile = JSON.parse(loadstring);
|
||||
//Malformed somehow.
|
||||
if(!loadfile.version || !loadfile.tabs) {
|
||||
this.internal_message("There was a problem loading your tabs. Any new ones you make will be saved, however.");
|
||||
return;
|
||||
}
|
||||
//Version is old? Sorry.
|
||||
if(!loadfile.version == vchat_opts.vchatTabsVer) {
|
||||
this.internal_message("Your saved tabs are for an older version of VChat and must be recreated, sorry.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.tabs.push.apply(this.tabs, loadfile.tabs);
|
||||
},
|
||||
save_tabs: function() {
|
||||
var savefile = {
|
||||
version: vchat_opts.vchatTabsVer,
|
||||
tabs: []
|
||||
}
|
||||
|
||||
//The tabs contain a bunch of vue stuff that gets funky when you try to serialize it with stringify, so we 'purify' it
|
||||
this.tabs.forEach(function(tab){
|
||||
if(tab.immutable)
|
||||
return;
|
||||
|
||||
var name = tab.name;
|
||||
|
||||
var categories = [];
|
||||
tab.categories.forEach(function(category){categories.push(category);});
|
||||
|
||||
var cleantab = {name: name, categories: categories, immutable: false, active: false}
|
||||
|
||||
savefile.tabs.push(cleantab);
|
||||
});
|
||||
|
||||
var savestring = JSON.stringify(savefile);
|
||||
set_storage("tabs", savestring);
|
||||
},
|
||||
//Change to another tab
|
||||
switchtab: function(tab) {
|
||||
@@ -377,6 +429,7 @@ function start_vue() {
|
||||
//Toggle edit mode
|
||||
editmode: function() {
|
||||
this.editing = !this.editing;
|
||||
this.save_tabs();
|
||||
},
|
||||
//Toggle autoscroll
|
||||
pause: function() {
|
||||
@@ -588,21 +641,50 @@ function start_vue() {
|
||||
textToSave += "<br>\n";
|
||||
});
|
||||
textToSave += "</body></html>";
|
||||
var hiddenElement = document.createElement('a');
|
||||
hiddenElement.href = 'data:attachment/text,' + encodeURI(textToSave);
|
||||
hiddenElement.target = '_blank';
|
||||
|
||||
var filename = "chat_export.html";
|
||||
var fileprefix = "log";
|
||||
var extension =".html";
|
||||
|
||||
var now = new Date();
|
||||
var hours = String(now.getHours());
|
||||
if(hours.length < 2) {
|
||||
hours = "0" + hours;
|
||||
}
|
||||
var minutes = String(now.getMinutes());
|
||||
if(minutes.length < 2) {
|
||||
minutes = "0" + minutes;
|
||||
}
|
||||
var dayofmonth = String(now.getDate());
|
||||
if(dayofmonth.length < 2) {
|
||||
dayofmonth = "0" + dayofmonth;
|
||||
}
|
||||
var month = String(now.getMonth()+1); //0-11
|
||||
if(month.length < 2) {
|
||||
month = "0" + month;
|
||||
}
|
||||
var year = String(now.getFullYear());
|
||||
var datesegment = " "+year+"-"+month+"-"+dayofmonth+" ("+hours+" "+minutes+")";
|
||||
|
||||
var filename = fileprefix+datesegment+extension;
|
||||
|
||||
//Unlikely to work unfortunately, not supported in any version of IE, only Edge
|
||||
if (hiddenElement.download !== undefined){
|
||||
hiddenElement.download = filename;
|
||||
hiddenElement.click();
|
||||
//Probably what will end up getting used
|
||||
} else {
|
||||
let blob = new Blob([textToSave], {type: 'text/html;charset=utf8;'});
|
||||
saved = window.navigator.msSaveBlob(blob, filename);
|
||||
}
|
||||
var hiddenElement = document.createElement('a');
|
||||
if (hiddenElement.download !== undefined) {
|
||||
hiddenElement.href = 'data:attachment/text,' + encodeURI(textToSave); //Has a problem in byond 512 due to weird unicode handling
|
||||
hiddenElement.target = '_blank';
|
||||
hiddenElement.download = filename;
|
||||
hiddenElement.click();
|
||||
//Probably what will end up getting used
|
||||
} else {
|
||||
var blob = new Blob([textToSave], {type: 'text/html;charset=utf8;'});
|
||||
saved = window.navigator.msSaveOrOpenBlob(blob, filename);
|
||||
}
|
||||
},
|
||||
do_latency_test: function() {
|
||||
send_latency_check();
|
||||
},
|
||||
blur_this: function(event) {
|
||||
event.target.blur();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -613,21 +695,37 @@ function start_vue() {
|
||||
* Actual Methods
|
||||
*
|
||||
************/
|
||||
//Send a 'ping' to byond and check to see if we got the last one back in a timely manner
|
||||
function send_ping() {
|
||||
vchat_state.latency = (Math.min(Math.max(vchat_state.lastPingReply - vchat_state.lastPingAttempt, -1), 999));
|
||||
//If their last reply was in the previous ping window or earlier.
|
||||
if(vchat_state.latency < 0) {
|
||||
vchat_state.missedPings++;
|
||||
if((vchat_state.missedPings >= vchat_opts.pingDropsAllowed) && !vchat_state.reconnecting) {
|
||||
system_message("Your client has lost connection with the server. It will reconnect automatically if possible.");
|
||||
vchat_state.reconnecting = true;
|
||||
function check_ping() {
|
||||
var time_ago = Date.now() - vchat_state.lastPingReceived;
|
||||
if(time_ago > vchat_opts.msBeforeDropped)
|
||||
vueapp.reconnecting = true;
|
||||
}
|
||||
|
||||
//Send a 'ping' to byond
|
||||
function send_latency_check() {
|
||||
if(vchat_state.latency_sent)
|
||||
return;
|
||||
|
||||
vchat_state.latency_sent = Date.now();
|
||||
vueapp.latency = "?";
|
||||
push_Topic("ping");
|
||||
setTimeout(function() {
|
||||
if(vchat_state.latency_ms == "?") {
|
||||
vchat_state.latency_ms = 999;
|
||||
}
|
||||
}, 1000); // 1 second to reply otherwise we mark it as bad
|
||||
setTimeout(function() {
|
||||
vchat_state.latency_sent = 0;
|
||||
vueapp.latency = 0;
|
||||
}, 5000); //5 seconds to display ping time overall
|
||||
}
|
||||
|
||||
function get_latency_check() {
|
||||
if(!vchat_state.latency_sent) {
|
||||
return; //Too late
|
||||
}
|
||||
|
||||
vueapp.latency = vchat_state.latency;
|
||||
push_Topic("keepalive_client");
|
||||
vchat_state.lastPingAttempt = Date.now();
|
||||
vueapp.latency = Date.now() - vchat_state.latency_sent;
|
||||
}
|
||||
|
||||
//We accept double-url-encoded JSON strings because Byond is garbage and UTF-8 encoded url_encode() text has crazy garbage in it.
|
||||
@@ -678,7 +776,7 @@ function send_debug(message) {
|
||||
//A side-channel to send events over that aren't just chat messages, if necessary.
|
||||
function get_event(event) {
|
||||
if(!vchat_state.ready) {
|
||||
push_Topic('not_ready');
|
||||
push_Topic("not_ready");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -704,10 +802,19 @@ function get_event(event) {
|
||||
break;
|
||||
|
||||
//Just a ping.
|
||||
case 'keepalive_server':
|
||||
vchat_state.lastPingReply = Date.now();
|
||||
vchat_state.missedPings = 0;
|
||||
reconnecting = false;
|
||||
case 'keepalive':
|
||||
vchat_state.lastPingReceived = Date.now();
|
||||
vueapp.reconnecting = false;
|
||||
break;
|
||||
|
||||
//Response to a latency test.
|
||||
case 'pong':
|
||||
get_latency_check();
|
||||
break;
|
||||
|
||||
//The server doesn't know if we're loaded or not (we bail above if we're not, so we must be).
|
||||
case 'availability':
|
||||
push_Topic("done_loading");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -46,7 +46,6 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
. = ..()
|
||||
|
||||
owner = C
|
||||
update_vis()
|
||||
|
||||
/datum/chatOutput/Destroy()
|
||||
owner = null
|
||||
@@ -78,14 +77,20 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
become_broken()
|
||||
return FALSE
|
||||
|
||||
//Could be loaded from a previous round, are you still there?
|
||||
if(winget(owner,"outputwindow.htmloutput","is-visible") == "true") //Winget returns strings
|
||||
send_event(event = list("evttype" = "availability"))
|
||||
sleep(3 SECONDS)
|
||||
|
||||
if(!owner) // In case the client vanishes before winexists returns
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
if(!resources_sent)
|
||||
send_resources()
|
||||
|
||||
load()
|
||||
if(!loaded)
|
||||
update_vis()
|
||||
if(!resources_sent)
|
||||
send_resources()
|
||||
load()
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -115,7 +120,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
owner.chatOutputLoadedAt = world.time
|
||||
|
||||
//update_vis() //It does it's own winsets
|
||||
|
||||
ping_cycle()
|
||||
send_playerinfo()
|
||||
load_database()
|
||||
|
||||
@@ -135,6 +140,10 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
/datum/chatOutput/proc/become_broken()
|
||||
broken = TRUE
|
||||
loaded = FALSE
|
||||
|
||||
if(!owner)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
update_vis()
|
||||
|
||||
@@ -163,9 +172,23 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
/datum/chatOutput/proc/send_event(var/event, var/client/C = owner)
|
||||
C << output(jsEncode(event), "htmloutput:get_event")
|
||||
|
||||
//Looping sleeping proc that just pings the client and dies when we die
|
||||
/datum/chatOutput/proc/ping_cycle()
|
||||
set waitfor = FALSE
|
||||
while(!QDELING(src))
|
||||
if(!owner)
|
||||
qdel(src)
|
||||
return
|
||||
send_event(event = keep_alive())
|
||||
sleep(20 SECONDS) //Make sure this makes sense with what the js client is expecting
|
||||
|
||||
//Just produces a message for using in keepalives from the server to the client
|
||||
/datum/chatOutput/proc/keepalive()
|
||||
return list("evttype" = "keepalive_server")
|
||||
/datum/chatOutput/proc/keep_alive()
|
||||
return list("evttype" = "keepalive")
|
||||
|
||||
//A response to a latency check from the client
|
||||
/datum/chatOutput/proc/latency_check()
|
||||
return list("evttype" = "pong")
|
||||
|
||||
//Redirected from client/Topic when the user clicks a link that pertains directly to the chat (when src == "chat")
|
||||
/datum/chatOutput/Topic(var/href, var/list/href_list)
|
||||
@@ -197,8 +220,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
CRASH("Tried to send a message to [owner.ckey] chatOutput before it was ready!")
|
||||
if("done_loading")
|
||||
data = done_loading(arglist(params))
|
||||
if("keepalive_client")
|
||||
data = keepalive(arglist(params))
|
||||
if("ping")
|
||||
data = latency_check(arglist(params))
|
||||
if("ident")
|
||||
data = bancheck(arglist(params))
|
||||
if("unloading")
|
||||
|
||||
@@ -24,7 +24,7 @@ GLOBAL_DATUM(vchatdb, /database)
|
||||
//For INSERT/CREATE/DELETE, etc that return a RowsAffected.
|
||||
/proc/vchat_exec_update(var/query)
|
||||
if(!check_vchat())
|
||||
log_debug("There's no vchat database open but you tried to query it with: [query]")
|
||||
log_world("There's no vchat database open but you tried to query it with: [query]")
|
||||
return FALSE
|
||||
|
||||
//Solidify our query
|
||||
@@ -35,7 +35,7 @@ GLOBAL_DATUM(vchatdb, /database)
|
||||
|
||||
//Handle errors
|
||||
if(q.Error())
|
||||
log_debug("Query \"[islist(query)?query[1]:query]\" ended in error [q.ErrorMsg()]")
|
||||
log_world("Query \"[islist(query)?query[1]:query]\" ended in error [q.ErrorMsg()]")
|
||||
return FALSE
|
||||
|
||||
return q.RowsAffected()
|
||||
@@ -43,7 +43,7 @@ GLOBAL_DATUM(vchatdb, /database)
|
||||
//For SELECT, that return results.
|
||||
/proc/vchat_exec_query(var/query)
|
||||
if(!check_vchat())
|
||||
log_debug("There's no vchat database open but you tried to query it!")
|
||||
log_world("There's no vchat database open but you tried to query it!")
|
||||
return FALSE
|
||||
|
||||
//Solidify our query
|
||||
@@ -54,7 +54,7 @@ GLOBAL_DATUM(vchatdb, /database)
|
||||
|
||||
//Handle errors
|
||||
if(q.Error())
|
||||
log_debug("Query \"[islist(query)?query[1]:query]\" ended in error [q.ErrorMsg()]")
|
||||
log_world("Query \"[islist(query)?query[1]:query]\" ended in error [q.ErrorMsg()]")
|
||||
return FALSE
|
||||
|
||||
//Return any results
|
||||
|
||||
Reference in New Issue
Block a user