/* Original Script by cbk1994 Updated by fowlplay4 1. Added work-around for downloading images. No longer need to add anything to folder config. See function getGraphic(img) for more notes on that. 2. Added support for setting transparencies via fiximagetransparency(filepath) 3. Updated naming to be more user-friendly by changing the getUploadFullName() function. Prevents players from using periods in the name however. 4. Added support for hats. 5. Added support for using a different database. 6. Fixed to use V6's new uploadfile() function. */ function onCreated() { this.admins = {"fowlplay4", "cbk1994"}; this.custom_db = "default"; createTable(); } function onActionServerSide(cmd, data, pars) { switch (cmd) { case "requestFunc": temp.funcs = {"getAdminGraphics", "getMyUploads", "getAdmins", "getGraphic"}; if (funcs.index(@ data) <= -1) { printf("Hacker Alert: %s (%s) is attempting to send unrequestable function %s (uploads manager)!", player.communityname, player.account, data); return; } temp.returned = this.(@ data)(pars); if (returned == "msg") { return; } triggerclient("gui", name, "returnFunc", data, returned); break; case "callFunc": temp.funcs = {"doApproveGraphic", "doDenyGraphic", "doGraphicUploaded"}; if (funcs.index(@ data) <= -1) { printf("Hacker Alert: %s (%s) is attempting to send uncallable function %s (uploads manager)!", player.communityname, player.account, data); return; } this.(@ data)(pars); break; } } function getAdmins() { return this.admins; } function isStaff() { return player.account in this.admins; } function doGraphicUploaded(data) { // {filePath, fileName, getUploadFullName(), SupportUpload_Type.getSelectedText(), SupportUpload_Trans.checked} temp.path = data[0]; if (! fileexists(path)) { // client-rc upload? return; } temp.uName = data[1]; temp.fName = data[2].lower(); fName = fName.substring(0, fName.length() - 3); temp.gType = data[3]; temp.trans = (data[4] == true); temp.t = path.tokenize("."); temp.ext = t[t.size() - 1]; fName @= ext; if (fileSize(path) > 400000) { msg("Sorry, but your file must be no larger than 400 KB. Try using PNG 8 or another efficient format."); deletefile(path); return; } temp.okay = isOkay(path, ext, uName); if (okay != true) { msg("You uploaded an invalid file! Please remember that only PNG and GIF images will be accepted."); if (okay == 0) { deletefile(path); } else { // faked header movefile(path, "uploads/illegal/" @ player.account @ "_file" @ int(timevar2) @ "." @ ext); } return; } // check if the file already exists if (levelExists(fName) || headExists(fName) || shieldExists(fName) || bodyExists(fName) || req("SELECT count(*) FROM 'support_uploads' WHERE filename = '" @ fName.escape() @ "' AND status != 'denied'", true)[0][0] > 0) { deletefile(path); return msg("Sorry, a file already exists with that name!"); } temp.loc = "levels/uploads/upload_" @ player.account @ "_" @ int(timevar2) @ "." @ ext; movefile(path, loc); msg("Your file has been submitted successfully to the upload queue!"); // Fix Transparency Functionality if (temp.trans) { fiximagetransparency(loc); } req("INSERT INTO 'support_uploads' VALUES('" @ player.account.escape() @ "', '" @ gType.lower() @ "', '" @ fName.escape() @ "', '" @ loc.escape() @ "', 'pending', '', 0, '')"); } function isOkay(path, ext, fName) { if (! (ext in {"png", "gif"})) { return; } temp.str.loadLines(path); if ((ext == "png" && str.pos("PNG") >= 0) || (ext == "gif" && str.pos("GIF8") >= 0)) { return true; } else { // faked header temp.msg = { format("File Uploads: %s (%s) tried to upload graphic '%s' with a faked header!", player.communityname, player.account, fName), format(" File has been moved to: %s", "uploads/illegal/" @ player.account @ "_file" @ int(timevar2) @ "." @ ext) }; printf(msg[0]); printf(msg[1]); savelog2("uploads.txt", msg[0] @ "\n" @ msg[1]); return 2; } } function doApproveGraphic(gid) { if (! isStaff()) { return msg("You are not staff!"); } temp.file = req("SELECT uploader, type, filename, path, accepted FROM 'support_uploads' WHERE rowid = " @ gid.escape(), true)[0]; temp.uploader = file[0]; temp.gType = file[1]; temp.fName = file[2]; temp.path = file[3]; temp.status = file[4]; if (status) { return; } if (fileExists(path)) { temp.mPath = ""; switch (gType) { case "head": mPath = "levels/heads/"; break; case "body": mPath = "levels/bodies/"; break; case "shield": mPath = "levels/shields/"; break; case "hat": mPath = "levels/hats/"; break; } moveFile(path, mPath @ fName); } req("UPDATE 'support_uploads' SET 'accepted' = 1, admin = '" @ player.account.escape() @ "', status = 'accepted' WHERE rowid = " @ gid.escape()); } function doDenyGraphic(data) { if (! isStaff()) { return msg("You are not staff!"); } temp.gid = data[0]; temp.reason = data[1]; temp.file = req("SELECT path, status FROM 'support_uploads' WHERE rowid = " @ gid.escape(), true)[0]; temp.path = file[0]; temp.status = file[1]; if (status != "pending") { return; } if (fileExists(path)) { deletefile(path); } req("UPDATE 'support_uploads' SET 'accepted' = 0, admin = '" @ player.account.escape() @ "', status = 'denied', reason = '" @ reason.escape() @ "' WHERE rowid = " @ gid.escape()); } function getMyUploads() { // return {pending, approved, denied} // which are in form {id, type, upload name, admin, reason, path} temp.pending = req("SELECT rowid, type, filename, admin, reason, path FROM 'support_uploads' WHERE uploader = '" @ player.account.escape() @ "' AND status = 'pending'", true); temp.approved = req("SELECT rowid, type, filename, admin, reason, path FROM 'support_uploads' WHERE uploader = '" @ player.account.escape() @ "' AND status = 'accepted'", true); temp.denied = req("SELECT rowid, type, filename, admin, reason, path FROM 'support_uploads' WHERE uploader = '" @ player.account.escape() @ "' AND status = 'denied'", true); return {pending, approved, denied}; } function getGraphic(img) { // Work-around for Folder Config Modification // Basically so players can't use the files in // the uploads folder as hats before they've been // approved. Clients probably need V6 in order to // view them properly. temp.filedata.loadstring("levels/uploads/" @ img); temp.filedata = base64encode(temp.filedata); return {img, temp.filedata}; } function getAdminGraphics() { return req("SELECT rowid, type, filename, path, uploader FROM 'support_uploads' WHERE status = 'pending' ORDER BY type", true); } function createTable() { // support_uploads req("CREATE TABLE IF NOT EXISTS 'support_uploads' ( uploader TEXT NOT NULL DEFAULT '', type TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'pending', admin TEXT NOT NULL DEFAULT '', accepted INT NOT NULL DEFAULT 0, reason TEXT NOT NULL DEFAULT '' )"); req("CREATE INDEX IF NOT EXISTS 'idx_support_uploads_uploader' ON 'support_uploads' (uploader)"); } // SQL stuff function req(request, wait) { temp.req = requestsql2(this.custom_db, request, wait); if (req.error != "") { errorSql(req.error, request); } if (wait == 0) { return; } if (! req.completed) { waitfor(req, "onReceiveData", 60); } return req.rows; } function errorSql(error, query) { echo("SQL Error:" SPC error); echo(" Query:" SPC query); savelog2("sqlerror.txt", "SQL Error:" SPC error @ "\n Query:" SPC query); } // Dialog function msg(msg) { triggerclient("gui", name, "showDialog", msg); return "msg"; } //#CLIENTSIDE function onCreated() { initProfiles(); requestServer("getAdmins"); } function onKeyPressed(code, key, id) { if (code == 122) { // F11 showMainWindow(); } } // Serverside Interaction function requestServer(func, data) { triggerserver("gui", name, "requestFunc", func, data); } function tellServer(func, data) { triggerserver("gui", name, "callFunc", func, data); } function onActionClientSide(cmd, func, data) { switch (cmd) { case "showDialog": showDialog(func); break; case "returnFunc": this.funcReturned(func, data); break; } } function funcReturned(func, data) { switch (func) { case "getAdmins": this.admins = data; break; case "getMyUploads": showMyUploads(data[0], data[1], data[2]); break; case "getAdminGraphics": showAdminGraphics(data); break; case "getGraphic": temp.filedata = base64decode(data[1]); temp.filedata.savestring("uploads/" @ data[0], 0); break; } } // GUI Profiles function initProfiles() { new GuiTextProfile("SupportTextProfile") { modal = false; fontColor = {0, 0, 0}; } } // Interfaces function showMainWindow() { if (isObject("SupportMain_Window")) { SupportMain_Window.destroy(); // destroy if open } new GuiWindowCtrl("SupportMain_Window") { profile = "GuiBlueWindowProfile"; visible = canClose = canMove = canMinimize = true; canResize = canMaximize = false; text = getServerName() @ " Upload Manager [F11]"; showTop(); temp.options = { {"upload", "Upload Graphics", "Submit heads, bodies, and shields to be added to the game."}, {"viewuploads", "View Uploads", "View pending and uploaded graphics you've submitted."} }; if (player.account in thiso.admins) { options.add({"viewu", "Manage Uploads", "Manage uploaded heads, shields, and bodies."}); } width = 19 + (141 * min(3, options.size())); // draw main frame with (addBar("SupportMain_MainFrame", 0, true)) { profile.fillColor = {179, 199, 226, 200}; x = 10; y = 28; width = SupportMain_Window.width - 20; height = 45; new GuiMLTextCtrl("SupportMain_MainFrame_Text") { profile = "SupportTextProfile"; x = 5; y = 2; width = SupportMain_Window.width - 30; text = "

" @ getServerName() @ " Upload Manager
Click one of the options below.

"; } } height = 83 + (79 * ceil(options.size() / 3)); y = GraalControl.height / 2 - (height / 2); // recenter temp.c = 0; for (temp.option : options) { with (addBar("SupportMain_Frame_" @ c, 0, true)) { profile.fillColor = {159, 179, 206, 180}; x = 10 + (142 * (c % 3)); y = 77 + (79 * int(c / 3)); width = 138; height = 75; this.action = option[0]; new GuiMLTextCtrl(name @ "_Text") { profile = "SupportTextProfile"; x = 5; y = 2; width = 128; text = "

" @ option[1] @ "
" @ option[2] @ "

"; } thiso.catchEvent(this, "onMouseEnter", "onMouseEntersFrame"); thiso.catchEvent(this, "onMouseLeave", "onMouseLeavesFrame"); thiso.catchEvent(this, "onMouseDown", "onMouseClicksFrame"); } c ++; } x = GraalControl.width / 2 - (width / 2); y = GraalControl.height / 2 - (height / 2); } } function ceil(int) { if (int(int) != int) { return int(int) + 1; } return int; } function onMouseEntersFrame(frame) { frame.profile.fillColor = {179, 199, 226, 180}; } function onMouseLeavesFrame(frame) { frame.profile.fillColor = {159, 179, 206, 180}; } function onMouseClicksFrame(frame) { switch (frame.action) { case "viewuploads": requestServer("getMyUploads"); break; case "viewu": requestServer("getAdminGraphics"); break; case "upload": showUploadFile(); break; } } function showUploadFile() { if (isObject("SupportUpload_Window")) { SupportUpload_Window.destroy(); } new GuiWindowCtrl("SupportUpload_Window") { profile = "GuiBlueWindowProfile"; width = 250; height = 268 + 25 + 20; x = GraalControl.width / 2 - (width / 2); y = GraalControl.height / 2 - (height / 2); canMinimize = canClose = visible = true; canMaximize = canResize = false; text = "Upload Graphics"; temp.startY = 24; with (addBar("SupportUpload_Bar1", 0)) { x = 6; y = startY; width = 238; height = 50; startY += height; new GuiMLTextCtrl("SupportUpload_Warning") { profile = "SupportTextProfile"; x = 5; y = 1; width = 228; text = "

Warning:
Uploading obscene, indecent, stolen, or copyrighted images will result in a jail or ban.

"; } } with (addBar("SupportUpload_Bar6", 1)) { x = 6; y = startY; width = 238; height = 50; startY += height; new GuiMLTextCtrl("SupportUpload_Remember") { profile = "SupportTextProfile"; x = 5; y = 1; width = 228; text = "

No stolen, recolored, or copyrighted graphics\nNo heads with hats that exist\nNo invisible or mostly transparent graphics

"; } } with (addBar("SupportUpload_Bar2", 2)) { x = 6; y = startY; width = 238; height = 25; startY += height; new GuiMLTextCtrl("SupportUpload_TypeLabel") { profile = "SupportTextProfile"; x = 5; y = 5; width = 228; text = "Type:"; } new GuiPopUpMenuCtrl("SupportUpload_Type") { profile = "GuiBluePopUpMenuProfile"; textprofile = "GuiBlueTextListProfile"; scrollprofile = "GuiBlueScrollProfile"; width = 197; height = 21; x = 38; y = 2; clearRows(); temp.types = {"Head", "Body", "Shield", "Hat"}; for (temp.t : types) { addRow(0, t); } setSelectedRow(0); } } with (addBar("SupportUpload_Bar3", 3)) { x = 6; y = startY; width = 238; height = 25; startY += height; new GuiMLTextCtrl("SupportUpload_NameLabel") { profile = "SupportTextProfile"; x = 5; y = 5; width = 228; text = "Name:"; } new GuiTextEditCtrl("SupportUpload_Name") { profile = "GuiBlueTextEditProfile"; width = 197; height = 21; x = 38; y = 2; clearRows(); text = "my-graphic"; } } with (addBar("SupportUpload_Bar8", 4)) { x = 6; y = startY; width = 238; height = 25; startY += height; new GuiCheckBoxCtrl("SupportUpload_Trans") { profile = "GuiBlueCheckBoxProfile"; useownprofile = true; profile.fontcolor = "black"; width = 197; height = 21; x = 38; y = 2; clearRows(); text = "Set Transparencies"; checked = false; } } with (addBar("SupportUpload_Bar4", 5)) { x = 6; y = startY; width = 238; height = 58; startY += height; new GuiMLTextCtrl("SupportUpload_NameWarning") { profile = "SupportTextProfile"; x = 5; y = 5; width = 228; text = "

Set Transparencies makes the transparent color as the same color in the top left corner of the graphic.

"; } } with (addBar("SupportUpload_Bar5", 6)) { x = 6; y = startY; width = 238; height = 25; startY += height; new GuiMLTextCtrl("SupportUpload_FullName") { profile = "SupportTextProfile"; x = 5; y = 5; width = 228; } } with (addBar("SupportUpload_Bar7", 7)) { x = 6; y = startY; width = 238; height = 25; startY += height; new GuiButtonCtrl("SupportUpload_Browse") { profile = "GuiBlueButtonProfile"; width = 248; height = 26; x = (- 5); y = 0; text = "Browse"; } } } } function FileSelector_Window.onCloseQuery() { filesClosed(); } function FileSelector_CancelButton.onAction() { filesClosed(); } function filesClosed() { if (SupportUpload_Browse.active == false && SupportUpload_Window.visible) { SupportUpload_Browse.active = true; SupportUpload_Window.active = true; } } function SupportUpload_Private.onAction() { updateFullName(); } function SupportUpload_Type.onSelect(z, text) { if (text != "Head") { SupportUpload_Private.active = false; SupportUpload_Private.alpha = .6; } else { SupportUpload_Private.active = true; SupportUpload_Private.alpha = 1; } updateFullName(); } function SupportUpload_Name.onTextChanged() { updateFullName(); } function updateFullName() { SupportUpload_FullName.text = "

" @ getUploadFullName() @ "

"; } function SupportUpload_Browse.onAction() { SupportUpload_Window.active = false; SupportUpload_Browse.active = false; playerUploadFile(); } function onPlayerFileUploaded(fileName, filePath) { if (SupportUpload_Browse.active == false && SupportUpload_Window.visible) { tellServer("doGraphicUploaded", {filePath, fileName, getUploadFullName(), SupportUpload_Type.getSelectedText(), SupportUpload_Trans.checked}); SupportUpload_Window.destroy(); } } function getUploadPrefix(gType, gName) { temp.tokens = getServerName().lower().tokenize(); temp.svr = tokens[0]; switch (gType) { case "Head": temp.prefix = svr @ "_head-"; break; case "Body": temp.prefix = svr @ "_body-"; break; case "Shield": temp.prefix = svr @ "_shield-"; break; case "Hat": temp.prefix = svr @ "_hat-"; break; } return gName.starts(temp.prefix) ? "" : temp.prefix; } function getUploadFullName() { temp.gType = SupportUpload_Type.getSelectedText(); temp.gName = SupportUpload_Name.text; temp.gName = temp.gName.substring(0, temp.gName.pos(".")); temp.fullname = getUploadPrefix(gType, gName) @ gName @ ".ext"; return temp.fullname; } function playerUploadFile() { player.waitingForUpload = true; requestText("folder", "PERSONAL"); FileSelector_Window.requestscript = this.name; temp.file = selectFileForUpload(); } function onSelectedFileForUpload(fullfilename) { if (FileSelector_Window.requestscript==this.name) uploadfile(fullfilename); } function onFolderLog(msg) { if (! player.waitingForUpload) { return; } if (! msg.starts("Uploaded")) { return; } player.waitingForUpload = false; temp.filePath = msg.substring(msg.starts("Uploaded file") ? 14 : 18); if (msg.starts("Uploaded big")) { filePath = filePath.substring(0, filePath.length() - 1); } temp.parts = filePath.tokenize("/"); temp.fileName = parts[parts.size() - 1]; this.trigger("onPlayerFileUploaded", fileName, filePath); } function showMyUploads(pending, approved, denied) { if (isObject("SupportMyUploads_Window")) { SupportMyUploads_Window.destroy(); } new GuiWindowCtrl("SupportMyUploads_Window") { profile = "GuiBlueWindowProfile"; width = 300; height = 230; x = GraalControl.width / 2 - (width / 2); y = GraalControl.height / 2 - (height / 2); canMinimize = canClose = visible = true; canMaximize = canResize = false; text = "My Uploads"; temp.tabs = null; new GuiTabCtrl("SupportMyUploads_Tabs") { profile = "GuiBlueTabProfile"; width = 270; height = 23; tabwidth = 88; x = 15; y = 27; clearRows(); tabs.add(this.addRow(0, "Pending")); tabs.add(this.addRow(0, "Approved")); tabs.add(this.addRow(0, "Denied")); } temp.c = 0; for (temp.tab : {pending, approved, denied}) { new GuiScrollCtrl("SupportMyUploads_Scroll_" @ c) { profile = "GuiBlueScrollProfile"; useownprofile = true; profile.border = 1; x = 10; y = 49; width = 280; height = 172; tabs[c].scroll = this; visible = false; vScrollBar = "alwaysOff"; hScrollBar = "alwaysOff"; temp.par = this; new GuiMLTextCtrl("SupportMyUploads_" @ c @ "_Info") { profile = "GuiBlueMLTextProfile"; width = 145; x = 130; y = 2; text = "\n\n\n
Click one of the files on the left for information.
"; par.info = this; } new GuiScrollCtrl("SupportMyUploads_Scroll_" @ c @ "_ListScroll") { profile = "GuiBlueScrollProfile"; useownprofile = true; profile.border = 1; profile.opaque = true; profile.fillColor = {255, 100, 255, 1}; x = (- 1); y = (- 1); width = 130; height = 171; vScrollBar = "alwaysOn"; hScrollBar = "alwaysOff"; temp.alt = 0; for (temp.upload : tab) { with (addBar("SupportMyUploads_Scroll_" @ c @ "_List_" @ upload[0], alt)) { height = 36; y = alt * height; this.fColor = profile.fillColor; this.info = upload; this.info.insert(0, c); thiso.catchEvent(this, "onMouseEnter", "onEnterBar"); thiso.catchEvent(this, "onMouseLeave", "onLeaveBar"); thiso.catchEvent(this, "onMouseDown", "onClickBar"); temp.bar = this; new GuiShowImgCtrl(name @ "_" @ alt @ "_Image") { bar.graphic = this; active = false; temp.tokens = upload[5].tokenize("/"); image = tokens[tokens.size() - 1]; if (upload[1] == "head" || c == 2) { x = 2; y = 4; width = 32; height = 32; if (c != 2) { offsety = (- 64); } } else if (upload[1] == "body") { x = 2; y = 1; width = 32; height = 32; offsetx = (- 64); } else if (upload[1] == "shield") { x = 10; y = 8; width = 16; height = 20; offsetx = (- 14); } else if (upload[1] == "hat") { x = 0; y = 0; partw = 48; parth = 48; stretchx = 32 / 48; stretchy = 32 / 48; offsetx = -4; offsety = -4; } if (c == 2) { image = "support_denied.png"; y -= 2; } } new GuiTextCtrl(name @ "_" @ c @ "_" @ alt @ "_Text") { profile = "SupportTextProfile"; x = 38; y = 8; width = 200; text = upload[2]; } } alt ++; } } } c ++; } } SupportMyUploads_Tabs.setSelectedRow(0); } function onEnterBar(bar) { bar.profile.fillColor = {bar.fColor[0] + 20, bar.fColor[1] + 20, bar.fColor[2] + 20}; } function onLeaveBar(bar) { bar.profile.fillColor = bar.fColor; } function onClickBar(bar) { temp.info = bar.info; temp.i = bar.parent.parent.info; i.text = "\n
" @ info[3] @ "\n" @ info[2].charat(0).upper() @ info[2].substring(1); if (info[0] == 0) { i.text @= "\n\nPending approval"; } else if (info[0] == 1) { i.text @= "\n\nApproved by: " @ info[4]; } else if (info[0] == 2) { i.text @= "\n\nDenied by: " @ info[4] @ "\nReason: " @ info[5]; } } function SupportMyUploads_Tabs.onSelect(rowid, rowtext, rowindex) { SupportMyUploads_Tabs.selectedScroll.visible = false; temp.scroll = SupportMyUploads_Tabs.rows[rowindex].scroll; SupportMyUploads_Tabs.selectedScroll = scroll; scroll.visible = true; } function showAdminGraphics(graphics) { if (isObject("SupportAdminGraphics_Window")) { SupportAdminGraphics_Window.destroy(); } new GuiWindowCtrl("SupportAdminGraphics_Window") { profile = "GuiBlueWindowProfile"; width = 300; height = 245; x = GraalControl.width / 2 - (width / 2); y = GraalControl.height / 2 - (height / 2); text = getServerName() @ " Uploads Manager"; visible = canClose = canMinimize = true; canResize = canMaximize = canMinimize = false; this.gfx = graphics; this.cgfx = (- 1); with (addBar("SupportAdminGraphics_Graphic", 0)) { profile.fillColor = {173, 204, 222}; width = 100; height = 213; x = 7; y = 25; new GuiControl("SupportAdminGraphics_GraphicContainer") { x = 0; y = 0; width = 100; height = 213; } with (addBar("SupportAdminGraphics_TypeBar", 1, true)) { width = 102; height = 20; x = (- 1); y = (- 1); new GuiMLTextCtrl("SupportAdminGraphics_Type") { profile = "SupportTextProfile"; useownprofile = true; profile.fontSize = 17; x = (- 1); y = 1; width = 102; text = "
Waiting...
"; } } } with (addBar("SupportAdminGraphics_SideBar", 0, true)) { profile.fillColor = {183, 194, 212}; width = 188; height = 216; x = 107; y = 23; new GuiControl("SupportAdminGraphics_InfoContainer") { useownprofile = true; profile.border = 1; profile.opaque = true; profile.fillColor = {153, 184, 202, 120}; width = 174; height = 50; x = 7; y = 7; new GuiMLTextCtrl("SupportAdminGraphics_Info") { profile = "SupportTextProfile"; width = 174; x = 0; y = 2; text = ""; } } new GuiMLTextCtrl("SupportAdminGraphics_Hover") { profile = "SupportTextProfile"; width = 174; x = 7; y = 60; text = "
Hover your mouse over a button for an expanded description.
"; } temp.reasons = { {"Stolen", "Stolen, recolored, or copyrighted graphic"}, {"Innapropriate", "Obscene, pornographic, political, or indecent graphic"}, {"Invisible", "Invisible or mostly invisible graphic"}, {"Contains Hat", "Head contains a hat that exists"} }; temp.c = 0; for (temp.reason : reasons) { new GuiButtonCtrl("SupportAdminGraphics_Deny_" @ c) { profile = "GuiBlueButtonProfile"; width = 85; height = 20; x = 7 + (c % 2) * (width + 4); y = 94 + int(c / 2) * (height + 4); text = reason[0]; this.trueReason = reason[1]; hint = reason[1]; thiso.catchEvent(this, "onAction", "onDenyButton"); } c ++; } new GuiButtonCtrl("SupportAdminGraphics_CustomDeny") { profile = "GuiBlueButtonProfile"; width = 175; height = 20; x = 7; y = 94 + (ceil(c / 2) * (height + 4)); text = "Custom Deny Reason"; hint = "Write your own custom deny reason when one of the above ones don't work."; c += 2; } new GuiButtonCtrl("SupportAdminGraphics_Accept") { profile = "GuiBlueButtonProfile"; width = 175; height = 20; x = 7; y = 94 + (ceil(c / 2) * (height + 4)); text = "Approve"; hint = "Approve and make active this graphic."; c += 2; } new GuiButtonCtrl("SupportAdminGraphics_Skip") { profile = "GuiBlueButtonProfile"; width = 175; height = 20; x = 7; y = 94 + (ceil(c / 2) * (height + 4)); text = "Skip"; hint = "Skip this graphic (do not approve or deny - leave it in the queue)."; c += 2; } } } nextGraphic(); } function onDenyButton(button) { temp.realReason = button.trueReason; denyCurrent(realReason); } function SupportAdminGraphics_CustomDeny.onAction() { showDialogInput("Why should this image be denied?", "Deny", "onCustomDeny", SupportAdminGraphics_Window.gfx[SupportAdminGraphics_Window.cgfx][0]); } function onCustomDeny(text, gid) { if (SupportAdminGraphics_Window.gfx[SupportAdminGraphics_Window.cgfx][0] != gid) { return; // custom deny reason for another image in the queue } denyCurrent(text); } function denyCurrent(reason) { temp.graphic = SupportAdminGraphics_Window.gfx[SupportAdminGraphics_Window.cgfx]; temp.gid = graphic[0]; tellServer("doDenyGraphic", {gid, reason}); nextGraphic(); } function SupportAdminGraphics_Accept.onAction() { temp.graphic = SupportAdminGraphics_Window.gfx[SupportAdminGraphics_Window.cgfx]; tellServer("doApproveGraphic", graphic[0]); nextGraphic(); } function SupportAdminGraphics_Skip.onAction() { nextGraphic(); } function nextGraphic() { setTimer(0); SupportAdminGraphics_Window.cgfx ++; temp.graphic = SupportAdminGraphics_Window.gfx[SupportAdminGraphics_Window.cgfx]; if (graphic.size() <= 0) { showDialog("All graphics have been moderated!"); return SupportAdminGraphics_Window.destroy(); // no more graphics } // id, type, upload name, path, uploader SupportAdminGraphics_Type.text = "
" @ graphic[1].charat(0).upper() @ graphic[1].substring(1) @ "
"; SupportAdminGraphics_Info.text = "
" @ graphic[2] @ "\nUploaded by: " @ graphic[4] @ "\n"; SupportAdminGraphics_Info.before = SupportAdminGraphics_Info.text; temp.myName = graphic[3].tokenize("/"); myName = myName[myName.size() - 1]; if (getimgwidth(myName) > 0) { SupportAdminGraphics_Info.text @= getimgwidth(myName) @ "x" @ getimgheight(myName) @ "
"; fillUploadImage(graphic[1], myName); } else { // wait for the graphic to load SupportAdminGraphics_Info.text @= "Loading...
"; this.waitingGraphic = myName; this.waitName = graphic[2]; this.waitType = graphic[1]; this.waitSteps = 0; requestServer("getGraphic", this.waitingGraphic); SupportAdminGraphics_GraphicContainer.clearControls(); setTimer(0.05); } } function fillUploadImage(iType, img) { with (SupportAdminGraphics_GraphicContainer) { this.clearControls(); switch (iType) { case "head": new GuiShowImgCtrl("SupportAdminGraphics_Head1") { image = img; x = 3; y = 22; width = 32; height = 176; } new GuiShowImgCtrl("SupportAdminGraphics_Head2") { image = img; x = 35; y = 22; offsety = (- 176); width = 32; height = 192; } new GuiShowImgCtrl("SupportAdminGraphics_Head3") { image = img; x = 64; y = 22; offsety = (- 368); width = 32; height = 192; } new GuiShowImgCtrl("SupportAdminGraphics_HeadTemplate") { image = "support_template-head.png"; width = 94; height = 192; x = 3; y = 21; } break; case "shield": temp.w = min(98, getimgwidth(img)); temp.h = min(150, getimgheight(img)); temp.percents = {.1579, .2105, .421, .2105}; // shields suck for (temp.i = 0; i < 4; i ++) { new GuiControl("SupportAdminGraphics_ShieldTemplate" @ i) { useownprofile = true; profile.border = 1; profile.bordercolor = {255, 0, 0}; width = min(98, (getimgwidth(img) * percents[i]) + 2); height = h + 2; x = 100 / 2 - (width / 2); y = 25 + (i * (h + 6)); new GuiShowImgCtrl("SupportAdminGraphics_Shield" @ i) { image = img; width = min(98, getimgwidth(img) * percents[i]); height = h; x = 1; y = 1; offsetx = (- (getimgwidth(img) * percents[i])); } } } break; case "body": temp.c = 0; temp.parts = { {0, 0}, {32, 0}, {64, 0}, {96, 0}, {96, 544}, {96, 577}, {0, 256}, {32, 256}, {64, 256}, {96, 256}, {96, 384}, {96, 608}, {96, 640}, {0, 384}, {64, 640}, {0, 640}, {32, 640}, {64, 384} }; for (temp.part : parts) { new GuiShowImgCtrl("SupportAdminGraphics_Body" @ c) { image = img; x = 3 + (32 * (c % 3)); y = 20 + (32 * int(c / 3)); width = 32; height = 32; offsetx = (- part[0]); offsety = (- part[1]); } c ++; } new GuiShowImgCtrl("SupportAdminGraphics_BodyTemplate") { image = "support_template-body.png"; width = 96; height = 192; x = 2; y = 21; } break; case "hat": new GuiShowImgCtrl("SupportAdminGraphics_Hat") { x = 0; y = 40; offsetx = -46; image = img; stretchx = 0.5; width = 144; height = 192; } break; } } } function onTimeOut() { if (! SupportAdminGraphics_Window.visible) { return; } if (getimgwidth(this.waitingGraphic) > 0) { fillUploadImage(this.waitType, this.waitingGraphic); return SupportAdminGraphics_Info.text = SupportAdminGraphics_Info.before @ getimgwidth(this.waitingGraphic) @ "x" @ getimgheight(this.waitingGraphic) @ ""; } else { this.waitSteps ++; if (this.waitSteps > 200) { // 10 seconds to load? showDialog("Failed to download file '" @ this.waitName @ "': Check if you are lagging, and if not, deny the file. Otherwise, try again later."); return SupportAdminGraphics_Info.text = SupportAdminGraphics_Info.before @ "Load failed"; } } setTimer(0.05); } // GUI functions function addBar(bName, num, hasBorder) { temp.par = this; // parent new GuiControl(@ bName) { useownprofile = true; profile.border = hasBorder; profile.opaque = true; profile.fillColor = ((num % 2) == 1) ? {199, 219, 226} : {153, 184, 202}; x = (- 1); y = (- 1); width = par.width + 1; height = 25; horizSizing = "width"; } return (@ bName); } // Dialogs function showDialog(msg) { new GuiWindowCtrl("SupportDialog_" @ timevar2 @ "_Window") { profile = "GuiBlueWindowProfile"; width = 230; temp.lines = wraptext2(210, SupportTextProfile.fontSize / 24, " ", "@Arial@@" @ msg); temp.tHeight = (lines.size() * (SupportTextProfile.getTextHeight() + 2)); height = tHeight + 57; x = GraalControl.width / 2 - (width / 2); y = GraalControl.height / 2 - (height / 2); canMinimize = canMaximize = canResize = false; canMove = canClose = visible = true; text = "Alert"; temp.startY = 24; with (addBar(name @ "_TextBar", 0)) { width = 218; height = 2 + tHeight; x = 6; y = startY; startY += height; temp.par = this; new GuiMLTextCtrl(name @ "_Text") { profile = "SupportTextProfile"; x = 4; y = 2; width = 210; height = par.height; text = "
" @ msg @ "
"; } } with (addBar(name @ "_CloseBar", 1)) { width = 218; height = 25; x = 6; y = startY; startY += height; new GuiButtonCtrl(name @ "_Close") { profile = "GuiBlueButtonProfile"; width = 208; height = 21; x = 5; y = 2; text = "Close"; thiso.catchEvent(this, "onAction", "onCloseDialog"); } } } } function showDialogInput(msg, button, event, p1, p2) { new GuiWindowCtrl("SupportDialog_" @ timevar2 @ "_Window") { profile = "GuiBlueWindowProfile"; width = 230; temp.lines = wraptext2(210, SupportTextProfile.fontSize / 24, " ", "@Arial@@" @ msg); temp.tHeight = (lines.size() * (SupportTextProfile.getTextHeight() + 2)); height = tHeight + 82; x = GraalControl.width / 2 - (width / 2); y = GraalControl.height / 2 - (height / 2); canMinimize = canMaximize = canResize = false; canMove = canClose = visible = true; text = "Question"; temp.startY = 24; this.eventToCall = {event, p1, p2}; temp.wind = this; with (addBar(name @ "_TextBar", 0)) { width = 218; height = 2 + tHeight; x = 6; y = startY; startY += height; temp.par = this; new GuiMLTextCtrl(name @ "_Text") { profile = "SupportTextProfile"; x = 4; y = 2; width = 210; height = par.height; text = "
" @ msg @ "
"; } } with (addBar(name @ "_InputBar", 1)) { width = 218; height = 25; x = 6; y = startY; startY += height; new GuiTextEditCtrl(name @ "_Input") { profile = "GuiBlueTextEditProfile"; width = 208; height = 21; x = 5; y = 2; wind.input = this; } } with (addBar(name @ "_CloseBar", 2)) { width = 218; height = 25; x = 6; y = startY; startY += height; new GuiButtonCtrl(name @ "_Close") { profile = "GuiBlueButtonProfile"; width = 208; height = 21; x = 5; y = 2; text = button; thiso.catchEvent(this, "onAction", "onDialogInput"); } } } } function onDialogInput(button) { temp.window = button.parent.parent; temp.input = window.input; this.trigger(window.eventToCall[0], input.text, window.eventToCall[1], window.eventToCall[2]); window.destroy(); } function onCloseDialog(button) { button.parent.parent.destroy(); }