Merge pull request #1743 from Citadel-Station-13/upstream-merge-28670
[MIRROR] Makes oldchat show while goonchat loads, sends preload messages there.
This commit is contained in:
@@ -591,8 +591,8 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
log_access("Failed Login: [key] [computer_id] [address] - CID randomizer check")
|
||||
var/url = winget(src, null, "url")
|
||||
//special javascript to make them reconnect under a new window.
|
||||
src << browse("<a id='link' href='byond://[url]?token=[token]'>byond://[url]?token=[token]</a><script type='text/javascript'>document.getElementById(\"link\").click();window.location=\"byond://winset?command=.quit\"</script>", "border=0;titlebar=0;size=1x1")
|
||||
src << browse("<a href='byond://[url]?token=[token]'>You will be automatically taken to the game, if not, click here to be taken manually</a>", "window=browseroutput")
|
||||
src << browse({"<a id='link' href="byond://[url]?token=[token]">byond://[url]?token=[token]</a><script type="text/javascript">document.getElementById("link").click();window.location="byond://winset?command=.quit"</script>"}, "border=0;titlebar=0;size=1x1;window=redirect")
|
||||
to_chat(src, {"<a href="byond://[url]?token=[token]">You will be automatically taken to the game, if not, click here to be taken manually</a>"})
|
||||
|
||||
/client/proc/note_randomizer_user()
|
||||
var/const/adminckey = "CID-Error"
|
||||
|
||||
@@ -11,14 +11,13 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
var/loaded = FALSE // Has the client loaded the browser output area?
|
||||
var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do
|
||||
var/cookieSent = FALSE // Has the client sent a cookie for analysis
|
||||
var/list/connectionHistory //Contains the connection history passed from chat cookie
|
||||
var/broken = FALSE
|
||||
var/list/connectionHistory //Contains the connection history passed from chat cookie
|
||||
|
||||
/datum/chatOutput/New(client/C)
|
||||
owner = C
|
||||
messageQueue = list()
|
||||
connectionHistory = list()
|
||||
// log_world("chatOutput: New()")
|
||||
|
||||
/datum/chatOutput/proc/start()
|
||||
//Check for existing chat
|
||||
@@ -26,11 +25,14 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
return FALSE
|
||||
|
||||
if(!winexists(owner, "browseroutput")) // Oh goddamnit.
|
||||
alert(owner.mob, "Updated chat window does not exist. If you are using a custom skin file please allow the game to update.")
|
||||
set waitfor = FALSE
|
||||
broken = TRUE
|
||||
return FALSE
|
||||
message_admins("Couldn't start chat for [key_name_admin(owner)]!")
|
||||
. = FALSE
|
||||
alert(owner.mob, "Updated chat window does not exist. If you are using a custom skin file please allow the game to update.")
|
||||
return
|
||||
|
||||
if(winget(owner, "browseroutput", "is-disabled") == "false") //Already setup
|
||||
if(winget(owner, "browseroutput", "is-visible") == "true") //Already setup
|
||||
doneLoading()
|
||||
|
||||
else //Not setup
|
||||
@@ -43,33 +45,11 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
var/static/list/chatResources = list(
|
||||
"code/modules/html_interface/js/jquery.min.js",
|
||||
"goon/browserassets/js/json2.min.js",
|
||||
"goon/browserassets/js/browserOutput.js",
|
||||
"tgui/assets/fonts/fontawesome-webfont.eot",
|
||||
"tgui/assets/fonts/fontawesome-webfont.svg",
|
||||
"tgui/assets/fonts/fontawesome-webfont.ttf",
|
||||
"tgui/assets/fonts/fontawesome-webfont.woff",
|
||||
"goon/browserassets/css/font-awesome.css",
|
||||
"goon/browserassets/css/browserOutput.css"
|
||||
)
|
||||
var/datum/asset/stuff = get_asset_datum(/datum/asset/simple/goonchat)
|
||||
stuff.register()
|
||||
stuff.send(owner)
|
||||
|
||||
// to_chat(world.log, "chatOutput: load()")
|
||||
for(var/attempts in 1 to 5)
|
||||
for(var/asset in chatResources)
|
||||
owner << browse_rsc(file(asset))
|
||||
|
||||
//log_world("Sending main chat window to client [owner.ckey]")
|
||||
owner << browse(file("goon/browserassets/html/browserOutput.html"), "window=browseroutput")
|
||||
sleep(14 + (chatResources.len * 7))
|
||||
if(!owner || loaded)
|
||||
break
|
||||
|
||||
if(owner && !loaded)
|
||||
doneLoading() // try doing this manually
|
||||
CRASH("[owner] failed to load chat. Attempting doneLoading() manually")
|
||||
// log_world("chatOutput: [owner.ckey] load() completed")
|
||||
owner << browse(file('code/modules/goonchat/browserassets/html/browserOutput.html'), "window=browseroutput")
|
||||
|
||||
/datum/chatOutput/Topic(href, list/href_list)
|
||||
if(usr.client != owner)
|
||||
@@ -102,13 +82,18 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
if(data)
|
||||
ehjax_send(data = data)
|
||||
|
||||
|
||||
//Called on chat output done-loading by JS.
|
||||
/datum/chatOutput/proc/doneLoading()
|
||||
if(loaded)
|
||||
return
|
||||
|
||||
testing("Chat loaded for [owner.ckey]")
|
||||
loaded = TRUE
|
||||
winset(owner, "browseroutput", "is-disabled=false")
|
||||
winset(owner, "output", "is-disabled=true;is-visible=false")
|
||||
winset(owner, "browseroutput", "is-disabled=false;is-visible=true")
|
||||
|
||||
|
||||
for(var/message in messageQueue)
|
||||
to_chat(owner, message)
|
||||
|
||||
@@ -173,15 +158,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
/datum/chatOutput/proc/debug(error)
|
||||
log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]")
|
||||
|
||||
#ifdef TESTING
|
||||
/client/verb/debug_chat()
|
||||
set hidden = TRUE
|
||||
chatOutput.ehjax_send(data = list("firebug" = TRUE))
|
||||
#endif
|
||||
//Global chat procs
|
||||
|
||||
GLOBAL_LIST_EMPTY(bicon_cache)
|
||||
|
||||
//Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
|
||||
// exporting it as text, and then parsing the base64 from that.
|
||||
// (This relies on byond automatically storing icons in savefiles as base64)
|
||||
@@ -193,85 +171,93 @@ GLOBAL_LIST_EMPTY(bicon_cache)
|
||||
var/list/partial = splittext(iconData, "{")
|
||||
return replacetext(copytext(partial[2], 3, -5), "\n", "")
|
||||
|
||||
/proc/bicon(obj)
|
||||
if (!obj)
|
||||
/proc/bicon(thing)
|
||||
if (!thing)
|
||||
return
|
||||
|
||||
if (isicon(obj))
|
||||
if (isicon(thing))
|
||||
//Icons get pooled constantly, references are no good here.
|
||||
/*if (!bicon_cache["\ref[obj]"]) // Doesn't exist yet, make it.
|
||||
bicon_cache["\ref[obj]"] = icon2base64(obj)
|
||||
return "<img class='icon misc' src='data:image/png;base64,[bicon_cache["\ref[obj]"]]'>"*/
|
||||
return "<img class='icon misc' src='data:image/png;base64,[icon2base64(obj)]'>"
|
||||
return "<img class='icon misc' src='data:image/png;base64,[icon2base64(thing)]'>"
|
||||
|
||||
// Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with.
|
||||
var/atom/A = obj
|
||||
var/atom/A = thing
|
||||
var/key = "[istype(A.icon, /icon) ? "\ref[A.icon]" : A.icon]:[A.icon_state]"
|
||||
if (!GLOB.bicon_cache[key]) // Doesn't exist, make it.
|
||||
|
||||
var/static/list/bicon_cache = list()
|
||||
if (!bicon_cache[key]) // Doesn't exist, make it.
|
||||
var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1)
|
||||
if (ishuman(obj)) // Shitty workaround for a BYOND issue.
|
||||
if (ishuman(thing)) // Shitty workaround for a BYOND issue.
|
||||
var/icon/temp = I
|
||||
I = icon()
|
||||
I.Insert(temp, dir = SOUTH)
|
||||
GLOB.bicon_cache[key] = icon2base64(I, key)
|
||||
bicon_cache[key] = icon2base64(I, key)
|
||||
|
||||
return "<img class='icon [A.icon_state]' src='data:image/png;base64,[GLOB.bicon_cache[key]]'>"
|
||||
return "<img class='icon [A.icon_state]' src='data:image/png;base64,[bicon_cache[key]]'>"
|
||||
|
||||
//Costlier version of bicon() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
|
||||
/proc/costly_bicon(obj)
|
||||
if (!obj)
|
||||
/proc/costly_bicon(thing)
|
||||
if (!thing)
|
||||
return
|
||||
|
||||
if (isicon(obj))
|
||||
return bicon(obj)
|
||||
if (isicon(thing))
|
||||
return bicon(thing)
|
||||
|
||||
var/icon/I = getFlatIcon(obj)
|
||||
var/icon/I = getFlatIcon(thing)
|
||||
return bicon(I)
|
||||
|
||||
/proc/to_chat(target, message)
|
||||
if(isnull(target))
|
||||
if(!target)
|
||||
return
|
||||
|
||||
//Ok so I did my best but I accept that some calls to this will be for shit like sound and images
|
||||
//It stands that we PROBABLY don't want to output those to the browser output so just handle them here
|
||||
if (istype(message, /image) || istype(message, /sound) || istype(target, /savefile) || !(ismob(target) || islist(target) || istype(target, /client) || istype(target, /datum/log) || target == world))
|
||||
if (istype(message, /image) || istype(message, /sound) || istype(target, /savefile))
|
||||
target << message
|
||||
if (!istype(target, /atom)) // Really easy to mix these up, and not having to make sure things are mobs makes the code cleaner.
|
||||
CRASH("DEBUG: Boutput called with invalid message")
|
||||
CRASH("Invalid message! [message]")
|
||||
|
||||
if(!istext(message))
|
||||
return
|
||||
|
||||
//Otherwise, we're good to throw it at the user
|
||||
else if (istext(message))
|
||||
if (istext(target))
|
||||
if(target == world)
|
||||
target = GLOB.clients
|
||||
|
||||
var/list/targets
|
||||
if(!islist(target))
|
||||
targets = list(target)
|
||||
else
|
||||
targets = target
|
||||
if(!targets.len)
|
||||
return
|
||||
var/original_message = message
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
message = replacetext(message, "\n", "<br>")
|
||||
message = replacetext(message, "\t", "[GLOB.TAB][GLOB.TAB]")
|
||||
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
if (findtext(message, "\improper"))
|
||||
message = replacetext(message, "\improper", "")
|
||||
if (findtext(message, "\proper"))
|
||||
message = replacetext(message, "\proper", "")
|
||||
|
||||
for(var/I in targets)
|
||||
//Grab us a client if possible
|
||||
var/client/C = grab_client(target)
|
||||
var/client/C = grab_client(I)
|
||||
|
||||
if (C && C.chatOutput)
|
||||
if(C.chatOutput.broken) // A player who hasn't updated his skin file.
|
||||
to_chat(C, message)
|
||||
return TRUE
|
||||
if(!C.chatOutput.loaded && C.chatOutput.messageQueue && islist(C.chatOutput.messageQueue))
|
||||
//Client sucks at loading things, put their messages in a queue
|
||||
C.chatOutput.messageQueue.Add(message)
|
||||
return
|
||||
if (!C)
|
||||
continue
|
||||
|
||||
if(istype(target, /datum/log))
|
||||
var/datum/log/L = target
|
||||
L.log += (message + "\n")
|
||||
if(!C.chatOutput || C.chatOutput.broken) // A player who hasn't updated his skin file.
|
||||
C << original_message
|
||||
return TRUE
|
||||
|
||||
if(!C.chatOutput.loaded)
|
||||
//Client sucks at loading things, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
//But also send it to their output window since that shows until goonchat loads
|
||||
C << original_message
|
||||
return
|
||||
|
||||
message = replacetext(message, "\n", "<br>")
|
||||
message = replacetext(message, "\t", " ")
|
||||
|
||||
// url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
target << output(url_encode(url_encode(message)), "browseroutput:output")
|
||||
C << output(url_encode(url_encode(message)), "browseroutput:output")
|
||||
|
||||
/proc/grab_client(target)
|
||||
if(istype(target, /client))
|
||||
@@ -284,6 +270,3 @@ GLOBAL_LIST_EMPTY(bicon_cache)
|
||||
var/datum/mind/M = target
|
||||
if(M.current && M.current.client)
|
||||
return M.current.client
|
||||
|
||||
/datum/log //exists purely to capture to_chat() output
|
||||
var/log = ""
|
||||
@@ -0,0 +1,51 @@
|
||||
diff a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm (rejected hunks)
|
||||
@@ -32,7 +32,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
alert(owner.mob, "Updated chat window does not exist. If you are using a custom skin file please allow the game to update.")
|
||||
return
|
||||
|
||||
- if(winget(owner, "browseroutput", "is-disabled") == "false") //Already setup
|
||||
+ if(winget(owner, "browseroutput", "is-visible") == "true") //Already setup
|
||||
doneLoading()
|
||||
|
||||
else //Not setup
|
||||
@@ -90,7 +90,10 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
|
||||
testing("Chat loaded for [owner.ckey]")
|
||||
loaded = TRUE
|
||||
- winset(owner, "browseroutput", "is-disabled=false")
|
||||
+ winset(owner, "output", "is-disabled=true;is-visible=false")
|
||||
+ winset(owner, "browseroutput", "is-disabled=false;is-visible=true")
|
||||
+
|
||||
+
|
||||
for(var/message in messageQueue)
|
||||
to_chat(owner, message)
|
||||
|
||||
@@ -228,7 +231,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
targets = target
|
||||
if(!targets.len)
|
||||
return
|
||||
-
|
||||
+ var/original_message = message
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
@@ -241,14 +244,16 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
|
||||
if (!C)
|
||||
continue
|
||||
-
|
||||
+
|
||||
if(!C.chatOutput || C.chatOutput.broken) // A player who hasn't updated his skin file.
|
||||
- C << message
|
||||
+ C << original_message
|
||||
return TRUE
|
||||
-
|
||||
+
|
||||
if(!C.chatOutput.loaded)
|
||||
//Client sucks at loading things, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
+ //But also send it to their output window since that shows until goonchat loads
|
||||
+ C << original_message
|
||||
return
|
||||
|
||||
// url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Chat</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css" href="font-awesome.css" />
|
||||
<link rel="stylesheet" type="text/css" href="browserOutput.css" />
|
||||
<script type="text/javascript" src="errorHandler.js"></script>
|
||||
<script type="text/javascript" src="jquery.min.js"></script>
|
||||
<script type="text/javascript" src="json2.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="loading">
|
||||
<i class="icon-spinner icon-2x"></i>
|
||||
<div>
|
||||
Loading...<br><br>
|
||||
If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times.<br>
|
||||
If it <b>still</b> doesn't work, use the bug report button at the top right of the window.
|
||||
</div>
|
||||
</div>
|
||||
<div id="messages">
|
||||
|
||||
</div>
|
||||
<div id="userBar" style="display: none;">
|
||||
<div id="ping">
|
||||
<i class="icon-circle" id="pingDot"></i>
|
||||
<span class="ms" id="pingMs">--ms</span>
|
||||
</div>
|
||||
<div id="options">
|
||||
<a href="#" class="toggle" id="toggleOptions" title="Options"><i class="icon-cog"></i></a>
|
||||
<div class="sub" id="subOptions">
|
||||
<a href="#" class="decreaseFont" id="decreaseFont"><span>Decrease font size</span> <i class="icon-font">-</i></a>
|
||||
<a href="#" class="increaseFont" id="increaseFont"><span>Increase font size</span> <i class="icon-font">+</i></a>
|
||||
<a href="#" class="togglePing" id="togglePing"><span>Toggle ping display</span> <i class="icon-circle"></i></a>
|
||||
<a href="#" class="highlightTerm" id="highlightTerm"><span>Highlight string</span> <i class="icon-tag"></i></a>
|
||||
<a href="#" class="saveLog" id="saveLog"><span>Save chat log</span> <i class="icon-save"></i></a>
|
||||
<a href="#" class="clearMessages" id="clearMessages"><span>Clear all messages</span> <i class="icon-eraser"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="browserOutput.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+27
-1
@@ -1617,7 +1617,7 @@ window "outputwindow"
|
||||
font-style = ""
|
||||
text-color = #000000
|
||||
background-color = #ffffff
|
||||
is-visible = true
|
||||
is-visible = false
|
||||
is-disabled = true
|
||||
is-transparent = false
|
||||
is-default = false
|
||||
@@ -1632,6 +1632,32 @@ window "outputwindow"
|
||||
use-title = false
|
||||
on_show = ""
|
||||
on_hide = ""
|
||||
elem "output"
|
||||
type = OUTPUT
|
||||
pos = 0,0
|
||||
size = 640x480
|
||||
anchor1 = 0,0
|
||||
anchor2 = 100,100
|
||||
font-family = ""
|
||||
font-size = 0
|
||||
font-style = ""
|
||||
text-color = #000000
|
||||
background-color = #ffffff
|
||||
is-visible = true
|
||||
is-disabled = false
|
||||
is-transparent = false
|
||||
is-default = true
|
||||
border = none
|
||||
drop-zone = false
|
||||
right-click = false
|
||||
saved-params = ""
|
||||
on-size = ""
|
||||
show-history = false
|
||||
show-url = false
|
||||
auto-format = false
|
||||
use-title = false
|
||||
on_show = ""
|
||||
on_hide = ""
|
||||
|
||||
window "statwindow"
|
||||
elem "statwindow"
|
||||
|
||||
Reference in New Issue
Block a user