From 0d2cdfdd6b469f2c98a175053c94de6bbefbee39 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 3 Jun 2012 23:11:18 -0300 Subject: [PATCH 01/15] filter verb. --- code/models/chatter/commands.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 86f8138..0113ae2 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -1,4 +1,3 @@ - mob chatter verb @@ -593,3 +592,8 @@ mob Home.GoAFK(src, msg) else ReturnAFK() + Filter(msg as text|null) + switch(ckey(msg)) + if("on","1") filter=2 + if("off","0") filter=0 + src << "Filter set [msg]" \ No newline at end of file From 798f60aa791ef88a998de59c4e8080eb26899773 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 3 Jun 2012 23:12:46 -0300 Subject: [PATCH 02/15] fixed something or other. --- code/models/channel.dm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/models/channel.dm b/code/models/channel.dm index 8567599..bff59e4 100644 --- a/code/models/channel.dm +++ b/code/models/channel.dm @@ -1,4 +1,3 @@ - Channel var founder @@ -190,7 +189,7 @@ Channel [world.name] - Created by Xooxerand the BYOND Community [TextMan.fadetext("Still the greatest chat program on BYOND!", list("102000000","255000000","102000000","000000000","000000255"))] Source available on the Chatters Repository. -Copyright © 2008 Andrew "Xooxer" Arnold +Copyright � 2008 Andrew "Xooxer" Arnold [TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] - All Rights Reserved - "}, "[ckey(name)].chat.default_output") @@ -200,7 +199,7 @@ Channel [world.name] - Created by Xooxerand the BYOND Community Still the greatest chat program on BYOND! Source available on the Chatters Repository. -Copyright © 2008 Andrew "Xooxer" Arnold +Copyright � 2008 Andrew "Xooxer" Arnold ########################################## - All Rights Reserved - "}, "[ckey(name)].chat.default_output") @@ -351,7 +350,7 @@ Channel if(c.ignoring(C) & CHAT_IGNORE) continue var/message if(!c.filter) - message = msg + message = raw_msg if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) message = TextMan.ParseLinks(message) message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) From e05d9e70d94cd629188cf7f6076b43a6e2b4b251 Mon Sep 17 00:00:00 2001 From: Stephen Badger Date: Thu, 14 Jun 2012 21:21:43 +0100 Subject: [PATCH 03/15] Removes Network Manager This patch removes the network manager. Be warned, this also makes config loading deterministic (and thus breaks it). --- Chatters.dme | 336 ++++-- code/_global.dm | 409 ++++--- code/controllers/console.dm | 284 +++-- code/controllers/managers/chanman.dm | 604 +++++----- code/controllers/managers/chatman.dm | 363 +++--- code/controllers/managers/helpman.dm | 167 ++- code/controllers/managers/msgman.dm | 89 +- code/controllers/managers/netman.dm | 557 +++++----- code/controllers/managers/opman.dm | 259 +++-- code/models/channel.dm | 1532 +++++++++++++------------- code/models/chatter/_main.dm | 390 ++++--- code/models/chatter/commands.dm | 1195 ++++++++++---------- code/models/chatter/controls.dm | 845 +++++++------- code/world.dm | 97 +- 14 files changed, 3563 insertions(+), 3564 deletions(-) diff --git a/Chatters.dme b/Chatters.dme index a5a2efa..60b3e50 100644 --- a/Chatters.dme +++ b/Chatters.dme @@ -1,100 +1,236 @@ -// DM Environment file for Chatters CS.dme. -// All manual changes should be made outside the BEGIN_ and END_ blocks. -// New source code should be placed in .dm files: choose File/New --> Code File. - -// BEGIN_INTERNALS -// END_INTERNALS -// BEGIN_FILE_DIR -#define FILE_DIR . -// END_FILE_DIR -#define FILE_DIR "resources" - -// BEGIN_PREFERENCES -// END_PREFERENCES - -// BEGIN_INCLUDE -#include "code\_global.dm" -#include "code\client.dm" -#include "code\world.dm" -#include "code\controllers\console.dm" -#include "code\controllers\managers\botman.dm" -#include "code\controllers\managers\chanman.dm" -#include "code\controllers\managers\chatman.dm" -#include "code\controllers\managers\errman.dm" -#include "code\controllers\managers\eventman.dm" -#include "code\controllers\managers\gameman.dm" -#include "code\controllers\managers\helpman.dm" -#include "code\controllers\managers\listman.dm" -#include "code\controllers\managers\logman.dm" -#include "code\controllers\managers\mapman.dm" -#include "code\controllers\managers\msghand.dm" -#include "code\controllers\managers\msgman.dm" -#include "code\controllers\managers\netman.dm" -#include "code\controllers\managers\opman.dm" -#include "code\controllers\managers\paintman.dm" -#include "code\controllers\managers\textman.dm" -#include "code\libraries\rc5\rc5.dm" -#include "code\libraries\s_smiley\alphabetics.dm" -#include "code\libraries\s_smiley\replacetext.dm" -#include "code\libraries\s_smiley\replaceword.dm" -#include "code\libraries\s_smiley\s_smiley.dm" -#include "code\libraries\swapmaps\SwapMaps.dm" -#include "code\libraries\syntaxhighlighter\SyntaxHighlighter.dm" -#include "code\libraries\test\Test.dm" -#include "code\libraries\texthandling\TextHandling.dm" -#include "code\libraries\xml\Element.dm" -#include "code\libraries\xml\Parser.dm" -#include "code\libraries\xml\Prolog.dm" -#include "code\libraries\xml\Tree.dm" -#include "code\libraries\xml\XML.dm" -#include "code\libraries\zipfile\zipfile.dm" -#include "code\models\atoms.dm" -#include "code\models\bot.dm" -#include "code\models\channel.dm" -#include "code\models\host.dm" -#include "code\models\icons.dm" -#include "code\models\messenger.dm" -#include "code\models\op.dm" -#include "code\models\player.dm" -#include "code\models\showcode_snippet.dm" -#include "code\models\tempmob.dm" -#include "code\models\chatter\_main.dm" -#include "code\models\chatter\commands.dm" -#include "code\models\chatter\controls.dm" -#include "code\models\chatter\procs.dm" -#include "code\models\painter\_main.dm" -#include "code\models\painter\colorboxes.dm" -#include "code\models\painter\controls.dm" -#include "code\models\painter\procs.dm" -#include "code\models\painter\tools.dm" -#include "code\views\default.dmf" -#include "code\views\color\_main.dm" -#include "code\views\games\_main.dm" -#include "code\views\games\roll_play.dm" -#include "code\views\help\_main.dm" -#include "code\views\open_chan\_main.dm" -#include "code\views\open_chan\index.dm" -#include "code\views\open_chan\load_chan.dm" -#include "code\views\open_chan\new_chan.dm" -#include "code\views\ops\_main.dm" -#include "code\views\ops\general.dm" -#include "code\views\ops\privileges.dm" -#include "code\views\ops\ranks.dm" -#include "code\views\paint\_main.dm" -#include "code\views\paint\canvas.dm" -#include "code\views\paint\pallete.dm" -#include "code\views\paint\window.dm" -#include "code\views\set\_main.dm" -#include "code\views\set\events.dm" -#include "code\views\set\filters.dm" -#include "code\views\set\general.dm" -#include "code\views\set\icons.dm" -#include "code\views\set\security.dm" -#include "code\views\set\style.dm" -#include "code\views\set\system.dm" -#include "code\views\set\style\colors.dm" -#include "code\views\set\style\default.dm" -#include "code\views\set\style\formats.dm" -// END_INCLUDE - - +// DM Environment file for Chatters CS.dme. +// All manual changes should be made outside the BEGIN_ and END_ blocks. +// New source code should be placed in .dm files: choose File/New --> Code File. + +// BEGIN_INTERNALS +// END_INTERNALS +// BEGIN_FILE_DIR +#define FILE_DIR . +#define FILE_DIR ".git" +#define FILE_DIR ".git/hooks" +#define FILE_DIR ".git/info" +#define FILE_DIR ".git/logs" +#define FILE_DIR ".git/logs/refs" +#define FILE_DIR ".git/logs/refs/heads" +#define FILE_DIR ".git/logs/refs/remotes" +#define FILE_DIR ".git/logs/refs/remotes/kevans" +#define FILE_DIR ".git/logs/refs/remotes/origin" +#define FILE_DIR ".git/objects" +#define FILE_DIR ".git/objects/01" +#define FILE_DIR ".git/objects/04" +#define FILE_DIR ".git/objects/05" +#define FILE_DIR ".git/objects/09" +#define FILE_DIR ".git/objects/0a" +#define FILE_DIR ".git/objects/0d" +#define FILE_DIR ".git/objects/0e" +#define FILE_DIR ".git/objects/10" +#define FILE_DIR ".git/objects/12" +#define FILE_DIR ".git/objects/1d" +#define FILE_DIR ".git/objects/27" +#define FILE_DIR ".git/objects/37" +#define FILE_DIR ".git/objects/38" +#define FILE_DIR ".git/objects/3a" +#define FILE_DIR ".git/objects/3f" +#define FILE_DIR ".git/objects/41" +#define FILE_DIR ".git/objects/4b" +#define FILE_DIR ".git/objects/54" +#define FILE_DIR ".git/objects/55" +#define FILE_DIR ".git/objects/57" +#define FILE_DIR ".git/objects/5a" +#define FILE_DIR ".git/objects/5c" +#define FILE_DIR ".git/objects/61" +#define FILE_DIR ".git/objects/67" +#define FILE_DIR ".git/objects/6d" +#define FILE_DIR ".git/objects/79" +#define FILE_DIR ".git/objects/85" +#define FILE_DIR ".git/objects/86" +#define FILE_DIR ".git/objects/88" +#define FILE_DIR ".git/objects/89" +#define FILE_DIR ".git/objects/8a" +#define FILE_DIR ".git/objects/90" +#define FILE_DIR ".git/objects/92" +#define FILE_DIR ".git/objects/95" +#define FILE_DIR ".git/objects/9a" +#define FILE_DIR ".git/objects/9b" +#define FILE_DIR ".git/objects/a5" +#define FILE_DIR ".git/objects/ad" +#define FILE_DIR ".git/objects/af" +#define FILE_DIR ".git/objects/b1" +#define FILE_DIR ".git/objects/b3" +#define FILE_DIR ".git/objects/ba" +#define FILE_DIR ".git/objects/bb" +#define FILE_DIR ".git/objects/bd" +#define FILE_DIR ".git/objects/bf" +#define FILE_DIR ".git/objects/c1" +#define FILE_DIR ".git/objects/c4" +#define FILE_DIR ".git/objects/c6" +#define FILE_DIR ".git/objects/ca" +#define FILE_DIR ".git/objects/d0" +#define FILE_DIR ".git/objects/da" +#define FILE_DIR ".git/objects/e0" +#define FILE_DIR ".git/objects/e1" +#define FILE_DIR ".git/objects/e3" +#define FILE_DIR ".git/objects/e6" +#define FILE_DIR ".git/objects/ee" +#define FILE_DIR ".git/objects/f2" +#define FILE_DIR ".git/objects/fc" +#define FILE_DIR ".git/objects/fd" +#define FILE_DIR ".git/objects/fe" +#define FILE_DIR ".git/objects/pack" +#define FILE_DIR ".git/refs" +#define FILE_DIR ".git/refs/heads" +#define FILE_DIR ".git/refs/remotes" +#define FILE_DIR ".git/refs/remotes/kevans" +#define FILE_DIR ".git/refs/remotes/origin" +#define FILE_DIR ".git/refs/tags" +#define FILE_DIR "code" +#define FILE_DIR "code/controllers" +#define FILE_DIR "code/controllers/managers" +#define FILE_DIR "code/libraries" +#define FILE_DIR "code/libraries/rc5" +#define FILE_DIR "code/libraries/s_smiley" +#define FILE_DIR "code/libraries/swapmaps" +#define FILE_DIR "code/libraries/syntaxhighlighter" +#define FILE_DIR "code/libraries/test" +#define FILE_DIR "code/libraries/texthandling" +#define FILE_DIR "code/libraries/xml" +#define FILE_DIR "code/libraries/zipfile" +#define FILE_DIR "code/models" +#define FILE_DIR "code/models/chatter" +#define FILE_DIR "code/models/painter" +#define FILE_DIR "code/views" +#define FILE_DIR "code/views/color" +#define FILE_DIR "code/views/games" +#define FILE_DIR "code/views/help" +#define FILE_DIR "code/views/open_chan" +#define FILE_DIR "code/views/ops" +#define FILE_DIR "code/views/paint" +#define FILE_DIR "code/views/set" +#define FILE_DIR "code/views/set/style" +#define FILE_DIR "data" +#define FILE_DIR "data/saves" +#define FILE_DIR "data/saves/channels" +#define FILE_DIR "data/saves/logs" +#define FILE_DIR "data/sndfx" +#define FILE_DIR "data/xml" +#define FILE_DIR "data/xml/help" +#define FILE_DIR "data/xml/help/topics" +#define FILE_DIR "data/xml/help/topics/1" +#define FILE_DIR "data/xml/help/topics/1/1" +#define FILE_DIR "data/xml/help/topics/1/2" +#define FILE_DIR "data/xml/help/topics/4" +#define FILE_DIR "data/xml/help/topics/4/2" +#define FILE_DIR "data/xml/help/topics/4/3" +#define FILE_DIR "data/xml/help/topics/4/3/1" +#define FILE_DIR "data/xml/help/topics/4/3/4" +#define FILE_DIR "data/xml/help/topics/4/8" +#define FILE_DIR "data/xml/help/topics/5" +#define FILE_DIR "data/xml/ops" +#define FILE_DIR "data/xml/ops/privileges" +#define FILE_DIR "data/xml/ops/ranks" +#define FILE_DIR "data/xml/quotes" +#define FILE_DIR "resources" +#define FILE_DIR "resources/icons" +#define FILE_DIR "resources/icons/atoms" +#define FILE_DIR "resources/icons/paint" +#define FILE_DIR "resources/icons/smileys" +#define FILE_DIR "resources/images" +#define FILE_DIR "resources/images/hangman" +#define FILE_DIR "resources/images/interface" +#define FILE_DIR "resources/images/interface/arrows" +#define FILE_DIR "resources/images/interface/locks" +#define FILE_DIR "resources/images/menu" +#define FILE_DIR "resources/images/smileys" +#define FILE_DIR "resources/maps" +#define FILE_DIR "resources/notes" +// END_FILE_DIR +#define FILE_DIR "resources" + +// BEGIN_PREFERENCES +#define DEBUG +// END_PREFERENCES + +// BEGIN_INCLUDE +#include "code\_global.dm" +#include "code\client.dm" +#include "code\world.dm" +#include "code\controllers\console.dm" +#include "code\controllers\managers\botman.dm" +#include "code\controllers\managers\chanman.dm" +#include "code\controllers\managers\chatman.dm" +#include "code\controllers\managers\errman.dm" +#include "code\controllers\managers\eventman.dm" +#include "code\controllers\managers\gameman.dm" +#include "code\controllers\managers\helpman.dm" +#include "code\controllers\managers\listman.dm" +#include "code\controllers\managers\logman.dm" +#include "code\controllers\managers\mapman.dm" +#include "code\controllers\managers\msghand.dm" +#include "code\controllers\managers\msgman.dm" +#include "code\controllers\managers\opman.dm" +#include "code\controllers\managers\paintman.dm" +#include "code\controllers\managers\textman.dm" +#include "code\libraries\rc5\rc5.dm" +#include "code\libraries\s_smiley\alphabetics.dm" +#include "code\libraries\s_smiley\replacetext.dm" +#include "code\libraries\s_smiley\replaceword.dm" +#include "code\libraries\s_smiley\s_smiley.dm" +#include "code\libraries\swapmaps\SwapMaps.dm" +#include "code\libraries\syntaxhighlighter\SyntaxHighlighter.dm" +#include "code\libraries\test\Test.dm" +#include "code\libraries\texthandling\TextHandling.dm" +#include "code\libraries\xml\Element.dm" +#include "code\libraries\xml\Parser.dm" +#include "code\libraries\xml\Prolog.dm" +#include "code\libraries\xml\Tree.dm" +#include "code\libraries\xml\XML.dm" +#include "code\libraries\zipfile\zipfile.dm" +#include "code\models\atoms.dm" +#include "code\models\bot.dm" +#include "code\models\channel.dm" +#include "code\models\icons.dm" +#include "code\models\messenger.dm" +#include "code\models\op.dm" +#include "code\models\player.dm" +#include "code\models\showcode_snippet.dm" +#include "code\models\tempmob.dm" +#include "code\models\chatter\_main.dm" +#include "code\models\chatter\commands.dm" +#include "code\models\chatter\controls.dm" +#include "code\models\chatter\procs.dm" +#include "code\models\painter\_main.dm" +#include "code\models\painter\colorboxes.dm" +#include "code\models\painter\controls.dm" +#include "code\models\painter\procs.dm" +#include "code\models\painter\tools.dm" +#include "code\views\default.dmf" +#include "code\views\color\_main.dm" +#include "code\views\games\_main.dm" +#include "code\views\games\roll_play.dm" +#include "code\views\help\_main.dm" +#include "code\views\open_chan\_main.dm" +#include "code\views\open_chan\index.dm" +#include "code\views\open_chan\load_chan.dm" +#include "code\views\open_chan\new_chan.dm" +#include "code\views\ops\_main.dm" +#include "code\views\ops\general.dm" +#include "code\views\ops\privileges.dm" +#include "code\views\ops\ranks.dm" +#include "code\views\paint\_main.dm" +#include "code\views\paint\canvas.dm" +#include "code\views\paint\pallete.dm" +#include "code\views\paint\window.dm" +#include "code\views\set\_main.dm" +#include "code\views\set\events.dm" +#include "code\views\set\filters.dm" +#include "code\views\set\general.dm" +#include "code\views\set\icons.dm" +#include "code\views\set\security.dm" +#include "code\views\set\style.dm" +#include "code\views\set\system.dm" +#include "code\views\set\style\colors.dm" +#include "code\views\set\style\default.dm" +#include "code\views\set\style\formats.dm" +// END_INCLUDE + + diff --git a/code/_global.dm b/code/_global.dm index bf67a99..2f985c7 100644 --- a/code/_global.dm +++ b/code/_global.dm @@ -1,205 +1,204 @@ - -/* Chatters Channel Server - -* Copyright (c) 2008, Andrew "Xooxer" Arnold -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the Chatters Network nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY Andrew "Xooxer" Arnold ``AS IS'' AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL Andrew "Xooxer" Arnold BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -// Preprocessor Definitions - -// Network Status -#define FAILED 0 -#define CONTACTING 1 -#define VALIDATING 2 -#define CONNECTING 3 -#define CONNECTED 4 - -#define LIKEABOSS 16 - -// Ignore Scopes -#define NO_IGNORE 0 -#define IM_IGNORE 1 -#define CHAT_IGNORE 2 -#define FADE_IGNORE 4 -#define COLOR_IGNORE 8 -#define SMILEY_IGNORE 16 -#define IMAGES_IGNORE 32 -#define FILES_IGNORE 64 -#define FULL_IGNORE 128 - -// File Size Limit -#define MAX_FILE_SIZE 5242880 // 5 Megabytes - -// telnet echo ON -#define VERBOSE 1 - -// Used to enable debugging output with debug() -#define DEV_DEBUG - -// Paint canvas dimensions -#define CANVASX 32 -#define CANVASY 32 - -// Number of Undos allowed to painters -#define UNDONUM 99 - -// Swap two variables -// pass an unused temporary -// variable C so you can swap A and B -#define swapVars(A,B,C) C=(A);A=(B);B=(C) - -#define drawbound(x1,y1,x2,y2,L) \ -do { \ - L += x1; L += y1;\ - L += x2; L += y1;\ - L += x1; L += y2;\ - L += x2; L += y2 \ -} while(0) - -#define fillbound(x1,y1,x2,y2,L,i) \ -do { \ - for(i=y1,i<=y2,i++) { \ - L += x1; L += i;\ - L += x2; L += i \ - } \ -} while(0) - -// Global variables and procedures -var/global - mob/chatter // Current Host of the Channel Server - Host - - ServerConsole // Main controller handles all managers - Console - - Channel // Main server channel - Home - - // Global Managers - BotManager/BotMan - ChannelManager/ChanMan - ChatterManager/ChatMan - ErrorManager/ErrMan - EventManager/EventMan - GameManager/GameMan - HelpManager/HelpMan - ListManager/ListMan - LogManager/LogMan - MapManager/MapMan - MessageManager/MsgMan - NetworkManager/NetMan - OperatorManager/OpMan - PaintManager/PaintMan - TextManager/TextMan - - savefile_version = "0.1.6" // savefile versioning to reduce needless wipes - - - - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** // - // ***** IF YOU FAIL TO UPDATE THIS YOUR SERVER WILL NOT START ***** // - // ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - - - rscHash = "69d0703e66f36405aef2192008066790" // verifies the rsc file - - // Use Chatters Utilities to generate the rscHash after altering - // the rsc file. Paste the generated text here so that your code - // knows the current hash for the updated rsc file. - - // If you modify the rsc (by either altering, creating or removing - // icons, by including, removing or altering sounds, by modifying - // the DMF, by changing the DMMs, or by including any library or - // code that does any of the above, etc) and you fail to update the - // rscHash vairable with the Chatters Utility program, your server - // will not start. Instead you will recieve: - - // Chatter.rsc is out of date! - - // and the server will close. - - - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** // - // ***** IF YOU FAIL TO UPDATE THIS YOUR SERVER WILL NOT START ***** // - // ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - - - - list/debugs // debug messages saved when host is offline - - -proc -// Global Procedure Aliases - debug (text) return Console.debug(text) - islist (list/L) return ListMan.isList(L) - text2list (text) return TextMan.List(text) - list2text (list/L) return ListMan.Text(L) - listOpen (list/L) return ListMan.Open(L) - listAdd () return ListMan.Add(args) - listRemove () return ListMan.Remove(args) - listClose (list/L) return ListMan.Close(L) - invertList (list/L) return ListMan.Invert(L) - stack (list/L, item, list_len) return ListMan.Stack(L, item, list_len) - implode (list/words, separator) return TextMan.Implode(words, separator) - explode (text, separator) return TextMan.Explode(text, separator) - trim (text) return TextMan.Trim(text) - ltrim (text) return TextMan.lTrim(text) - rtrim (text) return TextMan.rTrim(text) - line (x0, y0, x1, y1) return PaintMan.line(x0, y0, x1, y1) - ellipse (x1, y1, x2, y2, fill) return PaintMan.ellipse(x1, y1, x2, y2, fill) - escapeQuotes(txt) return TextMan.escapeQuotes(txt) - - - VerifyResources() // Makes sure the rsc file is up to date - return 1 - if(!fexists("./Chatters.rsc")) - if(!fexists("./Chatters.zip")) - // ErrMan doesn't exist yet, so send to world.log directly - world.log << "\nChatters.rsc not found!" - world.log << "Please include the Chatters.rsc file with the Chatters.dmb." - return - else return "unpakit" - return 1 - var/F = file("./Chatters.rsc") - if(!isfile(F)) - world.log << "\nChatters.rsc is not a valid file!" - world.log << "Please include a valid Chatters.rsc file with the Chatters.dmb." - return - var/md5 = md5(F) - if(md5 != rscHash) - world.log << "\nChatters.rsc is out of date!" - world.log << "Please include the proper Chatters.rsc file with the Chatters.dmb, or use the Chatters Utilities program to generate an updated rscHash, and recompile the DMB file." - return - return 1 - + +/* Chatters Channel Server + +* Copyright (c) 2008, Andrew "Xooxer" Arnold +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the Chatters Network nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY Andrew "Xooxer" Arnold ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL Andrew "Xooxer" Arnold BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +// Preprocessor Definitions + +// Network Status +#define FAILED 0 +#define CONTACTING 1 +#define VALIDATING 2 +#define CONNECTING 3 +#define CONNECTED 4 + +#define LIKEABOSS 16 + +// Ignore Scopes +#define NO_IGNORE 0 +#define IM_IGNORE 1 +#define CHAT_IGNORE 2 +#define FADE_IGNORE 4 +#define COLOR_IGNORE 8 +#define SMILEY_IGNORE 16 +#define IMAGES_IGNORE 32 +#define FILES_IGNORE 64 +#define FULL_IGNORE 128 + +// File Size Limit +#define MAX_FILE_SIZE 5242880 // 5 Megabytes + +// telnet echo ON +#define VERBOSE 1 + +// Used to enable debugging output with debug() +#define DEV_DEBUG + +// Paint canvas dimensions +#define CANVASX 32 +#define CANVASY 32 + +// Number of Undos allowed to painters +#define UNDONUM 99 + +// Swap two variables +// pass an unused temporary +// variable C so you can swap A and B +#define swapVars(A,B,C) C=(A);A=(B);B=(C) + +#define drawbound(x1,y1,x2,y2,L) \ +do { \ + L += x1; L += y1;\ + L += x2; L += y1;\ + L += x1; L += y2;\ + L += x2; L += y2 \ +} while(0) + +#define fillbound(x1,y1,x2,y2,L,i) \ +do { \ + for(i=y1,i<=y2,i++) { \ + L += x1; L += i;\ + L += x2; L += i \ + } \ +} while(0) + +// Global variables and procedures +var/global + mob/chatter // Current Host of the Channel Server + Host + + ServerConsole // Main controller handles all managers + Console + + Channel // Main server channel + Home + + // Global Managers + BotManager/BotMan + ChannelManager/ChanMan + ChatterManager/ChatMan + ErrorManager/ErrMan + EventManager/EventMan + GameManager/GameMan + HelpManager/HelpMan + ListManager/ListMan + LogManager/LogMan + MapManager/MapMan + MessageManager/MsgMan + OperatorManager/OpMan + PaintManager/PaintMan + TextManager/TextMan + + savefile_version = "0.1.6" // savefile versioning to reduce needless wipes + + + + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** // + // ***** IF YOU FAIL TO UPDATE THIS YOUR SERVER WILL NOT START ***** // + // ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + + + rscHash = "69d0703e66f36405aef2192008066790" // verifies the rsc file + + // Use Chatters Utilities to generate the rscHash after altering + // the rsc file. Paste the generated text here so that your code + // knows the current hash for the updated rsc file. + + // If you modify the rsc (by either altering, creating or removing + // icons, by including, removing or altering sounds, by modifying + // the DMF, by changing the DMMs, or by including any library or + // code that does any of the above, etc) and you fail to update the + // rscHash vairable with the Chatters Utility program, your server + // will not start. Instead you will recieve: + + // Chatter.rsc is out of date! + + // and the server will close. + + + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** // + // ***** IF YOU FAIL TO UPDATE THIS YOUR SERVER WILL NOT START ***** // + // ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + + + + list/debugs // debug messages saved when host is offline + + +proc +// Global Procedure Aliases + debug (text) return Console.debug(text) + islist (list/L) return ListMan.isList(L) + text2list (text) return TextMan.List(text) + list2text (list/L) return ListMan.Text(L) + listOpen (list/L) return ListMan.Open(L) + listAdd () return ListMan.Add(args) + listRemove () return ListMan.Remove(args) + listClose (list/L) return ListMan.Close(L) + invertList (list/L) return ListMan.Invert(L) + stack (list/L, item, list_len) return ListMan.Stack(L, item, list_len) + implode (list/words, separator) return TextMan.Implode(words, separator) + explode (text, separator) return TextMan.Explode(text, separator) + trim (text) return TextMan.Trim(text) + ltrim (text) return TextMan.lTrim(text) + rtrim (text) return TextMan.rTrim(text) + line (x0, y0, x1, y1) return PaintMan.line(x0, y0, x1, y1) + ellipse (x1, y1, x2, y2, fill) return PaintMan.ellipse(x1, y1, x2, y2, fill) + escapeQuotes(txt) return TextMan.escapeQuotes(txt) + + + VerifyResources() // Makes sure the rsc file is up to date + return 1 + if(!fexists("./Chatters.rsc")) + if(!fexists("./Chatters.zip")) + // ErrMan doesn't exist yet, so send to world.log directly + world.log << "\nChatters.rsc not found!" + world.log << "Please include the Chatters.rsc file with the Chatters.dmb." + return + else return "unpakit" + return 1 + var/F = file("./Chatters.rsc") + if(!isfile(F)) + world.log << "\nChatters.rsc is not a valid file!" + world.log << "Please include a valid Chatters.rsc file with the Chatters.dmb." + return + var/md5 = md5(F) + if(md5 != rscHash) + world.log << "\nChatters.rsc is out of date!" + world.log << "Please include the proper Chatters.rsc file with the Chatters.dmb, or use the Chatters Utilities program to generate an updated rscHash, and recompile the DMB file." + return + return 1 + diff --git a/code/controllers/console.dm b/code/controllers/console.dm index 691a1bf..0bd441f 100644 --- a/code/controllers/console.dm +++ b/code/controllers/console.dm @@ -1,144 +1,140 @@ - -ServerConsole // main controller - New() - ..() - // start the server managers - ListMan = new() - TextMan = new() - BotMan = new() - OpMan = new() - ChanMan = new() - ChatMan = new() - ErrMan = new() - EventMan = new() - GameMan = new() - HelpMan = new() - LogMan = new() - MapMan = new() - MsgMan = new() - NetMan = new() - PaintMan = new() - - Del() - del(BotMan) - del(OpMan) - del(ChanMan) - del(ChatMan) - del(ErrMan) - del(EventMan) - del(HelpMan) - del(LogMan) - del(MapMan) - del(MsgMan) - del(NetMan) - del(PaintMan) - del(TextMan) - del(ListMan) - ..() - - Topic(href, href_list[]) - if(!href_list) href_list = params2list(href) - ..() - switch(href_list["dest"]) - if("chanman") - ChanMan.Topic(href, href_list) - if("chatman") - ChatMan.Topic(href, href_list) - if("helpman") - HelpMan.Topic(href, href_list) - if("msgman") - MsgMan.Topic(href, href_list) - if("netman") - NetMan.Topic(href, href_list) - - - proc - Show() - winshow(Host, "console", 1) - winset(Host, "console.input", "focus=true;") - - Hide() - winshow(Host, "console", 0) - - debug(T) - #ifdef DEV_DEBUG - if(!T) return - var/online - for(var/mob/M in world) - if((M.ckey in ChanMan.devs) && M.client) - if(!online) online = TRUE - M << output("[T]", "console.output") - winshow(M, "console", 1) - if(!online) - debugs = debugs || new() - debugs += T - #endif - - LoadCFG(cfg) - if(!cfg || !fexists(cfg)) return - - var/list/config=new(),list/lines=new(),head - var/txt,l,line,fchar,cbracket,phead,sep,comm,param,value - - txt = file2text(cfg) - if(!txt || !length(txt)) return - - lines = explode(txt, "\n") - if(!lines || !lines.len) return - - config += "main" - - for(l in lines) - line = trim(l) - if(!line) continue - - fchar = copytext(line, 1, 2) - - switch(fchar) - if(";") continue - - if("#") continue - - if("\[") - cbracket = findtext(line, "]") - if(!cbracket) continue - - if(head) - phead = config[config.len] - config[phead] = head - config += lowertext(copytext(line, 2, cbracket)) - head = null - continue - - else if(config.len==1) - config = new() - config += lowertext(copytext(line, 2, cbracket)) - continue - - else - phead = config[config.len] - config -= phead - config += lowertext(copytext(line, 2, cbracket)) - - else - sep = findtext(line, "=") - if(!sep) sep = findtext(line, ":") - if(!sep) continue - - comm = findtext(line, ";") - if(!comm) comm = findtext(line, "#") - if(comm && (comm < sep)) continue - if(sep == length(line)) continue - - param = lowertext(trim(copytext(line, 1, sep))) - value = trim(copytext(line, sep+1, comm)) - - if(head) head += "&"+param - else head = param - head += "="+value - - if(head) - phead = config[config.len] - config[phead] = head - - return config + +ServerConsole // main controller + New() + ..() + // start the server managers + ListMan = new() + TextMan = new() + BotMan = new() + OpMan = new() + ChanMan = new(src) + ChatMan = new() + ErrMan = new() + EventMan = new() + GameMan = new() + HelpMan = new() + LogMan = new() + MapMan = new() + MsgMan = new() + PaintMan = new() + + Del() + del(BotMan) + del(OpMan) + del(ChanMan) + del(ChatMan) + del(ErrMan) + del(EventMan) + del(HelpMan) + del(LogMan) + del(MapMan) + del(MsgMan) + del(PaintMan) + del(TextMan) + del(ListMan) + ..() + + Topic(href, href_list[]) + if(!href_list) href_list = params2list(href) + ..() + switch(href_list["dest"]) + if("chanman") + ChanMan.Topic(href, href_list) + if("chatman") + ChatMan.Topic(href, href_list) + if("helpman") + HelpMan.Topic(href, href_list) + if("msgman") + MsgMan.Topic(href, href_list) + + + proc + Show() + winshow(Host, "console", 1) + winset(Host, "console.input", "focus=true;") + + Hide() + winshow(Host, "console", 0) + + debug(T) + #ifdef DEV_DEBUG + if(!T) return + var/online + for(var/mob/M in world) + if((M.ckey in ChanMan.devs) && M.client) + if(!online) online = TRUE + M << output("[T]", "console.output") + winshow(M, "console", 1) + if(!online) + debugs = debugs || new() + debugs += T + #endif + + LoadCFG(cfg) + if(!cfg || !fexists(cfg)) return + + var/list/config=new(),list/lines=new(),head + var/txt,l,line,fchar,cbracket,phead,sep,comm,param,value + + txt = file2text(cfg) + if(!txt || !length(txt)) return + + lines = explode(txt, "\n") + if(!lines || !lines.len) return + + config += "main" + + for(l in lines) + line = trim(l) + if(!line) continue + + fchar = copytext(line, 1, 2) + + switch(fchar) + if(";") continue + + if("#") continue + + if("\[") + cbracket = findtext(line, "]") + if(!cbracket) continue + + if(head) + phead = config[config.len] + config[phead] = head + config += lowertext(copytext(line, 2, cbracket)) + head = null + continue + + else if(config.len==1) + config = new() + config += lowertext(copytext(line, 2, cbracket)) + continue + + else + phead = config[config.len] + config -= phead + config += lowertext(copytext(line, 2, cbracket)) + + else + sep = findtext(line, "=") + if(!sep) sep = findtext(line, ":") + if(!sep) continue + + comm = findtext(line, ";") + if(!comm) comm = findtext(line, "#") + if(comm && (comm < sep)) continue + if(sep == length(line)) continue + + param = lowertext(trim(copytext(line, 1, sep))) + value = trim(copytext(line, sep+1, comm)) + + if(head) head += "&"+param + else head = param + head += "="+value + + if(head) + phead = config[config.len] + config[phead] = head + + return config diff --git a/code/controllers/managers/chanman.dm b/code/controllers/managers/chanman.dm index fbbbc7c..9608b8d 100644 --- a/code/controllers/managers/chanman.dm +++ b/code/controllers/managers/chanman.dm @@ -1,345 +1,259 @@ - -ChannelManager - var/host - var/telnet_pass - var/telnet_attempts - var/NameResult=1 - var/list/devs - - New() - ..() - spawn() - LoadServerCfg() - - Del() - if(Home) SaveChan(Home) - ..() - - Topic(href, href_list[]) - ..() - switch(href_list["action"]) - if("namecheck") - if(NetMan.Status != CONNECTED) - alert(Host, "You are not currently connected to the Chatters network. You may create a private channel, but you may need to change its name if you wish go connect publicly to the network.", "Unable to Check Name") - return - var/result = isTaken(href_list["Name"]) - if(result) alert(Host, "[href_list["Name"]] is already in use.", "Name Taken") - else alert(Host, "[href_list["Name"]] is free!", "Name Available") - if("newchan") - NewChan(href_list) - if("loadchan") - Home = LoadChan(href_list["chan"]) - Home.chanbot = BotMan.LoadBot(Home) - ProcessChan() - if("delchan") - switch(alert("Are you sure you want to delete [href_list["chan"]]?", "Confirm Delete", "Yes", "No")) - if("Yes") DelChan(href_list["chan"]) - var/OpenChannel/OC = new() - OC.Display("load_chan") - del(OC) - if("connected") - NetMan.Status = CONNECTED - if(Host && Host.client) - winset(Host, "main_menu.info_top", "text='Channel successfully published to the network.'") - sleep(30) - winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") - Host << output("Hosting [Home.name]", "main_menu_output.output") - NetMan.Query("getchans") - NetMan.Query("getchatters") - if("checkedname") - var/result = href_list["result"] - if(NameResult) - world.visibility = 0 - NetMan.Status = FAILED - if(Host && Host.client) - spawn() alert(Host, "The name you chose for your channel is already in use. Plaese choose a different name before reconnecting to the network.","Network Disconnected") - - else - if(result == "true") NameResult = TRUE - else NameResult = FALSE - - proc - NewChan(list/params) - var/Channel/Chan = new(params) - Home = Chan - ProcessChan() - - DelChan(chan) - fdel("./data/saves/channels/[chan].sav") - - isTaken(Name) - var/timeout = 300 - NameResult = null - world.Export("[NetMan.addr]:[NetMan.port]?dest=chanman&action=checkname&name=[Name]") - while(isnull(NameResult) && timeout--) sleep(1) - return NameResult - - Join(mob/chatter/C, Channel/Chan) - Chan.Join(C) - - Quit(mob/chatter/C, Channel/Chan) - Chan.Quit(C) - - Say(mob/chatter/C, msg) - C.Chan.Say(C, msg) - - ProcessChan() - Home.LoadOps() - SaveChan(Home) - BotMan.SaveBot(Home.chanbot) - if(Host && Host.client) - call(Host,"Join")(Home) - winshow(Host, "open_chan", 0) - winset(Host, "main_menu.info_top", "text='Publishing channel to the network...'") - world.status = "[Home.name] founded by [Home.founder] - [(Home.chatters ? Home.chatters.len : 0)] chatter\s" - if(Home.publicity != "public") world.visibility = 0 - var/savefile/F = new("packet") - F["founder"] << Home.founder - F["name"] << Home.name - F["desc"] << Home.desc - F["topic"] << Home.topic - F["password"] << Home.pass - F["locked"] << Home.locked - F["chatters"] << (Home.chatters ? Home.chatters.len : 0) - F["supernode"] << Home.SuperNode - F["maxnodes"] << Home.MaxNodes - NetMan.Status = CONNECTING - var/retries = NetMan.retry - spawn(20) - do - world.Export("[NetMan.addr]:[NetMan.port]?dest=chanman&action=connect",F) - sleep(NetMan.timeout) - if(NetMan.Status == CONNECTING) - if(Host && Host.client) winset(Host, "main_menu.info_top", "text='Connection timed out.'") - sleep(20) - if(!--retries) break - if(NetMan.Status == CONNECTING) - if(Host && Host.client) winset(Host, "main_menu.info_top", "text='Publishing channel to the network...'") - while(NetMan.Status == CONNECTING) - if(NetMan.Status == CONNECTING || NetMan.Status == FAILED) - NetMan.Status = FAILED - if(Host && Host.client) - winset(Host, "main_menu.info_top", "text='Problem contacting network!'") - winset(Host, "main_menu.cim", "is-disabled=true;") - winset(Host, "main_menu.public_chans", "is-disabled=true;") - winset(Host, "main_menu.cmail", "is-disabled=true;") - winset(Host, "main_menu.info_bottom", "text=") - fdel("packet") - - - SaveChan(Channel/Chan) - var/savefile/S = new("./data/saves/channels/[ckey(Chan.name)].sav") - S["founder"] << Chan.founder - S["name"] << Chan.name - S["publicity"] << Chan.publicity - S["desc"] << Chan.desc - S["room_desc"] << Chan.room_desc - S["room_desc_size"] << Chan.room_desc_size - S["topic"] << Chan.topic - S["pass"] << Chan.pass - S["locked"] << Chan.locked - S["telpass"] << Chan.telnet_pass - S["telatmpts"] << Chan.telnet_attempts - S["mute"] << Chan.mute - S["banned"] << Chan.banned - if(Chan.operators && Chan.operators.len) - var/list/ops = new() - for(var/cKey in Chan.operators) - var/Op/O = Chan.operators[cKey] - ops += O.name - ops[O.name] = O.Rank.pos - S["operators"] << ops - - LoadChan(chan, telpass, telatmpts) - var/savefile/S = new("./data/saves/channels/[ckey(chan)].sav") - var/Channel/Chan = new() - S["founder"] >> Chan.founder - S["name"] >> Chan.name - S["publicity"] >> Chan.publicity - S["desc"] >> Chan.desc - S["room_desc"] >> Chan.room_desc - S["room_desc_size"] >> Chan.room_desc_size - S["topic"] >> Chan.topic - S["pass"] >> Chan.pass - S["locked"] >> Chan.locked - Chan.telnet_pass = telnet_pass - Chan.telnet_attempts = telnet_attempts - if(!Chan.telnet_pass && telpass) Chan.telnet_pass = telpass - if(!Chan.telnet_attempts && telatmpts) Chan.telnet_attempts = telatmpts - S["mute"] >> Chan.mute - S["banned"] >> Chan.banned - return Chan - - LoadServerCfg() - var/list/config = Console.LoadCFG("./data/saves/server.cfg") - if(!config || !config.len) return - - var/list/H = params2list(config["main"]) - if(!H || !H.len) return - host = ckey(H["host"]) - NetMan.Port = text2num(H["port"]) - - var/list/D = params2list(config["devs"]) - if(D && D.len) - - if(!devs) devs = new - for(var/d in D) devs += ckey(D[d]) - - var/list/muteList = params2list(config["mute"]) - var/list/banList = params2list(config["bans"]) - var/list/opList = params2list(config["ops"]) - - var/list/S = params2list(config["server"]) - if(S && S.len) - - telnet_pass = S["telnet_pass"] - telnet_attempts = (text2num(S["telnet_attempts"]) || -1) - - var/AutoStart = text2num(S["auto_start"]) ? 1 : 0 - if(AutoStart) - var/HomeChan = S["home_chan"] - if(!HomeChan) - return - else if(!fexists("./data/saves/channels/[ckey(HomeChan)].sav")) - var/Password = S["password"] - var/Founder = S["founder"] - var/ChanDesc = S["desc"] - var/ChanTopic = S["topic"] - var/SuperNode = text2num(S["super_name"]) ? 1 : 0 - var/MaxNodes = text2num(S["max_nodes"]) - var/Publicity = S["publicity"] - var/Locked = S["locked"] - - var/botName = S["bot_name"] - var/botNameColor = S["bot_name_color"] - var/botTextColor = S["bot_text_color"] - - var/botSpamControls= text2num(S["bot_spam_control"]) ? 1 : 0 - var/botSpamLimit = text2num(S["bot_spam_limit"]) - var/botFloodLimit = text2num(S["bot_flood_limit"]) - var/botSmileysLimit= text2num(S["bot_smileys_limit"]) - var/botMaxMsgs = text2num(S["bot_max_msgs"]) - var/botMinDelay = text2num(S["bot_min_delay"]) - - Home = new(list( - "Founder"=Founder, - "Name"=HomeChan, - "Publicity"=Publicity, - "Desc"=ChanDesc, - "Topic"=ChanTopic, - "Pass"=Password, - "Locked"=Locked, - "TelPass"=telnet_pass, - "TelAtmpts"=telnet_attempts, - "SuperNode"=SuperNode, - "MaxNodes"=MaxNodes)) - if(Publicity != "public") world.visibility = 0 - - Home.chanbot.SetName(botName) - Home.chanbot.SetNameColor("#"+botNameColor) - Home.chanbot.SetTextColor("#"+botTextColor) - Home.chanbot.SetSpamControl(botSpamControls) - Home.chanbot.SetSpamLimit(botSpamLimit) - Home.chanbot.SetFloodLimit(botFloodLimit) - Home.chanbot.SetSmileysLimit(botSmileysLimit) - Home.chanbot.SetMaxMsgs(botMaxMsgs) - Home.chanbot.SetMinDelay(botMinDelay) - - if(muteList && muteList.len) - Home.mute = new - for(var/i in muteList) - Home.mute += ckey(i) - - if(banList && banList.len) - Home.banned = new - for(var/i in banList) - Home.banned += ckey(i) - - if(opList && opList.len) - Home.operators = new - for(var/Name in opList) - if(!findtext(Name, "_")) - var/opKey = ckey(opList[Name]) - var/rankIndex = text2num(opList["[Name]_level"]) -/* var/rankPrivs = opList[Name + "_privs"] // Not sure what to do with this. - if(rankPrivs != "default") - // Do something -*/ - var/OpRank/Rank = Home.op_ranks[rankIndex] - Home.operators[opKey] = new/Op(opList[Name], Rank) - - if(NetMan.Status != FAILED) spawn() - NetMan.Status = CONTACTING - var/retries = NetMan.retry - sleep(10) - do - world.Export("[NetMan.addr]:[NetMan.port]?dest=netman&action=newserver") - sleep(NetMan.timeout) - if(NetMan.Status == CONTACTING) if(!--retries) break - while(NetMan.Status == CONTACTING) - if(NetMan.Status == CONTACTING) - NetMan.Status = FAILED - return -/* - var/a_pos = findtext(world.address, ".", 1) - var/b_pos = findtext(world.address, ".", a_pos+1) - var/c_pos = findtext(world.address, ".", b_pos+1) - var/a = num2hex(text2num(copytext(world.address, 1, a_pos))) + ascii2text(rand(103,122)) - var/b = num2hex(text2num(copytext(world.address, a_pos+1, b_pos))) + ascii2text(rand(103,122)) - var/c = num2hex(text2num(copytext(world.address, b_pos+1, c_pos))) + ascii2text(rand(103,122)) - var/d = num2hex(text2num(copytext(world.address, c_pos+1))) + ascii2text(rand(103,122)) - var/e = num2hex(world.port) - - world.status = "[lowertext(a+b+c+d+e)]
[Home.name] founded by [Home.founder]" -*/ - var/savefile/F = new() - F["founder"] << Home.founder - F["name"] << Home.name - F["desc"] << Home.desc - F["topic"] << Home.topic - F["password"] << Home.pass - F["locked"] << Home.locked - F["supernode"] << Home.SuperNode - F["maxnodes"] << Home.MaxNodes - if(Home.chatters) - F["chatters"] << Home.chatters.len - else - F["chatters"] << 0 - NetMan.Status = CONNECTING - sleep(20) - do - world.Export("[NetMan.addr]:[NetMan.port]?dest=chanman&action=connect",F) - sleep(NetMan.timeout) - if(NetMan.Status == CONNECTING) if(!--retries) break - while(NetMan.Status == CONNECTING) - if(NetMan.Status == CONNECTING) NetMan.Status = FAILED - else - Home = LoadChan(HomeChan, telnet_pass, telnet_attempts) - Home.chanbot = BotMan.LoadBot(Home) - Home.LoadOps() - if(muteList && muteList.len) - Home.mute = listOpen(Home.mute) - for(var/i in muteList) - var/cval = ckey(i) - if(!(cval in Home.mute)) Home.mute += cval - - if(banList && banList.len) - Home.banned = listOpen(Home.banned) - for(var/i in banList) - var/cval = ckey(i) - if(!(cval in Home.banned)) Home.banned += cval - - if(opList && opList.len) - Home.operators = listOpen(Home.operators) - for(var/Name in opList) - if(!findtext(Name, "_")) - var/opKey = ckey(opList[Name]) - var/rankIndex = text2num(opList["[Name]_level"]) -/* var/rankPrivs = opList[Name + "_privs"] // Not sure what to do with this. - if(rankPrivs != "default") - // Do something -*/ - var/OpRank/Rank = Home.op_ranks[rankIndex] - Home.operators[opKey] = new/Op(opList[Name], Rank) - // TODO: Remove this once the Chatters Network is properly implemented. - world.OpenPort(NetMan.Port) \ No newline at end of file + +ChannelManager + var/host + var/port + var/telnet_pass + var/telnet_attempts + var/NameResult=1 + var/list/devs + + New(var/ServerConsole/console) + ..() + LoadServerCfg(console) + + Del() + if(Home) SaveChan(Home) + ..() + + Topic(href, href_list[]) + ..() + switch(href_list["action"]) + if("newchan") + NewChan(href_list) + if("loadchan") + Home = LoadChan(href_list["chan"]) + Home.chanbot = BotMan.LoadBot(Home) + ProcessChan() + if("delchan") + switch(alert("Are you sure you want to delete [href_list["chan"]]?", "Confirm Delete", "Yes", "No")) + if("Yes") DelChan(href_list["chan"]) + var/OpenChannel/OC = new() + OC.Display("load_chan") + del(OC) + + proc + NewChan(list/params) + var/Channel/Chan = new(params) + Home = Chan + ProcessChan() + + DelChan(chan) + fdel("./data/saves/channels/[chan].sav") + + isTaken(Name) + return 0 + + Join(mob/chatter/C, Channel/Chan) + Chan.Join(C) + + Quit(mob/chatter/C, Channel/Chan) + Chan.Quit(C) + + Say(mob/chatter/C, msg) + C.Chan.Say(C, msg) + + ProcessChan() + Home.LoadOps() + SaveChan(Home) + BotMan.SaveBot(Home.chanbot) + if(Host && Host.client) + call(Host,"Join")(Home) + winshow(Host, "open_chan", 0) + winset(Host, "main_menu.info_top", "text='Publishing channel to the network...'") + world.status = "[Home.name] founded by [Home.founder] - [(Home.chatters ? Home.chatters.len : 0)] chatter\s" + if(Home.publicity != "public") world.visibility = 0 + var/savefile/F = new("packet") + F["founder"] << Home.founder + F["name"] << Home.name + F["desc"] << Home.desc + F["topic"] << Home.topic + F["password"] << Home.pass + F["locked"] << Home.locked + F["chatters"] << (Home.chatters ? Home.chatters.len : 0) + F["supernode"] << Home.SuperNode + F["maxnodes"] << Home.MaxNodes + + SaveChan(Channel/Chan) + var/savefile/S = new("./data/saves/channels/[ckey(Chan.name)].sav") + S["founder"] << Chan.founder + S["name"] << Chan.name + S["publicity"] << Chan.publicity + S["desc"] << Chan.desc + S["room_desc"] << Chan.room_desc + S["room_desc_size"] << Chan.room_desc_size + S["topic"] << Chan.topic + S["pass"] << Chan.pass + S["locked"] << Chan.locked + S["telpass"] << Chan.telnet_pass + S["telatmpts"] << Chan.telnet_attempts + S["mute"] << Chan.mute + S["banned"] << Chan.banned + if(Chan.operators && Chan.operators.len) + var/list/ops = new() + for(var/cKey in Chan.operators) + var/Op/O = Chan.operators[cKey] + ops += O.name + ops[O.name] = O.Rank.pos + S["operators"] << ops + + LoadChan(chan, telpass, telatmpts) + var/savefile/S = new("./data/saves/channels/[ckey(chan)].sav") + var/Channel/Chan = new() + S["founder"] >> Chan.founder + S["name"] >> Chan.name + S["publicity"] >> Chan.publicity + S["desc"] >> Chan.desc + S["room_desc"] >> Chan.room_desc + S["room_desc_size"] >> Chan.room_desc_size + S["topic"] >> Chan.topic + S["pass"] >> Chan.pass + S["locked"] >> Chan.locked + Chan.telnet_pass = telnet_pass + Chan.telnet_attempts = telnet_attempts + if(!Chan.telnet_pass && telpass) Chan.telnet_pass = telpass + if(!Chan.telnet_attempts && telatmpts) Chan.telnet_attempts = telatmpts + S["mute"] >> Chan.mute + S["banned"] >> Chan.banned + return Chan + + LoadServerCfg(var/ServerConsole/console) + var/list/config = console.LoadCFG("./data/saves/server.cfg") + if(!config || !config.len) return + + var/list/H = params2list(config["main"]) + if(!H || !H.len) return + host = ckey(H["host"]) + port = text2num(H["port"]) + + var/list/D = params2list(config["devs"]) + if(D && D.len) + + if(!devs) devs = new + for(var/d in D) devs += ckey(D[d]) + + var/list/muteList = params2list(config["mute"]) + var/list/banList = params2list(config["bans"]) + var/list/opList = params2list(config["ops"]) + + var/list/S = params2list(config["server"]) + if(S && S.len) + + telnet_pass = S["telnet_pass"] + telnet_attempts = (text2num(S["telnet_attempts"]) || -1) + + var/AutoStart = text2num(S["auto_start"]) ? 1 : 0 + if(AutoStart) + var/HomeChan = S["home_chan"] + if(!HomeChan) + return + else if(!fexists("./data/saves/channels/[ckey(HomeChan)].sav")) + var/Password = S["password"] + var/Founder = S["founder"] + var/ChanDesc = S["desc"] + var/ChanTopic = S["topic"] + var/SuperNode = text2num(S["super_name"]) ? 1 : 0 + var/MaxNodes = text2num(S["max_nodes"]) + var/Publicity = S["publicity"] + var/Locked = S["locked"] + + var/botName = S["bot_name"] + var/botNameColor = S["bot_name_color"] + var/botTextColor = S["bot_text_color"] + + var/botSpamControls= text2num(S["bot_spam_control"]) ? 1 : 0 + var/botSpamLimit = text2num(S["bot_spam_limit"]) + var/botFloodLimit = text2num(S["bot_flood_limit"]) + var/botSmileysLimit= text2num(S["bot_smileys_limit"]) + var/botMaxMsgs = text2num(S["bot_max_msgs"]) + var/botMinDelay = text2num(S["bot_min_delay"]) + + Home = new(list( + "Founder"=Founder, + "Name"=HomeChan, + "Publicity"=Publicity, + "Desc"=ChanDesc, + "Topic"=ChanTopic, + "Pass"=Password, + "Locked"=Locked, + "TelPass"=telnet_pass, + "TelAtmpts"=telnet_attempts, + "SuperNode"=SuperNode, + "MaxNodes"=MaxNodes)) + if(Publicity != "public") world.visibility = 0 + + Home.chanbot.SetName(botName) + Home.chanbot.SetNameColor("#"+botNameColor) + Home.chanbot.SetTextColor("#"+botTextColor) + Home.chanbot.SetSpamControl(botSpamControls) + Home.chanbot.SetSpamLimit(botSpamLimit) + Home.chanbot.SetFloodLimit(botFloodLimit) + Home.chanbot.SetSmileysLimit(botSmileysLimit) + Home.chanbot.SetMaxMsgs(botMaxMsgs) + Home.chanbot.SetMinDelay(botMinDelay) + + if(muteList && muteList.len) + Home.mute = new + for(var/i in muteList) + Home.mute += ckey(i) + + if(banList && banList.len) + Home.banned = new + for(var/i in banList) + Home.banned += ckey(i) + + if(opList && opList.len) + Home.operators = new + for(var/Name in opList) + if(!findtext(Name, "_")) + var/opKey = ckey(opList[Name]) + var/rankIndex = text2num(opList["[Name]_level"]) +/* var/rankPrivs = opList[Name + "_privs"] // Not sure what to do with this. + if(rankPrivs != "default") + // Do something +*/ + var/OpRank/Rank = Home.op_ranks[rankIndex] + Home.operators[opKey] = new/Op(opList[Name], Rank) + + var/savefile/F = new() + F["founder"] << Home.founder + F["name"] << Home.name + F["desc"] << Home.desc + F["topic"] << Home.topic + F["password"] << Home.pass + F["locked"] << Home.locked + F["supernode"] << Home.SuperNode + F["maxnodes"] << Home.MaxNodes + if(Home.chatters) + F["chatters"] << Home.chatters.len + else + F["chatters"] << 0 + else + Home = LoadChan(HomeChan, telnet_pass, telnet_attempts) + Home.chanbot = BotMan.LoadBot(Home) + Home.LoadOps() + if(muteList && muteList.len) + Home.mute = listOpen(Home.mute) + for(var/i in muteList) + var/cval = ckey(i) + if(!(cval in Home.mute)) Home.mute += cval + + if(banList && banList.len) + Home.banned = listOpen(Home.banned) + for(var/i in banList) + var/cval = ckey(i) + if(!(cval in Home.banned)) Home.banned += cval + +/* if(opList && opList.len) + Home.operators = listOpen(Home.operators) + for(var/Name in opList) + if(!findtext(Name, "_")) + var/opKey = ckey(opList[Name]) + var/rankIndex = text2num(opList["[Name]_level"]) + var/rankPrivs = opList[Name + "_privs"] // Not sure what to do with this. + if(rankPrivs != "default") + // Do something +*/ + var/OpRank/Rank = Home.op_ranks[rankIndex] + Home.operators[opKey] = new/Op(opList[Name], Rank) + // TODO: Remove this once the Chatters Network is properly implemented. + world.OpenPort(port) \ No newline at end of file diff --git a/code/controllers/managers/chatman.dm b/code/controllers/managers/chatman.dm index e075777..13a92a5 100644 --- a/code/controllers/managers/chatman.dm +++ b/code/controllers/managers/chatman.dm @@ -1,195 +1,168 @@ - -ChatterManager - - var - tmp/list/Dummies - - Topic(href, href_list) - ..() - switch(href_list["action"]) - if("showcode") - var/mob/chatter/Target = locate(href_list["target"]) - var/showcode_snippet/snippet = Home.showcodes[text2num(href_list["index"])] - if (snippet.target && snippet.target != usr.ckey && usr.ckey != Target.ckey) - // This is a private message they are not allowed to view. - return - else - usr << browse(snippet.ReturnHtml(Target, 1), "window=showcode_[snippet.id];display=1;size=800x500;border=1;can_close=1;can_resize=1;titlebar=1") - if("showtext") - var/mob/chatter/Target = locate(href_list["target"]) - var/showcode_snippet/snippet = Home.showcodes[text2num(href_list["index"])] - if (snippet.target && snippet.target != usr.ckey && usr.ckey != Target.ckey) - // This is a private message they are not allowed to view. - return - else - usr << browse(snippet.ReturnHtml(Target), "window=showtext_[snippet.id];display=1;size=800x500;border=1;can_close=1;can_resize=1;titlebar=1") - - proc - Usher(mob/Temp/T) - if(!T || !T.client) - del T - return - - var/mob/chatter/C = new() - - // Do not call client.Import on telnet users - if(!istelnet(T.key)) - var/client_file - client_file = T.client.Import() - if(client_file == "-1.sav") client_file = null - if(client_file) - if(!Load(C, client_file)) - // Out of date or bad savefile, discard. - T.client.Export() - C.name = T.name - C.key = T.key - else - C.name = T.name - C.key = T.key - var/SetView/SV = new(); SV.Initialize(C); del(SV) - var/HelpView/HV = new(); HV.Initialize(C); del(SV) - var/GamesView/GV = new(); GV.Initialize(C); del(SV) - else - C.name = T.name - C.key = T.key - - del(T) - - - // Tests if the key is a telnet key eg: Telnet @127.000.000.001 - istelnet(key) - if(findtext(key, "Telnet @") == 1) - return 1 - - - Get(chatter, local) - if(!length(chatter)) return - if(!Home || !Home.chatters && NetMan.Status != CONNECTED) return - - if(Home && Home.chatters) - var first_char = text2ascii(copytext(chatter, 1, 2)) - // If search starts with a number, search IPs. - if(first_char > 47 && first_char < 58) - // Exact IP first - for(var/mob/chatter/C in Home.chatters) - if(C.client.address == chatter) - return C - - // Partial IP second - for(var/mob/chatter/C in Home.chatters) - if(TextMan.Match(C.client.address, chatter)) - return C - - else - // Exact key search. - for(var/mob/chatter/C in Home.chatters) - if(ckey(C.name) == ckey(chatter)) return C - - // Partial case-sensitive key search - for(var/mob/chatter/C in Home.chatters) - if(TextMan.Match(C.key, chatter)) return C - - // Partial non-case-sensitive key search - for(var/mob/chatter/C in Home.chatters) - if(TextMan.Match(C.ckey, chatter)) return C - - if(!local && NetMan.Status == CONNECTED) - if(!NetMan || !NetMan.Chatters || !NetMan.Chatters.len) - return - // Exact key search. - for(var/mob/chatter/C in world) - if(ckey(C.name) == ckey(chatter)) return C - - // Partial case-sensitive key search - for(var/mob/chatter/C in world) - if(TextMan.Match(C.key, chatter)) return C - - // Partial non-case-sensitive key search - for(var/mob/chatter/C in world) - if(TextMan.Match(C.ckey, chatter)) return C - // Exact key search. - for(var/C in NetMan.Chatters) - if(ckey(C) == ckey(chatter)) return C - - // Partial case-sensitive key search - for(var/C in NetMan.Chatters) - if(TextMan.Match(C, chatter)) return C - - // Partial non-case-sensitive key search - for(var/C in NetMan.Chatters) - if(TextMan.Match(ckey(C), chatter)) return C - - - Rank(chatter) - if(Home && chatter) - var/cKey = ckey(chatter) - if(cKey in Home.operators) - var/Op/O = Home.operators[cKey] - return O.Rank - return "All" - - - ParseFormat(format, variables[], required[]) - if(!format || !variables || !variables.len) return FALSE - if(required) - for(var/r in required) - if(!findtext(format, r)) return FALSE - var/list/L = new() - var/temp = format - for(var/v in variables) - var/pos = findtext(format, v) - if(pos) variables[v] = pos - else variables -= v - for(var/v = variables.len, v >= 1, v--) - for(var/i = 1, i < v, i++) - if(variables[variables[i]] > variables[variables[i+1]]) - variables.Swap( i, i+1) - else if(variables[variables[i]] == variables[variables[i+1]]) - variables -= variables[i+1] - if(v > variables.len) break - for(var/v in variables) - var/pos = findtext(temp, v) - if(pos > 1) - L += copytext(temp, 1, pos) - L += v - temp = copytext(temp, pos+length(v)) - if(length(temp)) - L += temp - return L - - Load(mob/chatter/C, client_file) - var/savefile/F = new(client_file) - var/version - F["version"] >> version - - if(version == "0.1.5" && ("CRYPTO" in F.dir)) - var/crypto - F["CRYPTO"] >> crypto - crypto = RC5_Decrypt(crypto, md5(world.hub_password)) - for(var/i = 1; i <= length(crypto); ++i) - if(text2ascii(crypto, i) < 32) return FALSE - F.dir -= "CRYPTO" - F.ImportText("/", crypto) - C.Read(F) - // Save an updated savefile. - Save(C) - return TRUE - else if(version == savefile_version) - C.Read(F) - return TRUE - else - return FALSE - - Save(mob/chatter/C) - var/savefile/S = new() - C.Write(S) - S["version"] << savefile_version - sleep(5) - C.client.Export(S) - - - EditSave(var/save) - if(!save) return - var/savefile/F = new(save) - var/text = F.ExportText("/") - return text + +ChatterManager + + var + tmp/list/Dummies + + Topic(href, href_list) + ..() + switch(href_list["action"]) + if("showcode") + var/mob/chatter/Target = locate(href_list["target"]) + var/showcode_snippet/snippet = Home.showcodes[text2num(href_list["index"])] + if (snippet.target && snippet.target != usr.ckey && usr.ckey != Target.ckey) + // This is a private message they are not allowed to view. + return + else + usr << browse(snippet.ReturnHtml(Target, 1), "window=showcode_[snippet.id];display=1;size=800x500;border=1;can_close=1;can_resize=1;titlebar=1") + if("showtext") + var/mob/chatter/Target = locate(href_list["target"]) + var/showcode_snippet/snippet = Home.showcodes[text2num(href_list["index"])] + if (snippet.target && snippet.target != usr.ckey && usr.ckey != Target.ckey) + // This is a private message they are not allowed to view. + return + else + usr << browse(snippet.ReturnHtml(Target), "window=showtext_[snippet.id];display=1;size=800x500;border=1;can_close=1;can_resize=1;titlebar=1") + + proc + Usher(mob/Temp/T) + if(!T || !T.client) + del T + return + + var/mob/chatter/C = new() + + // Do not call client.Import on telnet users + if(!istelnet(T.key)) + var/client_file + client_file = T.client.Import() + if(client_file == "-1.sav") client_file = null + if(client_file) + if(!Load(C, client_file)) + // Out of date or bad savefile, discard. + T.client.Export() + C.name = T.name + C.key = T.key + else + C.name = T.name + C.key = T.key + var/SetView/SV = new(); SV.Initialize(C); del(SV) + var/HelpView/HV = new(); HV.Initialize(C); del(SV) + var/GamesView/GV = new(); GV.Initialize(C); del(SV) + else + C.name = T.name + C.key = T.key + + del(T) + + + // Tests if the key is a telnet key eg: Telnet @127.000.000.001 + istelnet(key) + if(findtext(key, "Telnet @") == 1) + return 1 + + + Get(chatter, local) + if(!length(chatter)) return + + if(Home && Home.chatters) + var first_char = text2ascii(copytext(chatter, 1, 2)) + // If search starts with a number, search IPs. + if(first_char > 47 && first_char < 58) + // Exact IP first + for(var/mob/chatter/C in Home.chatters) + if(C.client.address == chatter) + return C + + // Partial IP second + for(var/mob/chatter/C in Home.chatters) + if(TextMan.Match(C.client.address, chatter)) + return C + + else + // Exact key search. + for(var/mob/chatter/C in Home.chatters) + if(ckey(C.name) == ckey(chatter)) return C + + // Partial case-sensitive key search + for(var/mob/chatter/C in Home.chatters) + if(TextMan.Match(C.key, chatter)) return C + + // Partial non-case-sensitive key search + for(var/mob/chatter/C in Home.chatters) + if(TextMan.Match(C.ckey, chatter)) return C + + + Rank(chatter) + if(Home && chatter) + var/cKey = ckey(chatter) + if(cKey in Home.operators) + var/Op/O = Home.operators[cKey] + return O.Rank + return "All" + + + ParseFormat(format, variables[], required[]) + if(!format || !variables || !variables.len) return FALSE + if(required) + for(var/r in required) + if(!findtext(format, r)) return FALSE + var/list/L = new() + var/temp = format + for(var/v in variables) + var/pos = findtext(format, v) + if(pos) variables[v] = pos + else variables -= v + for(var/v = variables.len, v >= 1, v--) + for(var/i = 1, i < v, i++) + if(variables[variables[i]] > variables[variables[i+1]]) + variables.Swap( i, i+1) + else if(variables[variables[i]] == variables[variables[i+1]]) + variables -= variables[i+1] + if(v > variables.len) break + for(var/v in variables) + var/pos = findtext(temp, v) + if(pos > 1) + L += copytext(temp, 1, pos) + L += v + temp = copytext(temp, pos+length(v)) + if(length(temp)) + L += temp + return L + + Load(mob/chatter/C, client_file) + var/savefile/F = new(client_file) + var/version + F["version"] >> version + + if(version == "0.1.5" && ("CRYPTO" in F.dir)) + var/crypto + F["CRYPTO"] >> crypto + crypto = RC5_Decrypt(crypto, md5(world.hub_password)) + for(var/i = 1; i <= length(crypto); ++i) + if(text2ascii(crypto, i) < 32) return FALSE + F.dir -= "CRYPTO" + F.ImportText("/", crypto) + C.Read(F) + // Save an updated savefile. + Save(C) + return TRUE + else if(version == savefile_version) + C.Read(F) + return TRUE + else + return FALSE + + Save(mob/chatter/C) + var/savefile/S = new() + C.Write(S) + S["version"] << savefile_version + sleep(5) + C.client.Export(S) + + + EditSave(var/save) + if(!save) return + var/savefile/F = new(save) + var/text = F.ExportText("/") + return text diff --git a/code/controllers/managers/helpman.dm b/code/controllers/managers/helpman.dm index 2a4e683..61f2bbe 100644 --- a/code/controllers/managers/helpman.dm +++ b/code/controllers/managers/helpman.dm @@ -1,84 +1,83 @@ - -HelpManager - - var - obj/help/chapter/Main - list - Contents - Topics - - New() - ..() - spawn() - LoadXML() - - Topic(href, href_list) - ..() - var/cKey = ckey(href_list["source"]) - var/mob/chatter/M = ChatMan.Get(cKey) - if(!M) for(var/mob/chatter/c in world) - if(cKey == c.ckey) M = c - if(!M) return - switch(href_list["action"]) - if("open") - for(var/obj/help/chapter/C in world) - if(C.name == url_decode(href_list["target"])) - C.open(M) - if("close") - for(var/obj/help/chapter/C in world) - if(C.name == url_decode(href_list["target"])) - C.close(M) - if("view_topic") - for(var/obj/help/topic/T in world) - if(T.name == url_decode(href_list["target"])) - T.show(M, href_list["page"]) - - proc - LoadXML() - if(!fexists("./data/xml/help/contents.xml")) - ErrMan.Topic("300") - return - var/XML/Element/contents_root = xmlRootFromFile("./data/xml/help/contents.xml") - if(!contents_root) - ErrMan.Topic("301") - return - var/XML/Element/topics_root = xmlRootFromPath("./data/xml/help/topics") - if(!topics_root) - ErrMan.Topic("302") - return - Contents = contents_root.ChildElements("chapter") - Topics = topics_root.Descendants("topic") - BuildContents() - - BuildContents() - Main = new() - Main.name = "Table of Contents" - Main = GetContents(Main, Contents, "./data/xml/help/topics", 1) - - GetContents(obj/help/chapter/container, contents[], path) - var/j = 1 - for(var/XML/Element/C in contents) - var/obj/help/chapter/O = new() - O.indent = container.indent+1 - O.name = C.Attribute("name") - var/list/Chapters = C.ChildElements("chapter") - if(Chapters && Chapters.len) - O = GetContents(O, Chapters, path+"/[j]") - var/list/topics = C.ChildElements("topic") - var/n = 1 - for(var/XML/Element/T in topics) - var/obj/help/topic/t = new() - t.indent = O.indent+1 - t.name = T.Text() - for(var/XML/Element/E in Topics) - if(E.Attribute("file_path") == "[path]/[j]/[n].xml") - var/XML/Element/info = E.Descendant("info") - var/TXT = info.Text() - if(TXT) t.Text = TXT - break - n++ - O.contents += t - container.contents += O - j++ - return container - + +HelpManager + + var + obj/help/chapter/Main + list + Contents + Topics + + New() + ..() + LoadXML() + + Topic(href, href_list) + ..() + var/cKey = ckey(href_list["source"]) + var/mob/chatter/M = ChatMan.Get(cKey) + if(!M) for(var/mob/chatter/c in world) + if(cKey == c.ckey) M = c + if(!M) return + switch(href_list["action"]) + if("open") + for(var/obj/help/chapter/C in world) + if(C.name == url_decode(href_list["target"])) + C.open(M) + if("close") + for(var/obj/help/chapter/C in world) + if(C.name == url_decode(href_list["target"])) + C.close(M) + if("view_topic") + for(var/obj/help/topic/T in world) + if(T.name == url_decode(href_list["target"])) + T.show(M, href_list["page"]) + + proc + LoadXML() + if(!fexists("./data/xml/help/contents.xml")) + ErrMan.Topic("300") + return + var/XML/Element/contents_root = xmlRootFromFile("./data/xml/help/contents.xml") + if(!contents_root) + ErrMan.Topic("301") + return + var/XML/Element/topics_root = xmlRootFromPath("./data/xml/help/topics") + if(!topics_root) + ErrMan.Topic("302") + return + Contents = contents_root.ChildElements("chapter") + Topics = topics_root.Descendants("topic") + BuildContents() + + BuildContents() + Main = new() + Main.name = "Table of Contents" + Main = GetContents(Main, Contents, "./data/xml/help/topics", 1) + + GetContents(obj/help/chapter/container, contents[], path) + var/j = 1 + for(var/XML/Element/C in contents) + var/obj/help/chapter/O = new() + O.indent = container.indent+1 + O.name = C.Attribute("name") + var/list/Chapters = C.ChildElements("chapter") + if(Chapters && Chapters.len) + O = GetContents(O, Chapters, path+"/[j]") + var/list/topics = C.ChildElements("topic") + var/n = 1 + for(var/XML/Element/T in topics) + var/obj/help/topic/t = new() + t.indent = O.indent+1 + t.name = T.Text() + for(var/XML/Element/E in Topics) + if(E.Attribute("file_path") == "[path]/[j]/[n].xml") + var/XML/Element/info = E.Descendant("info") + var/TXT = info.Text() + if(TXT) t.Text = TXT + break + n++ + O.contents += t + container.contents += O + j++ + return container + diff --git a/code/controllers/managers/msgman.dm b/code/controllers/managers/msgman.dm index fd2d24f..2043fce 100644 --- a/code/controllers/managers/msgman.dm +++ b/code/controllers/managers/msgman.dm @@ -1,46 +1,45 @@ - -MessageManager - var - isIgnoredResult = 1 - - Topic(href, href_list[]) - ..() - switch(href_list["action"]) - if("isIgnored") - var/From = href_list["from"] - var/T = href_list["to"] - var/mob/chatter/To = ChatMan.Get(T,1) - var/Addr = href_list["addr"] - if(To.ignoring(From) & IM_IGNORE) - world.Export("[Addr]?dest=msgman&action=isIgnoredResult&result=true") - else - world.Export("[Addr]?dest=msgman&action=isIgnoredResult&result=true") - if("isIgnoredResult") - isIgnoredResult = href_list["result"] - if("msg") - var/savefile/S = new(world.Import()) - var/mob/From, T, M - S["to"] >> T - S["from"] >> From - S["msg"] >> M - if(!ChatMan.Dummies) ChatMan.Dummies = new() - ChatMan.Dummies += From - var/mob/chatter/C = ChatMan.Get(T,1) - RouteMsg(From,C,M) - - - - proc - RouteMsg(mob/chatter/From, mob/chatter/To, msg, clean) - if(!msg) return - if(To.ignoring(From) & IM_IGNORE) - alert(From, "[To.name] is ignoring instant messages from you.", "Unable to IM chatter.") - return - To.MsgHand.GetMsg(From, msg, clean) - - isIgnoring(Name) - var/timeout = 300 - isIgnoredResult = null - world.Export("[NetMan.Chatters[Name]]?dest=msgman&action=isIgnored&name=[Name]") - while(isnull(isIgnoredResult) && timeout--) sleep(1) + +MessageManager + var + isIgnoredResult = 1 + + Topic(href, href_list[]) + ..() + switch(href_list["action"]) + if("isIgnored") + var/From = href_list["from"] + var/T = href_list["to"] + var/mob/chatter/To = ChatMan.Get(T,1) + var/Addr = href_list["addr"] + if(To.ignoring(From) & IM_IGNORE) + world.Export("[Addr]?dest=msgman&action=isIgnoredResult&result=true") + else + world.Export("[Addr]?dest=msgman&action=isIgnoredResult&result=true") + if("isIgnoredResult") + isIgnoredResult = href_list["result"] + if("msg") + var/savefile/S = new(world.Import()) + var/mob/From, T, M + S["to"] >> T + S["from"] >> From + S["msg"] >> M + if(!ChatMan.Dummies) ChatMan.Dummies = new() + ChatMan.Dummies += From + var/mob/chatter/C = ChatMan.Get(T,1) + RouteMsg(From,C,M) + + + + proc + RouteMsg(mob/chatter/From, mob/chatter/To, msg, clean) + if(!msg) return + if(To.ignoring(From) & IM_IGNORE) + alert(From, "[To.name] is ignoring instant messages from you.", "Unable to IM chatter.") + return + To.MsgHand.GetMsg(From, msg, clean) + + isIgnoring(Name) + var/timeout = 300 + isIgnoredResult = null + while(isnull(isIgnoredResult) && timeout--) sleep(1) return isIgnoredResult \ No newline at end of file diff --git a/code/controllers/managers/netman.dm b/code/controllers/managers/netman.dm index 65265be..6f731db 100644 --- a/code/controllers/managers/netman.dm +++ b/code/controllers/managers/netman.dm @@ -1,280 +1,279 @@ - -NetworkManager - var - name - desc - addr - port - Port - host - - ServerIP - - - Rebooting - Hosting - - timeout = 50 - retry = 3 - - Status - - MotD = "Thank you for helping test Chatters! Please post detailed bug reports so we can track down the problems and fix them." - - tmp/list - Chans - Chatters - - - New() - ..() - spawn() - LoadNetworkCfg() - - Topic(href, href_list) - ..() - switch(href_list["action"]) - if("validate") - if(Host && Host.client) winset(Host, "main_menu.info_top", - "text='Validating channel server...'") - var/Code = href_list["code"] - if(!ServerIP) ServerIP = copytext(href_list["ip"],1,findtext(href_list["ip"],":")) - var/Valid = md5("rbl9FQ0h[Code]zWtOEKtg") - Status = VALIDATING - var/retries = retry - sleep(20) - do - var/Name - if(Host && Host.client) Name = Host.name - else Name = ChanMan.host - world.Export("[addr]:[port]?dest=netman&action=validate&code=[Valid]&name=[ckey(Name)]") - sleep(timeout) - if(Status == VALIDATING) - if(Host && Host.client) - winset(Host, "main_menu.info_top", "text='Connection timed out.'") - sleep(20) - if(!--retries) break - if(Host && Host.client) - if(Status == VALIDATING) - winset(Host, "main_menu.info_top", "text='Validating channel server...'") - while(Status == VALIDATING) - if(Status == VALIDATING) - Status = FAILED - if(Host && Host.client) winset(Host, "main_menu.info_top", "text='Problem contacting network!'") - if("connected") - if(Host && Host.client) - winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") - winset(Host, "main_menu.cim", "is-disabled=false;") - winset(Host, "main_menu.public_chans", "is-disabled=false;") - winset(Host, "main_menu.cmail", "is-disabled=false;") - winset(Host, "main_menu.child", "left=main_menu_output") - winset(Host, "main_menu_output.network_label", "text='[NetMan.name]'") - Host << output(, "main_menu_output.output") - Host << output("Connected to the Chatters Network Server. \ -You may now open a public channel, or access the network features such as Cmail, CIMs, Groups and more. \ -Click Help for more information.", "main_menu_output.output") - call(Host,"ServerLink")() - Status = CONNECTED - Query("getchans") - Query("getchatters") - if("chanlist") - var/savefile/S = new(world.Import()) - S["chans"] >> Chans - if("chatlist") - var/savefile/S = new(world.Import()) - S["chatters"] >> Chatters - if("ping") - world.Export("[addr]:[port]?dest=netman&action=pong") - if("netmap") - Query("getchans") - Query("getchatters") - - proc - LoadNetworkCfg() - var/list/config = Console.LoadCFG("./data/saves/network.cfg") - if(!config || !config.len) ErrMan.Topic("100") - - var/list/Main = params2list(config["main"]) - - name = Main["name"] - if(!name) ErrMan.Topic("101") - - desc = Main["desc"] - if(!desc) ErrMan.Topic("102") - - addr = Main["addr"] - if(!addr) ErrMan.Topic("103") - - port = Main["port"] - if(!port) ErrMan.Topic("104") - - host = Main["host"] - if(!host) ErrMan.Topic("105") - - HostCheck(client/C) - if(ChanMan && ChanMan.devs && (C.ckey in ChanMan.devs)) - for(var/Command in (typesof(/Bot/verb)-/Bot/verb)) - C.verbs += Command - if(!Host && ((!ChanMan.host && (!C.address || C.address == "127.0.0.1")) || (ChanMan.host == C.ckey))) - Host = C.mob - winset(Host, "main_menu.close", "is-visible=false") - winset(Host, "default", "size=484x244") - winset(Host, "default.child", "left=main_menu") - for(var/Command in (typesof(/Host/proc)-/Host/proc)) - Host.verbs += Command - for(var/Command in (typesof(/Operator/proc)-/Operator/proc)) - Host.verbs += Command - call(Host, "ShowMainMenu")() - if(debugs) - for(var/d in debugs) - Host << output("[d]", "console.output") - winshow(Host, "console", 1) - debugs = null - return 1 - return 0 - - - PreConnect(newport) - //if(newport != "none") - // opening server - //else - // closing server - return newport - - - PostConnect(newport, oldport) - if(!world.port && !oldport && (newport != "none")) - Status = FAILED - // ErrMan.Topic("200", newport) - if(Host) winset(Host, "main_menu.info_top", "text='Unable to open port [newport]!'") - // problem opening the server - //else if(!world.port && oldport) - // server closed - //else if(newport != "none") - // server opened - - Connect() - if(NetMan.Status == CONNECTED) - winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") - winset(Host, "main_menu.cim", "is-disabled=false;") - winset(Host, "main_menu.public_chans", "is-disabled=false;") - winset(Host, "main_menu.cmail", "is-disabled=false;") - winset(Host, "main_menu.child", "left=main_menu_output") - winset(Host, "main_menu_output.network_label", "text='[NetMan.name]'") - call(Host,"ServerLink")() - else if(NetMan.Status != FAILED) - world.OpenPort(NetMan.Port) - spawn() - winset(Host, "main_menu.info_top", "text='Contacting network...'") - NetMan.Status = CONTACTING - var/retries = NetMan.retry - sleep(10) - do - world.Export("[NetMan.addr]:[NetMan.port]?dest=netman&action=newserver") - sleep(NetMan.timeout) - if(NetMan.Status == CONTACTING) - winset(Host, "main_menu.info_top", "text='Connection timed out.'") - Host << output("timeout.", "main_menu_connect.output") - sleep(20) - if(!--retries) break - if(NetMan.Status == CONTACTING) - winset(Host, "main_menu.info_top", "text='Contacting network...'") - Host << output("Retrying...\...", "main_menu_connect.output") - while(NetMan.Status == CONTACTING) - if(NetMan.Status == CONTACTING) - NetMan.Status = FAILED - winset(Host, "main_menu.info_top", "text='Problem contacting network!'") - var/msg = "The network server failed to respond. \ - Please make sure the network address is correct, \ - and no firewalls are blocking incoming traffic on \ - port [NetMan.Port]." - Host << output(, "main_menu_connect.output") - Host << output(msg, "main_menu_connect.output") - winset(Host, "main_menu_connect.network_label", "is-disabled=false;text-color=#000000") - winset(Host, "main_menu_connect.network_addr", "is-disabled=false;background-color=#FFFFFF") - winset(Host, "main_menu_connect.public", "is-disabled=false") - winset(Host, "main_menu_connect.private", "is-disabled=false") - winset(Host, "main_menu_connect.invisible", "is-disabled=false") - winset(Host, "main_menu_connect.connect", "is-disabled=false") - - - Disconnect() - if(port) world.OpenPort(0) - Status = null - world.Export("[addr]:[port]?dest=chanman&action=delserver") - if(Host) - winset(Host, "main_menu.cim", "is-disabled=true;") - winset(Host, "main_menu.public_chans", "is-disabled=true;") - winset(Host, "main_menu.cmail", "is-disabled=true;") - winset(Host, "main_menu.info_top", "text='Disconnected from the Chatters Network'") - spawn(30) - if(winget(Host, "main_menu.info_top", "text")=="Disconnected from the Chatters Network") - winset(Host, "main_menu.info_top", "text=") - winset(Host, "main_menu.info_bottom", "text=") - - - Report(topic, params) - if(Status != CONNECTED) return - switch(topic) - if("join") - world.Export("[addr]:[port]?dest=chatman&action=login&name=[params]") - return 1 - if("quit") - world.Export("[addr]:[port]?dest=chatman&action=logout&name=[params]") - return 1 - - Query(topic, params) - if(Status != CONNECTED) return - switch(topic) - if("getchans") - world.Export("[addr]:[port]?dest=chanman&action=getchans") - return 1 - if("getchatters") - world.Export("[addr]:[port]?dest=chatman&action=getchatters") - return 1 - - MOTD(mob/chatter/C) - if(!C || !C.client || !C.Chan || !C.show_motd || !MotD) return - if(C.show_colors) - C << output("[TextMan.fadetext("Network Message of the Day", list("255000000","204153153","255204000"))]:", "[ckey(C.Chan.name)].chat.default_output") - else - C << output("Network Message of the Day:", "[ckey(C.Chan.name)].chat.default_output") - C << output(" [MotD]\n", "[ckey(C.Chan.name)].chat.default_output") - - UpdatePubChans(mob/chatter/C) - if(!C || C.telnet) return - var/i=2 - var/bgcolor - var/obj/L = new(); L.icon = './resources/images/interface/locks/locked_white.png'; L.name = "" - var/obj/U = new(); U.icon = './resources/images/interface/locks/unlocked_white.png' ; U.name="" - if(!Chans || !Chans.len) - winset(C, "pub_chans.info_top", "text='0 channels online'") - winset(C, "pub_chans.grid", "current-cell=1,2;") - Host << output(, "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=2,2;") - Host << output(, "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=3,2;") - Host << output(, "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=4,2;") - Host << output(, "pub_chans.grid") - winset(C, "pub_chans.grid", "cells=4x1") - else - winset(C, "pub_chans.info_top", "text='[Chans.len] channel\s online'") - for(var/Addr in Chans) - var/Channel/Chan = Chans[Addr] - if(i&1) - bgcolor="#ccc" - L.icon = './resources/images/interface/locks/locked_grey.png' - U.icon = './resources/images/interface/locks/unlocked_grey.png' - else - bgcolor="#fff" - L.icon = './resources/images/interface/locks/locked_white.png' - U.icon = './resources/images/interface/locks/unlocked_white.png' - winset(C, "pub_chans.grid", "current-cell=1,[i];") - C << output(" [Chan.name]", "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=2,[i];") - C << output("[Chan.founder]", "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=3,[i];") - C << output("[Chan.desc]", "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=4,[i++];") + +NetworkManager + var + name + desc + addr + port + Port + host + + ServerIP + + + Rebooting + Hosting + + timeout = 50 + retry = 3 + + Status + + MotD = "Thank you for helping test Chatters! Please post detailed bug reports so we can track down the problems and fix them." + + tmp/list + Chans + Chatters + + + New(var/ServerConsole/console) + ..() + LoadNetworkCfg(console) + + Topic(href, href_list) + ..() + switch(href_list["action"]) + if("validate") + if(Host && Host.client) winset(Host, "main_menu.info_top", + "text='Validating channel server...'") + var/Code = href_list["code"] + if(!ServerIP) ServerIP = copytext(href_list["ip"],1,findtext(href_list["ip"],":")) + var/Valid = md5("rbl9FQ0h[Code]zWtOEKtg") + Status = VALIDATING + var/retries = retry + sleep(20) + do + var/Name + if(Host && Host.client) Name = Host.name + else Name = ChanMan.host + world.Export("[addr]:[port]?dest=netman&action=validate&code=[Valid]&name=[ckey(Name)]") + sleep(timeout) + if(Status == VALIDATING) + if(Host && Host.client) + winset(Host, "main_menu.info_top", "text='Connection timed out.'") + sleep(20) + if(!--retries) break + if(Host && Host.client) + if(Status == VALIDATING) + winset(Host, "main_menu.info_top", "text='Validating channel server...'") + while(Status == VALIDATING) + if(Status == VALIDATING) + Status = FAILED + if(Host && Host.client) winset(Host, "main_menu.info_top", "text='Problem contacting network!'") + if("connected") + if(Host && Host.client) + winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") + winset(Host, "main_menu.cim", "is-disabled=false;") + winset(Host, "main_menu.public_chans", "is-disabled=false;") + winset(Host, "main_menu.cmail", "is-disabled=false;") + winset(Host, "main_menu.child", "left=main_menu_output") + winset(Host, "main_menu_output.network_label", "text='[NetMan.name]'") + Host << output(, "main_menu_output.output") + Host << output("Connected to the Chatters Network Server. \ +You may now open a public channel, or access the network features such as Cmail, CIMs, Groups and more. \ +Click Help for more information.", "main_menu_output.output") + call(Host,"ServerLink")() + Status = CONNECTED + Query("getchans") + Query("getchatters") + if("chanlist") + var/savefile/S = new(world.Import()) + S["chans"] >> Chans + if("chatlist") + var/savefile/S = new(world.Import()) + S["chatters"] >> Chatters + if("ping") + world.Export("[addr]:[port]?dest=netman&action=pong") + if("netmap") + Query("getchans") + Query("getchatters") + + proc + LoadNetworkCfg(var/ServerConsole/console) + var/list/config = console.LoadCFG("./data/saves/network.cfg") + if(!config || !config.len) ErrMan.Topic("100") + + var/list/Main = params2list(config["main"]) + + name = Main["name"] + if(!name) ErrMan.Topic("101") + + desc = Main["desc"] + if(!desc) ErrMan.Topic("102") + + addr = Main["addr"] + if(!addr) ErrMan.Topic("103") + + port = Main["port"] + if(!port) ErrMan.Topic("104") + + host = Main["host"] + if(!host) ErrMan.Topic("105") + + HostCheck(client/C) + if(ChanMan && ChanMan.devs && (C.ckey in ChanMan.devs)) + for(var/Command in (typesof(/Bot/verb)-/Bot/verb)) + C.verbs += Command + if(!Host && ((!ChanMan.host && (!C.address || C.address == "127.0.0.1")) || (ChanMan.host == C.ckey))) + Host = C.mob + winset(Host, "main_menu.close", "is-visible=false") + winset(Host, "default", "size=484x244") + winset(Host, "default.child", "left=main_menu") + for(var/Command in (typesof(/Host/proc)-/Host/proc)) + Host.verbs += Command + for(var/Command in (typesof(/Operator/proc)-/Operator/proc)) + Host.verbs += Command + call(Host, "ShowMainMenu")() + if(debugs) + for(var/d in debugs) + Host << output("[d]", "console.output") + winshow(Host, "console", 1) + debugs = null + return 1 + return 0 + + + PreConnect(newport) + //if(newport != "none") + // opening server + //else + // closing server + return newport + + + PostConnect(newport, oldport) + if(!world.port && !oldport && (newport != "none")) + Status = FAILED + // ErrMan.Topic("200", newport) + if(Host) winset(Host, "main_menu.info_top", "text='Unable to open port [newport]!'") + // problem opening the server + //else if(!world.port && oldport) + // server closed + //else if(newport != "none") + // server opened + + Connect() + if(NetMan.Status == CONNECTED) + winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") + winset(Host, "main_menu.cim", "is-disabled=false;") + winset(Host, "main_menu.public_chans", "is-disabled=false;") + winset(Host, "main_menu.cmail", "is-disabled=false;") + winset(Host, "main_menu.child", "left=main_menu_output") + winset(Host, "main_menu_output.network_label", "text='[NetMan.name]'") + call(Host,"ServerLink")() + else if(NetMan.Status != FAILED) + world.OpenPort(NetMan.Port) + spawn() + winset(Host, "main_menu.info_top", "text='Contacting network...'") + NetMan.Status = CONTACTING + var/retries = NetMan.retry + sleep(10) + do + world.Export("[NetMan.addr]:[NetMan.port]?dest=netman&action=newserver") + sleep(NetMan.timeout) + if(NetMan.Status == CONTACTING) + winset(Host, "main_menu.info_top", "text='Connection timed out.'") + Host << output("timeout.", "main_menu_connect.output") + sleep(20) + if(!--retries) break + if(NetMan.Status == CONTACTING) + winset(Host, "main_menu.info_top", "text='Contacting network...'") + Host << output("Retrying...\...", "main_menu_connect.output") + while(NetMan.Status == CONTACTING) + if(NetMan.Status == CONTACTING) + NetMan.Status = FAILED + winset(Host, "main_menu.info_top", "text='Problem contacting network!'") + var/msg = "The network server failed to respond. \ + Please make sure the network address is correct, \ + and no firewalls are blocking incoming traffic on \ + port [NetMan.Port]." + Host << output(, "main_menu_connect.output") + Host << output(msg, "main_menu_connect.output") + winset(Host, "main_menu_connect.network_label", "is-disabled=false;text-color=#000000") + winset(Host, "main_menu_connect.network_addr", "is-disabled=false;background-color=#FFFFFF") + winset(Host, "main_menu_connect.public", "is-disabled=false") + winset(Host, "main_menu_connect.private", "is-disabled=false") + winset(Host, "main_menu_connect.invisible", "is-disabled=false") + winset(Host, "main_menu_connect.connect", "is-disabled=false") + + + Disconnect() + if(port) world.OpenPort(0) + Status = null + world.Export("[addr]:[port]?dest=chanman&action=delserver") + if(Host) + winset(Host, "main_menu.cim", "is-disabled=true;") + winset(Host, "main_menu.public_chans", "is-disabled=true;") + winset(Host, "main_menu.cmail", "is-disabled=true;") + winset(Host, "main_menu.info_top", "text='Disconnected from the Chatters Network'") + spawn(30) + if(winget(Host, "main_menu.info_top", "text")=="Disconnected from the Chatters Network") + winset(Host, "main_menu.info_top", "text=") + winset(Host, "main_menu.info_bottom", "text=") + + + Report(topic, params) + if(Status != CONNECTED) return + switch(topic) + if("join") + world.Export("[addr]:[port]?dest=chatman&action=login&name=[params]") + return 1 + if("quit") + world.Export("[addr]:[port]?dest=chatman&action=logout&name=[params]") + return 1 + + Query(topic, params) + if(Status != CONNECTED) return + switch(topic) + if("getchans") + world.Export("[addr]:[port]?dest=chanman&action=getchans") + return 1 + if("getchatters") + world.Export("[addr]:[port]?dest=chatman&action=getchatters") + return 1 + + MOTD(mob/chatter/C) + if(!C || !C.client || !C.Chan || !C.show_motd || !MotD) return + if(C.show_colors) + C << output("[TextMan.fadetext("Network Message of the Day", list("255000000","204153153","255204000"))]:", "[ckey(C.Chan.name)].chat.default_output") + else + C << output("Network Message of the Day:", "[ckey(C.Chan.name)].chat.default_output") + C << output(" [MotD]\n", "[ckey(C.Chan.name)].chat.default_output") + + UpdatePubChans(mob/chatter/C) + if(!C || C.telnet) return + var/i=2 + var/bgcolor + var/obj/L = new(); L.icon = './resources/images/interface/locks/locked_white.png'; L.name = "" + var/obj/U = new(); U.icon = './resources/images/interface/locks/unlocked_white.png' ; U.name="" + if(!Chans || !Chans.len) + winset(C, "pub_chans.info_top", "text='0 channels online'") + winset(C, "pub_chans.grid", "current-cell=1,2;") + Host << output(, "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=2,2;") + Host << output(, "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=3,2;") + Host << output(, "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=4,2;") + Host << output(, "pub_chans.grid") + winset(C, "pub_chans.grid", "cells=4x1") + else + winset(C, "pub_chans.info_top", "text='[Chans.len] channel\s online'") + for(var/Addr in Chans) + var/Channel/Chan = Chans[Addr] + if(i&1) + bgcolor="#ccc" + L.icon = './resources/images/interface/locks/locked_grey.png' + U.icon = './resources/images/interface/locks/unlocked_grey.png' + else + bgcolor="#fff" + L.icon = './resources/images/interface/locks/locked_white.png' + U.icon = './resources/images/interface/locks/unlocked_white.png' + winset(C, "pub_chans.grid", "current-cell=1,[i];") + C << output(" [Chan.name]", "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=2,[i];") + C << output("[Chan.founder]", "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=3,[i];") + C << output("[Chan.desc]", "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=4,[i++];") C << output("[Chan.chatters]", "pub_chans.grid") \ No newline at end of file diff --git a/code/controllers/managers/opman.dm b/code/controllers/managers/opman.dm index 4a5ac55..b07c621 100644 --- a/code/controllers/managers/opman.dm +++ b/code/controllers/managers/opman.dm @@ -1,130 +1,129 @@ - -OperatorManager - - var - list - op_ranks - op_privileges - - New() - ..() - spawn() - LoadXML() - - proc - LoadXML() - var/list/ranks = flist("./data/xml/ops/ranks/") - op_ranks = listOpen(op_ranks) - op_ranks.len = ranks.len - for(var/rank in ranks) - if(!findtext(rank, "xml", length(rank)-2)) continue - var/XML/Element/rank_root = xmlRootFromFile("./data/xml/ops/ranks/[rank]") - rank_root = rank_root.Descendant("oprank") - if(!rank_root) return - var/OpRank/Rank = new() - Rank.name = rank_root.Attribute("name") - Rank.select.name = Rank.name - Rank.pos = text2num(rank_root.Attribute("pos")) - Rank.color = rank_root.Attribute("color") - Rank.monitor = text2num(rank_root.Attribute("monitor")) - Rank.auto_approve = text2num(rank_root.Attribute("approve")) - var/XML/Element/descXML = rank_root.Descendant("desc") - if(descXML) Rank.desc = descXML.Text() - var/XML/Element/promoteXML = rank_root.Descendant("promote") - if(promoteXML) Rank.promote = promoteXML.Text() - var/XML/Element/demoteXML = rank_root.Descendant("demote") - if(demoteXML) Rank.demote = demoteXML.Text() - var/XML/Element/tempXML = rank_root.Descendant("temp") - if(tempXML) - Rank.temp = 1 - Rank.expires = text2num(tempXML.Attribute("expires")) - else Rank.temp = 0 - var/XML/Element/electXML = rank_root.Descendant("elect") - if(electXML) - Rank.elect = 1 - Rank.elect_by = electXML.Attribute("by") - Rank.or_lower = text2num(electXML.Attribute("orlower")) - if(!Rank.or_lower) Rank.or_higher = 1 - else Rank.or_higher = text2num(electXML.Attribute("orhigher")) - Rank.max_elect = text2num(electXML.Attribute("max")) - else Rank.elect = 0 - Rank.privs = new() - var/XML/Element/privsXML = rank_root.Descendant("privileges") - if(privsXML) - for(var/XML/Element/Priv in privsXML.Descendants("privilege")) - Rank.privs += Priv.Attribute("name") - op_ranks[Rank.pos] = Rank - for(var/r in op_ranks) - if(isnull(r)) op_ranks -= r - var/list/privs = flist("./data/xml/ops/privileges/") - op_privileges = listOpen(op_privileges) - op_privileges.len = privs.len - for(var/priv in privs) - if(!findtext(priv, "xml", length(priv)-2)) continue - var/XML/Element/priv_root = xmlRootFromFile("./data/xml/ops/privileges/[priv]") - priv_root = priv_root.Descendant("oppriv") - if(!priv_root) return - var/OpPrivilege/Priv = new() - Priv.name = priv_root.Attribute("name") - Priv.select.name = Priv.name - Priv.monitor = text2num(priv_root.Attribute("monitor")) - Priv.auto_approve = text2num(priv_root.Attribute("approve")) - var/XML/Element/descXML = priv_root.Descendant("desc") - if(descXML) Priv.desc = descXML.Text() - var/XML/Element/executeXML = priv_root.Descendant("execute") - if(executeXML) Priv.execute = executeXML.Text() - var/XML/Element/commandXML = priv_root.Descendant("command") - if(commandXML) Priv.command = commandXML.Text() - var/XML/Element/electXML = priv_root.Descendant("elect") - if(electXML) - Priv.elect = 1 - Priv.elect_by = electXML.Attribute("by") - Priv.or_lower = text2num(electXML.Attribute("orlower")) - if(!Priv.or_lower) Priv.or_higher = 1 - else Priv.or_higher = text2num(electXML.Attribute("orhigher")) - Priv.min_votes = abs(text2num(electXML.Attribute("min_votes"))) - Priv.min_delay = abs(text2num(electXML.Attribute("min_delay"))) - Priv.margin = abs(text2num(electXML.Attribute("margin"))) - else Priv.elect = 0 - op_privileges[Priv.name] = Priv - for(var/p in op_privileges) - if(isnull(p)) op_privileges -= p - - SaveRankXML(OpRank/Rank) - if(!Rank) return - var/XML/Element/mainXML = new("xml") - var/XML/Element/rankXML = new("oprank") - mainXML.AddChild(rankXML) - var/list/rank_attributes = list("name"=Rank.name,"pos"="[Rank.pos]","color"=Rank.color) - if(Rank.monitor) rank_attributes["monitor"] = "1" - if(Rank.auto_approve) rank_attributes["approve"] = "1" - rankXML.setAttributes(rank_attributes) - var/XML/Element/descXML = new("desc") - rankXML.AddChild(descXML) - descXML.setText(Rank.desc) - var/XML/Element/promoteXML = new("promote") - rankXML.AddChild(promoteXML) - promoteXML.setText(Rank.promote) - var/XML/Element/demoteXML = new("demote") - rankXML.AddChild(demoteXML) - demoteXML.setText(Rank.demote) - if(Rank.temp) - var/XML/Element/tempXML = new("temp") - rankXML.AddChild(tempXML) - tempXML.setAttribute("expires",Rank.expires) - if(Rank.elect) - var/XML/Element/electXML = new("elect") - rankXML.AddChild(electXML) - electXML.setAttribute("by", Rank.elect_by) - if(Rank.or_higher) - electXML.setAttribute("orhigher", "1") - electXML.setAttribute("max", Rank.max_elect) - var/XML/Element/privsXML = new("privileges") - rankXML.AddChild(privsXML) - for(var/priv in Rank.privs) - var/XML/Element/privXML = new("privilege") - privsXML.AddChild(privXML) - privXML.setAttribute("name", priv) - mainXML.WriteToFile("./data/xml/ops/ranks/[Rank.name].xml") - - + +OperatorManager + + var + list + op_ranks + op_privileges + + New() + ..() + LoadXML() + + proc + LoadXML() + var/list/ranks = flist("./data/xml/ops/ranks/") + op_ranks = listOpen(op_ranks) + op_ranks.len = ranks.len + for(var/rank in ranks) + if(!findtext(rank, "xml", length(rank)-2)) continue + var/XML/Element/rank_root = xmlRootFromFile("./data/xml/ops/ranks/[rank]") + rank_root = rank_root.Descendant("oprank") + if(!rank_root) return + var/OpRank/Rank = new() + Rank.name = rank_root.Attribute("name") + Rank.select.name = Rank.name + Rank.pos = text2num(rank_root.Attribute("pos")) + Rank.color = rank_root.Attribute("color") + Rank.monitor = text2num(rank_root.Attribute("monitor")) + Rank.auto_approve = text2num(rank_root.Attribute("approve")) + var/XML/Element/descXML = rank_root.Descendant("desc") + if(descXML) Rank.desc = descXML.Text() + var/XML/Element/promoteXML = rank_root.Descendant("promote") + if(promoteXML) Rank.promote = promoteXML.Text() + var/XML/Element/demoteXML = rank_root.Descendant("demote") + if(demoteXML) Rank.demote = demoteXML.Text() + var/XML/Element/tempXML = rank_root.Descendant("temp") + if(tempXML) + Rank.temp = 1 + Rank.expires = text2num(tempXML.Attribute("expires")) + else Rank.temp = 0 + var/XML/Element/electXML = rank_root.Descendant("elect") + if(electXML) + Rank.elect = 1 + Rank.elect_by = electXML.Attribute("by") + Rank.or_lower = text2num(electXML.Attribute("orlower")) + if(!Rank.or_lower) Rank.or_higher = 1 + else Rank.or_higher = text2num(electXML.Attribute("orhigher")) + Rank.max_elect = text2num(electXML.Attribute("max")) + else Rank.elect = 0 + Rank.privs = new() + var/XML/Element/privsXML = rank_root.Descendant("privileges") + if(privsXML) + for(var/XML/Element/Priv in privsXML.Descendants("privilege")) + Rank.privs += Priv.Attribute("name") + op_ranks[Rank.pos] = Rank + for(var/r in op_ranks) + if(isnull(r)) op_ranks -= r + var/list/privs = flist("./data/xml/ops/privileges/") + op_privileges = listOpen(op_privileges) + op_privileges.len = privs.len + for(var/priv in privs) + if(!findtext(priv, "xml", length(priv)-2)) continue + var/XML/Element/priv_root = xmlRootFromFile("./data/xml/ops/privileges/[priv]") + priv_root = priv_root.Descendant("oppriv") + if(!priv_root) return + var/OpPrivilege/Priv = new() + Priv.name = priv_root.Attribute("name") + Priv.select.name = Priv.name + Priv.monitor = text2num(priv_root.Attribute("monitor")) + Priv.auto_approve = text2num(priv_root.Attribute("approve")) + var/XML/Element/descXML = priv_root.Descendant("desc") + if(descXML) Priv.desc = descXML.Text() + var/XML/Element/executeXML = priv_root.Descendant("execute") + if(executeXML) Priv.execute = executeXML.Text() + var/XML/Element/commandXML = priv_root.Descendant("command") + if(commandXML) Priv.command = commandXML.Text() + var/XML/Element/electXML = priv_root.Descendant("elect") + if(electXML) + Priv.elect = 1 + Priv.elect_by = electXML.Attribute("by") + Priv.or_lower = text2num(electXML.Attribute("orlower")) + if(!Priv.or_lower) Priv.or_higher = 1 + else Priv.or_higher = text2num(electXML.Attribute("orhigher")) + Priv.min_votes = abs(text2num(electXML.Attribute("min_votes"))) + Priv.min_delay = abs(text2num(electXML.Attribute("min_delay"))) + Priv.margin = abs(text2num(electXML.Attribute("margin"))) + else Priv.elect = 0 + op_privileges[Priv.name] = Priv + for(var/p in op_privileges) + if(isnull(p)) op_privileges -= p + + SaveRankXML(OpRank/Rank) + if(!Rank) return + var/XML/Element/mainXML = new("xml") + var/XML/Element/rankXML = new("oprank") + mainXML.AddChild(rankXML) + var/list/rank_attributes = list("name"=Rank.name,"pos"="[Rank.pos]","color"=Rank.color) + if(Rank.monitor) rank_attributes["monitor"] = "1" + if(Rank.auto_approve) rank_attributes["approve"] = "1" + rankXML.setAttributes(rank_attributes) + var/XML/Element/descXML = new("desc") + rankXML.AddChild(descXML) + descXML.setText(Rank.desc) + var/XML/Element/promoteXML = new("promote") + rankXML.AddChild(promoteXML) + promoteXML.setText(Rank.promote) + var/XML/Element/demoteXML = new("demote") + rankXML.AddChild(demoteXML) + demoteXML.setText(Rank.demote) + if(Rank.temp) + var/XML/Element/tempXML = new("temp") + rankXML.AddChild(tempXML) + tempXML.setAttribute("expires",Rank.expires) + if(Rank.elect) + var/XML/Element/electXML = new("elect") + rankXML.AddChild(electXML) + electXML.setAttribute("by", Rank.elect_by) + if(Rank.or_higher) + electXML.setAttribute("orhigher", "1") + electXML.setAttribute("max", Rank.max_elect) + var/XML/Element/privsXML = new("privileges") + rankXML.AddChild(privsXML) + for(var/priv in Rank.privs) + var/XML/Element/privXML = new("privilege") + privsXML.AddChild(privXML) + privXML.setAttribute("name", priv) + mainXML.WriteToFile("./data/xml/ops/ranks/[Rank.name].xml") + + diff --git a/code/models/channel.dm b/code/models/channel.dm index bff59e4..19bb94e 100644 --- a/code/models/channel.dm +++ b/code/models/channel.dm @@ -1,768 +1,764 @@ -Channel - var - founder - name - publicity - desc - topic - pass - locked - telnet_pass - telnet_attempts - QOTD - SuperNode - MaxNodes - - // spam controls - spam_control =1 - spam_limit = 3 - flood_limit = 3 - smileys_limit = 10 - max_msgs = 3 - min_delay = 20 - - room_desc = "An average looking room." - room_desc_size - - Bot - chanbot - list - chatters - players - painters - operators - op_ranks - op_privileges - op_actions - mute - banned - nodes - ballots - showcodes = list() - - filtered_words = list( "fuck" = "fudge", - "shit" = "dung", - " ass" = "donkey", - " asshole"= "donkeyhole", - "penis" = "pencil", - "vagina" = "kitty", - "pussy" = "kitty", - " cunt" = "kitty", - "bitch" = "female dog", - "faggot" = "bundle of sticks", - " fag" = "cigarette", - "nigger" = "ignorant person", - "nigga" = "homeslice", - " dick" = "private eye", - " cock" = "rooster", - "cocksuck"= "milkdrink") - - New(params[]) - if(params) - founder = params["Founder"] - if(!founder) founder = Host.name - name = params["Name"] - publicity = params["Publicity"] - desc = params["Desc"] - topic = params["Topic"] - pass = params["Pass"] - locked = text2num(params["Locked"]) ? 1 : 0 - telnet_pass = params["TelPass"] - telnet_attempts = (text2num(params["TelAtmpts"]) || -1) - SuperNode = text2num(params["SuperNode"]) ? 1 : 0 - MaxNodes = text2num(params["MaxNodes"]) - ..() - chanbot = new /Bot(src) - if(SuperNode) nodes = new() - - proc - LoadOps() - op_ranks = OpMan.op_ranks - var/savefile/S = new("./data/saves/channels/[ckey(name)].sav") - var/list/ops = null - S["operators"] >> ops - if(ops) - operators = listOpen(operators) - for(var/Name in ops) - var/rankIndex = ops[Name] - var/OpRank/Rank = op_ranks[rankIndex] - operators[ckey(Name)] = new/Op(Name, Rank) - - Join(mob/chatter/C) - if(!C || !C.client) - del C - return - - if(C.Chan == src) return - C.Chan = src - winclone(C, "channel", ckey(name)) - winclone(C, "who", "[ckey(name)].who") - winclone(C, "chat", "[ckey(name)].chat") - var/window = ckey(name) - winset(C, null, "[window].default_input.is-default=true;\ - [window].chat.default_output.is-default=true;\ - [window].chat.default_output.is-disabled=false;\ - [window].topic_label.text='[TextMan.escapeQuotes(topic)]';\ - [window].child.left=[window].chat;\ - [window].child.right=[window].who;\ - default.size=[C.winsize];\ - default.can-resize=true;\ - default.title='[name] - Chatters';\ - default.menu=menu;\ - default.child.pos=0,0;\ - default.child.size=[C.winsize];\ - default.child.left=[ckey(name)];") -/* winset(C, "[ckey(name)].default_input", "is-default=true;") - winset(C, "[ckey(name)].chat.default_output", "is-default=true;is-disabled=false.") - winset(C, "[ckey(name)].topic_label", "text='[TextMan.escapeQuotes(topic)]';") - winset(C, "[ckey(name)].child", "left=[ckey(name)].chat; right=[ckey(name)].who") - winset(C, "default", "size=[C.winsize];can-resize=true;title='[name] - Chatters';menu=menu;") - winset(C, "default.child", "pos=0,0;size=[C.winsize];left=[ckey(name)];") -*/ - - if(C.ckey in banned) - C << output("Sorry, you are banned from this channel.", "[ckey(name)].chat.default_output") - C << output("Connection closed.", "[ckey(name)].chat.default_output") - del C - return - - - if(Host == C) winset(C, "default", "menu=host") - - for(var/p in typesof(/Player/proc)-/Player/proc) - C.verbs += p - - if(C.ckey in operators) - if(C.telnet) - operators -= C.ckey - else - var/Op/O = operators[C.ckey] - for(var/priv in O.privileges) - var/OpPrivilege/P = OpMan.op_privileges[priv] - C.verbs += text2path("/Operator/proc/[P.command]") - - if(!C.telnet && winget(C, "[ckey(name)].default_input", "is-disabled") == "true") - // Returning from a kick/ban - var/size = winget(C, "[ckey(name)].child", "size") - var/X = copytext(size, 1, findtext(size,"x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1)) - 44 - winset(C, null, "[window].toggle_quickbar.is-visible=true;\ - [window].set.is-visible=true;\ - [window].help.is-visible=true;\ - [window].default_input.is-disabled=false;\ - [window].child.size=[X]x[Y];\ - [window].child.pos=0,0;") - C.ToggleQuickBar(1) - - if(!C.quickbar) - C.quickbar = TRUE - C.ToggleQuickBar(1) -// if(Host == C) winset(C, "host.quickbar_toggle", "is-checked=false;") -// else winset(C, "menu.quickbar_toggle", "is-checked=false;") - - if(!C.showwho) - C.showwho = TRUE - C.ToggleWho(1) - if(Host == C) - winset(C, "host.who_toggle", "is-checked=false;") - else - winset(C, "menu.who_toggle", "is-checked=false;") - - if(!C.showtopic) - C.showtopic = TRUE - C.ToggleTopic(1) - if(Host == C) - winset(C, "host.topic_toggle", "is-checked=false;") - else - winset(C, "menu.topic_toggle", "is-checked=false;") - - if(C.swaped_panes) - C.swaped_panes = FALSE - C.SwapPanes(1) - - winshow(C, ckey(name), 1) - - winset(C, "[ckey(C.Chan.name)].chat.default_output", "style='[TextMan.escapeQuotes(C.default_output_style)]';max-lines='[C.max_output]';") - if(C.show_title) - if(C.show_colors) - C << output({"[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] -[world.name] - Created by Xooxerand the BYOND Community -[TextMan.fadetext("Still the greatest chat program on BYOND!", list("102000000","255000000","102000000","000000000","000000255"))] -Source available on the Chatters Repository. -Copyright � 2008 Andrew "Xooxer" Arnold -[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] -- All Rights Reserved - -"}, "[ckey(name)].chat.default_output") - - else - C << output({"########################################## -[world.name] - Created by Xooxerand the BYOND Community -Still the greatest chat program on BYOND! -Source available on the Chatters Repository. -Copyright � 2008 Andrew "Xooxer" Arnold -########################################## -- All Rights Reserved - -"}, "[ckey(name)].chat.default_output") - - if(C.show_welcome) - C << output("[time2text(world.realtime+C.time_offset, list2text(C.long_date_format))]\nWelcome, [C.name]!\n", "[ckey(name)].chat.default_output") - - if(C.show_motd) NetMan.MOTD(C) - - if(C.show_qotd) TextMan.QOTD(C) - - if(!chatters) chatters = new() - chatters += C - chatters = SortWho(chatters) - - UpdateWho() - - world.status = "[Home.name] founded by [Home.founder] - [Home.chatters.len] chatter\s" - - MapMan.Join(C) - - winset(C, "[ckey(Home.name)].default_input", "text='> ';focus=true;") - - chanbot.Say("[C.name] has joined [name]") - chanbot.Say("You have joined [name] founded by [founder]",C) - chanbot.Say("[topic]",C) - if(!Home.ismute(C)) EventMan.Parse(C, C.onJoin) - NetMan.Report("join", C.name) - - Quit(mob/chatter/C) - if(!C) - for(var/i=1 to chatters.len) - if(!chatters[i]) chatters -= chatters[i] - return - UpdateWho() - - if(C.ckey in operators) - var/Op/O = operators[C.ckey] - if(O.Rank.temp) operators -= C.ckey - - if(!Home.ismute(C)) EventMan.Parse(C, C.onQuit) - C.Chan = null - - if(chatters) chatters -= C - if(!chatters.len) chatters = null - - UpdateWho() - - chanbot.Say("[C.name] has quit [name]") - NetMan.Report("quit", C.name) - - if(C && ChatMan.istelnet(C.key)) - C.Logout() - - UpdateWho() - - //telnet update who - var chatter_array[] = list() - for(var/mob/chatter/C in chatters) - chatter_array += "[dd_replacetext(C.name, " ", "+")][C.afk ? "~" : ""]" - var display = dd_list2text(chatter_array, ",") - - - for(var/mob/chatter/C in chatters) - - var/active = chatters.len - - if(ChatMan.istelnet(C.key)) - C << ".who [display]" - - else - for(var/i=1, i<=chatters.len, i++) - var/mob/chatter/c = chatters[i] - if(isnull(c)) - chatters -= chatters[i] - continue - if(C.client) winset(C, "[ckey(name)].who.grid", "current-cell=1,[i]") - var/n = c.name - if(c==C) - if(c.afk) - active-- - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:gray;font-weight:bold}'") - c.name += " \[AFK]" - else if(C.ckey in C.Chan.operators) - var/Op/O = C.Chan.operators[C.ckey] - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:[O.Rank.color];font-weight:bold}'") - else - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{font-weight:bold}'") - else - if(!ChatMan.istelnet(c.key) && c.afk) - active-- - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:gray}'") - c.name += " \[AFK]" - else if(c.ckey in C.Chan.operators) - var/Op/O = C.Chan.operators[c.ckey] - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:[O.Rank.color];font-weight:bold}'") - else - if(C.client) winset(C, "[ckey(name)].who.grid", "style=''") - C << output(c, "[ckey(name)].who.grid") - c.name = n - if(C.client) - winset(C, "[ckey(name)].online", "text='[chatters.len] Chatter\s - [active] Active:';") - winset(C, "[ckey(name)].online_left", "text='[chatters.len] Chatter\s - [active] Active:';") - winset(C, "[ckey(name)].who.grid", "cells=1x[chatters.len]") - - SortWho(list/L) - var/list/AFK - for(var/mob/chatter/C in L) - if(C.afk) - if(!AFK) AFK = new - L -= C - AFK += C - if(!L.len) L = null - L = ListMan.atomSort(L) - AFK = ListMan.atomSort(AFK) - if(L && AFK) - return L + AFK - else if(AFK) - return AFK - else - return L - - Say(mob/chatter/C, msg, clean, window) - if(ismute(C)) - chanbot.Say("I'm sorry, but you appear to be muted.",C) - return - - if(length(msg)>512) - var/part2 = copytext(msg, 513) - msg = copytext(msg, 1, 513) - spawn(20) C.Say(part2) - - if(!clean) - msg = TextMan.Sanitize(msg) - chanbot.SpamTimer(C, msg) - - var/raw_msg = msg - msg = TextMan.FilterChat(msg) - - var/smsg = TextMan.ParseSmileys(msg) - smsg = TextMan.ParseLinks(smsg) - - msg = TextMan.ParseLinks(msg) - - if(!window) window = "[ckey(name)].chat.default_output" - - for(var/mob/chatter/c in chatters) - if(c.ignoring(C) & CHAT_IGNORE) continue - var/message - if(!c.filter) - message = raw_msg - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.say_format) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else if(c.filter==1) - message = TextMan.FilterChat(raw_msg,c) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.say_format) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else - message = msg - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) - message = smsg - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.say_format) - if(Parsedmsg) - c << output(Parsedmsg, "[window]") - - - Me(mob/chatter/C, msg, clean, window) - if(ismute(C)) - chanbot.Say("I'm sorry, but you appear to be muted.",C) - return - - if(!clean) msg = TextMan.Sanitize(msg) - - var/raw_msg = msg - msg = TextMan.FilterChat(msg) - - var/smsg = TextMan.ParseSmileys(msg) - smsg = TextMan.ParseLinks(smsg) - - msg = TextMan.ParseLinks(msg) - chanbot.SpamTimer(C, msg) - - if(!window) window = "[ckey(name)].chat.default_output" - - for(var/mob/chatter/c in chatters) - if(!c.ignoring(C)) - var/message - if(!c.filter) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 1) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else if(c.filter==1) - message = TextMan.FilterChat(raw_msg,c) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 1) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else - message = msg - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) - message = smsg - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message, c.me_format, 1) - if(Parsedmsg) - c << output(Parsedmsg, "[window]") - - My(mob/chatter/C, msg, clean, window) - if(ismute(C)) - chanbot.Say("I'm sorry, but you appear to be muted.",C) - return - - if(!clean) msg = TextMan.Sanitize(msg) - - var/raw_msg = msg - msg = TextMan.FilterChat(msg) - - var/smsg = TextMan.ParseSmileys(msg) - smsg = TextMan.ParseLinks(smsg) - - msg = TextMan.ParseLinks(msg) - chanbot.SpamTimer(C, msg) - - if(!window) window = "[ckey(name)].chat.default_output" - - for(var/mob/chatter/c in chatters) - if(!c.ignoring(C)) - var/message - if(!c.filter) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 2) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else if(c.filter==1) - message = TextMan.FilterChat(raw_msg,c) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 2) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else - message = msg - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) - msg = smsg - msg = TextMan.ParseTags(msg, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,msg, c.me_format, 2) - if(Parsedmsg) - c << output(Parsedmsg, "[window]") - - GoAFK(mob/chatter/C, msg) - if(ChatMan.istelnet(C.key)) return - C.afk = TRUE - C.away_at = world.realtime - msg = TextMan.Sanitize(msg) - C.away_reason = msg - - var/raw_msg = msg - msg = TextMan.FilterChat(msg) - - chatters = SortWho(chatters) - UpdateWho() - if(players && players.len) - players = SortWho(players) - GameMan.UpdateWho(src) - if(!ismute(C)) - for(var/mob/chatter/c in chatters) - if(!(c.ignoring(C) & CHAT_IGNORE)) - if(!c.filter) - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [raw_msg])", "[ckey(name)].chat.default_output") - else if(c.filter == 1) - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [TextMan.FilterChat(raw_msg,c)])", "[ckey(name)].chat.default_output") - else - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [msg])", "[ckey(name)].chat.default_output") - C << output("Your activity status is now set to Away From Keyboard.", "[ckey(name)].chat.default_output") - - - ReturnAFK(mob/chatter/C) - if(!C) return - C.afk = FALSE - C.away_reason = null - chatters = SortWho(chatters) - UpdateWho() - if(players && players.len) - players = SortWho(players) - GameMan.UpdateWho(src) - if(!ismute(C)) - for(var/mob/chatter/c in chatters) - if(!(c.ignoring(C) & CHAT_IGNORE)) - c << output("[c.ParseTime()] [C.name] is back from AFK after [round(((world.realtime - C.away_at)/600),1)] minute\s of inactivity.", "[ckey(name)].chat.default_output") - C.away_at = null - C << output("Your activity status is now set to Active Chatter.", "[ckey(name)].chat.default_output") - - - ismute(mob/M) - if(mute && mute.len) - if(istext(M)) - if(ckey(M) in mute) return 1 - else if(ismob(M)) - if(M.ckey in mute) return 1 - else return 1 - - - TallyVotes(OpPrivilege/Priv, OpRank/Rank) - if(!Priv) return - var/list/votes = new() - for(var/Ballot/B in ballots) - if(B.privilege == Priv.name) votes += B - if(votes.len < Priv.min_votes) return - switch(Priv.name) - if("Promote") - if(!Rank) return - var/list/nominations = new() - for(var/Ballot/B in votes) - var/OpRank/R = ChatMan.Rank(B.target) - var/OpRank/TargetRank - if(R == "All") TargetRank = op_ranks[op_ranks.len] - else if(R.pos == 1) return - else TargetRank = op_ranks[R.pos-1] - if(TargetRank == Rank) nominations[B] = TargetRank - if(nominations.len < Priv.min_votes) return - if(Rank.max_elect) - var/i=0 - for(var/op in operators) - var/Op/O = operators[op] - if(O.Rank == Rank) i++ - if(i >= Rank.max_elect) - return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - - var/mob/chatter/T = ChatMan.Get(R) - if(!ismob(T)) T = null - else if(T.telnet) return - var/Op/Operator - var/cKey = ckey(R) - if(ckey(founder) == cKey) return - if(cKey in operators) - Operator = operators[cKey] - var/r = op_ranks.Find(Operator.Rank) - if(r == 1) return - Operator.Rank = op_ranks[r-1] - Operator.privileges = Operator.Rank.privs - Operator.RankSelect.name = Operator.Rank.name - else - if(!op_ranks) return - var/i = op_ranks.len - var/OpRank/newRank = op_ranks[i] - Operator = new(R, newRank) - if(T) - if(T.telnet) return - for(var/priv in Operator.privileges) - var/OpPrivilege/P = OpMan.op_privileges[priv] - T.verbs += text2path("/Operator/proc/[P.command]") - if(Operator.Rank.promote) - chanbot.Say("[T.name] was elected to [Operator.Rank.name].") - UpdateWho() - ChanMan.SaveChan(src) - break - if("Demote") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Demote") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - - var/mob/chatter/T = ChatMan.Get(R) - if(!ismob(T)) T = null - var/cKey = ckey(R) - if(ckey(founder) == cKey) return - if(!(cKey in operators)) return - var/Op/Operator = operators[cKey] - var/r = op_ranks.Find(Operator.Rank) - if(r == op_ranks.len) - operators -= cKey - if(T) chanbot.Say("[T.name] was demoted by election.") - else - Operator.Rank = op_ranks[r+1] - Operator.privileges = Operator.Rank.privs - Operator.RankSelect.name = Operator.Rank.name - if(T) - if(Operator.Rank.demote) - chanbot.Say("[T.name] was demoted to [Operator.Rank.name] by election.") - if(T) - for(var/priv in Operator.privileges) - var/OpPrivilege/P = OpMan.op_privileges[priv] - T.verbs -= text2path("/Operator/proc/[P.command]") - UpdateWho() - ChanMan.SaveChan(src) - break - if("Mute") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Mute") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - if(!mute) mute = new - if(!(ckey(R) in mute)) - chanbot.Say("[R] has been muted by election.") - mute += ckey(R) - ChanMan.SaveChan(src) - break - if("Voice") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Voice") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - if(mute && (ckey(R) in mute)) - mute -= ckey(R) - chanbot.Say("[R] has been voiced by election.") - ChanMan.SaveChan(src) - break - if("Kick") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Kick") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - var/mob/chatter/C = ChatMan.Get(R) - if(!C) return - var/reason = "You were removed by a vote of your peers." - chanbot.Say("[C.name] has been kicked by election.") - - if(!ChatMan.istelnet(C.key)) - // clear the chat window of everything but the output - // to reinforce that they are really out of the program - winset(C, "default", "menu=") - if(C.quickbar) C.ToggleQuickBar(1) - C << output(null, "[ckey(name)].chat.default_output") - winset(C, "[ckey(name)].child", "right=") - winset(C, "[ckey(name)].toggle_quickbar", "is-visible=false") - winset(C, "[ckey(name)].set", "is-visible=false") - winset(C, "[ckey(name)].help", "is-visible=false") - winset(C, "[ckey(name)].default_input", "is-disabled=true") - - var/size = winget(C, "[ckey(name)].child", "size") - var/X = copytext(size, 1, findtext(size,"x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))+36 - winset(C, "[ckey(name)].child", "size=[X]x[Y];pos=0,0") - - C << output("You have been kicked from [name].", "[ckey(name)].chat.default_output") - C << output("Reason: [reason]", "[ckey(name)].chat.default_output") - C << output("Connection closed.", "[ckey(name)].chat.default_output") - - chatters -= C - UpdateWho() - - C.Logout() // omgwtfpwnt - if("Ban") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Ban") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - var/reason = "You were removed by a vote of your peers." - chanbot.Say("[R] has been banned by election.") - - if(!banned) banned = new - - banned += ckey(R) - - var/mob/chatter/C = ChatMan.Get(R) - if(C) - if(!ChatMan.istelnet(C.key)) - // clear the chat window of everything but the output - // to reinforce that they are really out of the program - winset(C, "default", "menu=") - if(C.quickbar) C.ToggleQuickBar(1) - C << output(null, "[ckey(name)].chat.default_output") - winset(C, "[ckey(name)].child", "right=") - winset(C, "[ckey(name)].toggle_quickbar", "is-visible=false") - winset(C, "[ckey(name)].set", "is-visible=false") - winset(C, "[ckey(name)].help", "is-visible=false") - winset(C, "[ckey(name)].default_input", "is-disabled=true") - - var/size = winget(C, "[ckey(name)].child", "size") - var/X = copytext(size, 1, findtext(size,"x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))+44 - winset(C, "[ckey(name)].child", "size=[X]x[Y];pos=0,0") - - C << output("You have been banned from [name]", "[ckey(name)].chat.default_output") - C << output("Reason: [reason]", "[ckey(name)].chat.default_output") - C << output("Connection closed.", "[ckey(name)].chat.default_output") - - chatters -= C - UpdateWho() - - C.Logout() // omgwtfpwnt - ChanMan.SaveChan(src) - if("Unban") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Unban") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - if((ckey(R) in banned)) - chanbot.Say("[R] has been unbanned by election.") - - banned -= ckey(R) - ChanMan.SaveChan(src) - +Channel + var + founder + name + publicity + desc + topic + pass + locked + telnet_pass + telnet_attempts + QOTD + SuperNode + MaxNodes + + // spam controls + spam_control =1 + spam_limit = 3 + flood_limit = 3 + smileys_limit = 10 + max_msgs = 3 + min_delay = 20 + + room_desc = "An average looking room." + room_desc_size + + Bot + chanbot + list + chatters + players + painters + operators + op_ranks + op_privileges + op_actions + mute + banned + nodes + ballots + showcodes = list() + + filtered_words = list( "fuck" = "fudge", + "shit" = "dung", + " ass" = "donkey", + " asshole"= "donkeyhole", + "penis" = "pencil", + "vagina" = "kitty", + "pussy" = "kitty", + " cunt" = "kitty", + "bitch" = "female dog", + "faggot" = "bundle of sticks", + " fag" = "cigarette", + "nigger" = "ignorant person", + "nigga" = "homeslice", + " dick" = "private eye", + " cock" = "rooster", + "cocksuck"= "milkdrink") + + New(params[]) + if(params) + founder = params["Founder"] + if(!founder) founder = Host.name + name = params["Name"] + publicity = params["Publicity"] + desc = params["Desc"] + topic = params["Topic"] + pass = params["Pass"] + locked = text2num(params["Locked"]) ? 1 : 0 + telnet_pass = params["TelPass"] + telnet_attempts = (text2num(params["TelAtmpts"]) || -1) + SuperNode = text2num(params["SuperNode"]) ? 1 : 0 + MaxNodes = text2num(params["MaxNodes"]) + ..() + chanbot = new /Bot(src) + if(SuperNode) nodes = new() + + proc + LoadOps() + op_ranks = OpMan.op_ranks + var/savefile/S = new("./data/saves/channels/[ckey(name)].sav") + var/list/ops = null + S["operators"] >> ops + if(ops) + operators = listOpen(operators) + for(var/Name in ops) + var/rankIndex = ops[Name] + var/OpRank/Rank = op_ranks[rankIndex] + operators[ckey(Name)] = new/Op(Name, Rank) + + Join(mob/chatter/C) + if(!C || !C.client) + del C + return + + if(C.Chan == src) return + C.Chan = src + winclone(C, "channel", ckey(name)) + winclone(C, "who", "[ckey(name)].who") + winclone(C, "chat", "[ckey(name)].chat") + var/window = ckey(name) + winset(C, null, "[window].default_input.is-default=true;\ + [window].chat.default_output.is-default=true;\ + [window].chat.default_output.is-disabled=false;\ + [window].topic_label.text='[TextMan.escapeQuotes(topic)]';\ + [window].child.left=[window].chat;\ + [window].child.right=[window].who;\ + default.size=[C.winsize];\ + default.can-resize=true;\ + default.title='[name] - Chatters';\ + default.menu=menu;\ + default.child.pos=0,0;\ + default.child.size=[C.winsize];\ + default.child.left=[ckey(name)];") +/* winset(C, "[ckey(name)].default_input", "is-default=true;") + winset(C, "[ckey(name)].chat.default_output", "is-default=true;is-disabled=false.") + winset(C, "[ckey(name)].topic_label", "text='[TextMan.escapeQuotes(topic)]';") + winset(C, "[ckey(name)].child", "left=[ckey(name)].chat; right=[ckey(name)].who") + winset(C, "default", "size=[C.winsize];can-resize=true;title='[name] - Chatters';menu=menu;") + winset(C, "default.child", "pos=0,0;size=[C.winsize];left=[ckey(name)];") +*/ + + if(C.ckey in banned) + C << output("Sorry, you are banned from this channel.", "[ckey(name)].chat.default_output") + C << output("Connection closed.", "[ckey(name)].chat.default_output") + del C + return + + + if(Host == C) winset(C, "default", "menu=host") + + for(var/p in typesof(/Player/proc)-/Player/proc) + C.verbs += p + + if(C.ckey in operators) + if(C.telnet) + operators -= C.ckey + else + var/Op/O = operators[C.ckey] + for(var/priv in O.privileges) + var/OpPrivilege/P = OpMan.op_privileges[priv] + C.verbs += text2path("/Operator/proc/[P.command]") + + if(!C.telnet && winget(C, "[ckey(name)].default_input", "is-disabled") == "true") + // Returning from a kick/ban + var/size = winget(C, "[ckey(name)].child", "size") + var/X = copytext(size, 1, findtext(size,"x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1)) - 44 + winset(C, null, "[window].toggle_quickbar.is-visible=true;\ + [window].set.is-visible=true;\ + [window].help.is-visible=true;\ + [window].default_input.is-disabled=false;\ + [window].child.size=[X]x[Y];\ + [window].child.pos=0,0;") + C.ToggleQuickBar(1) + + if(!C.quickbar) + C.quickbar = TRUE + C.ToggleQuickBar(1) +// if(Host == C) winset(C, "host.quickbar_toggle", "is-checked=false;") +// else winset(C, "menu.quickbar_toggle", "is-checked=false;") + + if(!C.showwho) + C.showwho = TRUE + C.ToggleWho(1) + if(Host == C) + winset(C, "host.who_toggle", "is-checked=false;") + else + winset(C, "menu.who_toggle", "is-checked=false;") + + if(!C.showtopic) + C.showtopic = TRUE + C.ToggleTopic(1) + if(Host == C) + winset(C, "host.topic_toggle", "is-checked=false;") + else + winset(C, "menu.topic_toggle", "is-checked=false;") + + if(C.swaped_panes) + C.swaped_panes = FALSE + C.SwapPanes(1) + + winshow(C, ckey(name), 1) + + winset(C, "[ckey(C.Chan.name)].chat.default_output", "style='[TextMan.escapeQuotes(C.default_output_style)]';max-lines='[C.max_output]';") + if(C.show_title) + if(C.show_colors) + C << output({"[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] +[world.name] - Created by Xooxerand the BYOND Community +[TextMan.fadetext("Still the greatest chat program on BYOND!", list("102000000","255000000","102000000","000000000","000000255"))] +Source available on the Chatters Repository. +Copyright � 2008 Andrew "Xooxer" Arnold +[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] +- All Rights Reserved - +"}, "[ckey(name)].chat.default_output") + + else + C << output({"########################################## +[world.name] - Created by Xooxerand the BYOND Community +Still the greatest chat program on BYOND! +Source available on the Chatters Repository. +Copyright � 2008 Andrew "Xooxer" Arnold +########################################## +- All Rights Reserved - +"}, "[ckey(name)].chat.default_output") + + if(C.show_welcome) + C << output("[time2text(world.realtime+C.time_offset, list2text(C.long_date_format))]\nWelcome, [C.name]!\n", "[ckey(name)].chat.default_output") + + if(C.show_qotd) TextMan.QOTD(C) + + if(!chatters) chatters = new() + chatters += C + chatters = SortWho(chatters) + + UpdateWho() + + world.status = "[Home.name] founded by [Home.founder] - [Home.chatters.len] chatter\s" + + MapMan.Join(C) + + winset(C, "[ckey(Home.name)].default_input", "text='> ';focus=true;") + + chanbot.Say("[C.name] has joined [name]") + chanbot.Say("You have joined [name] founded by [founder]",C) + chanbot.Say("[topic]",C) + if(!Home.ismute(C)) EventMan.Parse(C, C.onJoin) + + Quit(mob/chatter/C) + if(!C) + for(var/i=1 to chatters.len) + if(!chatters[i]) chatters -= chatters[i] + return + UpdateWho() + + if(C.ckey in operators) + var/Op/O = operators[C.ckey] + if(O.Rank.temp) operators -= C.ckey + + if(!Home.ismute(C)) EventMan.Parse(C, C.onQuit) + C.Chan = null + + if(chatters) chatters -= C + if(!chatters.len) chatters = null + + UpdateWho() + + chanbot.Say("[C.name] has quit [name]") + + if(C && ChatMan.istelnet(C.key)) + C.Logout() + + UpdateWho() + + //telnet update who + var chatter_array[] = list() + for(var/mob/chatter/C in chatters) + chatter_array += "[dd_replacetext(C.name, " ", "+")][C.afk ? "~" : ""]" + var display = dd_list2text(chatter_array, ",") + + + for(var/mob/chatter/C in chatters) + + var/active = chatters.len + + if(ChatMan.istelnet(C.key)) + C << ".who [display]" + + else + for(var/i=1, i<=chatters.len, i++) + var/mob/chatter/c = chatters[i] + if(isnull(c)) + chatters -= chatters[i] + continue + if(C.client) winset(C, "[ckey(name)].who.grid", "current-cell=1,[i]") + var/n = c.name + if(c==C) + if(c.afk) + active-- + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:gray;font-weight:bold}'") + c.name += " \[AFK]" + else if(C.ckey in C.Chan.operators) + var/Op/O = C.Chan.operators[C.ckey] + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:[O.Rank.color];font-weight:bold}'") + else + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{font-weight:bold}'") + else + if(!ChatMan.istelnet(c.key) && c.afk) + active-- + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:gray}'") + c.name += " \[AFK]" + else if(c.ckey in C.Chan.operators) + var/Op/O = C.Chan.operators[c.ckey] + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:[O.Rank.color];font-weight:bold}'") + else + if(C.client) winset(C, "[ckey(name)].who.grid", "style=''") + C << output(c, "[ckey(name)].who.grid") + c.name = n + if(C.client) + winset(C, "[ckey(name)].online", "text='[chatters.len] Chatter\s - [active] Active:';") + winset(C, "[ckey(name)].online_left", "text='[chatters.len] Chatter\s - [active] Active:';") + winset(C, "[ckey(name)].who.grid", "cells=1x[chatters.len]") + + SortWho(list/L) + var/list/AFK + for(var/mob/chatter/C in L) + if(C.afk) + if(!AFK) AFK = new + L -= C + AFK += C + if(!L.len) L = null + L = ListMan.atomSort(L) + AFK = ListMan.atomSort(AFK) + if(L && AFK) + return L + AFK + else if(AFK) + return AFK + else + return L + + Say(mob/chatter/C, msg, clean, window) + if(ismute(C)) + chanbot.Say("I'm sorry, but you appear to be muted.",C) + return + + if(length(msg)>512) + var/part2 = copytext(msg, 513) + msg = copytext(msg, 1, 513) + spawn(20) C.Say(part2) + + if(!clean) + msg = TextMan.Sanitize(msg) + chanbot.SpamTimer(C, msg) + + var/raw_msg = msg + msg = TextMan.FilterChat(msg) + + var/smsg = TextMan.ParseSmileys(msg) + smsg = TextMan.ParseLinks(smsg) + + msg = TextMan.ParseLinks(msg) + + if(!window) window = "[ckey(name)].chat.default_output" + + for(var/mob/chatter/c in chatters) + if(c.ignoring(C) & CHAT_IGNORE) continue + var/message + if(!c.filter) + message = raw_msg + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.say_format) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else if(c.filter==1) + message = TextMan.FilterChat(raw_msg,c) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.say_format) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else + message = msg + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) + message = smsg + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.say_format) + if(Parsedmsg) + c << output(Parsedmsg, "[window]") + + + Me(mob/chatter/C, msg, clean, window) + if(ismute(C)) + chanbot.Say("I'm sorry, but you appear to be muted.",C) + return + + if(!clean) msg = TextMan.Sanitize(msg) + + var/raw_msg = msg + msg = TextMan.FilterChat(msg) + + var/smsg = TextMan.ParseSmileys(msg) + smsg = TextMan.ParseLinks(smsg) + + msg = TextMan.ParseLinks(msg) + chanbot.SpamTimer(C, msg) + + if(!window) window = "[ckey(name)].chat.default_output" + + for(var/mob/chatter/c in chatters) + if(!c.ignoring(C)) + var/message + if(!c.filter) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 1) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else if(c.filter==1) + message = TextMan.FilterChat(raw_msg,c) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 1) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else + message = msg + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) + message = smsg + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message, c.me_format, 1) + if(Parsedmsg) + c << output(Parsedmsg, "[window]") + + My(mob/chatter/C, msg, clean, window) + if(ismute(C)) + chanbot.Say("I'm sorry, but you appear to be muted.",C) + return + + if(!clean) msg = TextMan.Sanitize(msg) + + var/raw_msg = msg + msg = TextMan.FilterChat(msg) + + var/smsg = TextMan.ParseSmileys(msg) + smsg = TextMan.ParseLinks(smsg) + + msg = TextMan.ParseLinks(msg) + chanbot.SpamTimer(C, msg) + + if(!window) window = "[ckey(name)].chat.default_output" + + for(var/mob/chatter/c in chatters) + if(!c.ignoring(C)) + var/message + if(!c.filter) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 2) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else if(c.filter==1) + message = TextMan.FilterChat(raw_msg,c) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 2) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else + message = msg + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) + msg = smsg + msg = TextMan.ParseTags(msg, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,msg, c.me_format, 2) + if(Parsedmsg) + c << output(Parsedmsg, "[window]") + + GoAFK(mob/chatter/C, msg) + if(ChatMan.istelnet(C.key)) return + C.afk = TRUE + C.away_at = world.realtime + msg = TextMan.Sanitize(msg) + C.away_reason = msg + + var/raw_msg = msg + msg = TextMan.FilterChat(msg) + + chatters = SortWho(chatters) + UpdateWho() + if(players && players.len) + players = SortWho(players) + GameMan.UpdateWho(src) + if(!ismute(C)) + for(var/mob/chatter/c in chatters) + if(!(c.ignoring(C) & CHAT_IGNORE)) + if(!c.filter) + c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [raw_msg])", "[ckey(name)].chat.default_output") + else if(c.filter == 1) + c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [TextMan.FilterChat(raw_msg,c)])", "[ckey(name)].chat.default_output") + else + c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [msg])", "[ckey(name)].chat.default_output") + C << output("Your activity status is now set to Away From Keyboard.", "[ckey(name)].chat.default_output") + + + ReturnAFK(mob/chatter/C) + if(!C) return + C.afk = FALSE + C.away_reason = null + chatters = SortWho(chatters) + UpdateWho() + if(players && players.len) + players = SortWho(players) + GameMan.UpdateWho(src) + if(!ismute(C)) + for(var/mob/chatter/c in chatters) + if(!(c.ignoring(C) & CHAT_IGNORE)) + c << output("[c.ParseTime()] [C.name] is back from AFK after [round(((world.realtime - C.away_at)/600),1)] minute\s of inactivity.", "[ckey(name)].chat.default_output") + C.away_at = null + C << output("Your activity status is now set to Active Chatter.", "[ckey(name)].chat.default_output") + + + ismute(mob/M) + if(mute && mute.len) + if(istext(M)) + if(ckey(M) in mute) return 1 + else if(ismob(M)) + if(M.ckey in mute) return 1 + else return 1 + + + TallyVotes(OpPrivilege/Priv, OpRank/Rank) + if(!Priv) return + var/list/votes = new() + for(var/Ballot/B in ballots) + if(B.privilege == Priv.name) votes += B + if(votes.len < Priv.min_votes) return + switch(Priv.name) + if("Promote") + if(!Rank) return + var/list/nominations = new() + for(var/Ballot/B in votes) + var/OpRank/R = ChatMan.Rank(B.target) + var/OpRank/TargetRank + if(R == "All") TargetRank = op_ranks[op_ranks.len] + else if(R.pos == 1) return + else TargetRank = op_ranks[R.pos-1] + if(TargetRank == Rank) nominations[B] = TargetRank + if(nominations.len < Priv.min_votes) return + if(Rank.max_elect) + var/i=0 + for(var/op in operators) + var/Op/O = operators[op] + if(O.Rank == Rank) i++ + if(i >= Rank.max_elect) + return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + + var/mob/chatter/T = ChatMan.Get(R) + if(!ismob(T)) T = null + else if(T.telnet) return + var/Op/Operator + var/cKey = ckey(R) + if(ckey(founder) == cKey) return + if(cKey in operators) + Operator = operators[cKey] + var/r = op_ranks.Find(Operator.Rank) + if(r == 1) return + Operator.Rank = op_ranks[r-1] + Operator.privileges = Operator.Rank.privs + Operator.RankSelect.name = Operator.Rank.name + else + if(!op_ranks) return + var/i = op_ranks.len + var/OpRank/newRank = op_ranks[i] + Operator = new(R, newRank) + if(T) + if(T.telnet) return + for(var/priv in Operator.privileges) + var/OpPrivilege/P = OpMan.op_privileges[priv] + T.verbs += text2path("/Operator/proc/[P.command]") + if(Operator.Rank.promote) + chanbot.Say("[T.name] was elected to [Operator.Rank.name].") + UpdateWho() + ChanMan.SaveChan(src) + break + if("Demote") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Demote") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + + var/mob/chatter/T = ChatMan.Get(R) + if(!ismob(T)) T = null + var/cKey = ckey(R) + if(ckey(founder) == cKey) return + if(!(cKey in operators)) return + var/Op/Operator = operators[cKey] + var/r = op_ranks.Find(Operator.Rank) + if(r == op_ranks.len) + operators -= cKey + if(T) chanbot.Say("[T.name] was demoted by election.") + else + Operator.Rank = op_ranks[r+1] + Operator.privileges = Operator.Rank.privs + Operator.RankSelect.name = Operator.Rank.name + if(T) + if(Operator.Rank.demote) + chanbot.Say("[T.name] was demoted to [Operator.Rank.name] by election.") + if(T) + for(var/priv in Operator.privileges) + var/OpPrivilege/P = OpMan.op_privileges[priv] + T.verbs -= text2path("/Operator/proc/[P.command]") + UpdateWho() + ChanMan.SaveChan(src) + break + if("Mute") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Mute") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + if(!mute) mute = new + if(!(ckey(R) in mute)) + chanbot.Say("[R] has been muted by election.") + mute += ckey(R) + ChanMan.SaveChan(src) + break + if("Voice") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Voice") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + if(mute && (ckey(R) in mute)) + mute -= ckey(R) + chanbot.Say("[R] has been voiced by election.") + ChanMan.SaveChan(src) + break + if("Kick") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Kick") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + var/mob/chatter/C = ChatMan.Get(R) + if(!C) return + var/reason = "You were removed by a vote of your peers." + chanbot.Say("[C.name] has been kicked by election.") + + if(!ChatMan.istelnet(C.key)) + // clear the chat window of everything but the output + // to reinforce that they are really out of the program + winset(C, "default", "menu=") + if(C.quickbar) C.ToggleQuickBar(1) + C << output(null, "[ckey(name)].chat.default_output") + winset(C, "[ckey(name)].child", "right=") + winset(C, "[ckey(name)].toggle_quickbar", "is-visible=false") + winset(C, "[ckey(name)].set", "is-visible=false") + winset(C, "[ckey(name)].help", "is-visible=false") + winset(C, "[ckey(name)].default_input", "is-disabled=true") + + var/size = winget(C, "[ckey(name)].child", "size") + var/X = copytext(size, 1, findtext(size,"x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))+36 + winset(C, "[ckey(name)].child", "size=[X]x[Y];pos=0,0") + + C << output("You have been kicked from [name].", "[ckey(name)].chat.default_output") + C << output("Reason: [reason]", "[ckey(name)].chat.default_output") + C << output("Connection closed.", "[ckey(name)].chat.default_output") + + chatters -= C + UpdateWho() + + C.Logout() // omgwtfpwnt + if("Ban") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Ban") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + var/reason = "You were removed by a vote of your peers." + chanbot.Say("[R] has been banned by election.") + + if(!banned) banned = new + + banned += ckey(R) + + var/mob/chatter/C = ChatMan.Get(R) + if(C) + if(!ChatMan.istelnet(C.key)) + // clear the chat window of everything but the output + // to reinforce that they are really out of the program + winset(C, "default", "menu=") + if(C.quickbar) C.ToggleQuickBar(1) + C << output(null, "[ckey(name)].chat.default_output") + winset(C, "[ckey(name)].child", "right=") + winset(C, "[ckey(name)].toggle_quickbar", "is-visible=false") + winset(C, "[ckey(name)].set", "is-visible=false") + winset(C, "[ckey(name)].help", "is-visible=false") + winset(C, "[ckey(name)].default_input", "is-disabled=true") + + var/size = winget(C, "[ckey(name)].child", "size") + var/X = copytext(size, 1, findtext(size,"x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))+44 + winset(C, "[ckey(name)].child", "size=[X]x[Y];pos=0,0") + + C << output("You have been banned from [name]", "[ckey(name)].chat.default_output") + C << output("Reason: [reason]", "[ckey(name)].chat.default_output") + C << output("Connection closed.", "[ckey(name)].chat.default_output") + + chatters -= C + UpdateWho() + + C.Logout() // omgwtfpwnt + ChanMan.SaveChan(src) + if("Unban") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Unban") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + if((ckey(R) in banned)) + chanbot.Say("[R] has been unbanned by election.") + + banned -= ckey(R) + ChanMan.SaveChan(src) + diff --git a/code/models/chatter/_main.dm b/code/models/chatter/_main.dm index 522b065..5ed3370 100644 --- a/code/models/chatter/_main.dm +++ b/code/models/chatter/_main.dm @@ -1,198 +1,194 @@ - -mob - chatter - var - name_color - text_color - background - fade_name - show_colors = TRUE - - _24hr_time = TRUE - time_offset = 0 - auto_away = 15 - auto_reason = "I have gone auto-AFK." - - default_output_style = ".code{color:#000000}.ident {color:#606}.comment {color:#666}.preproc {color:#008000}.keyword {color:#00f}.string {color:#0096b4}.number {color:#800000}body {text-indent: -8px;}" - ticker = 0 - - show_smileys = TRUE - show_images = TRUE - forced_punctuation = FALSE - - picture - age = "No age given." - location = "No location provided." - description = "No description available." - interests = "No interests supplied." - - onJoin = "me(\"enters the channel.\")" - onQuit = "me(\"exits the channel.\")" - - filter = 2 - replacement_word = "" - - quickbar = TRUE - showwho = TRUE - showtopic = TRUE - swaped_panes = FALSE - show_title = TRUE - show_welcome = TRUE - show_motd = TRUE - show_qotd = TRUE - show_highlight = TRUE - - clear_on_reboot = FALSE - max_output = 1000 - - telnet_pass - - winsize = "640x480" - - im_sounds = TRUE - im_volume = 100 - got_msg_snd = "./data/sndfx/mallert 010.wav" - snt_msg_snd = "./data/sndfx/mallert 009.wav" - - // Added to notify a user if his name has been said in conversation. - // - name_notify = FALSE - - tmp/Painter/Painter - - tmp/OpRank/RankSelect - tmp/OpPrivilege/PrivSelectLeft - tmp/OpPrivilege/PrivSelectRight - - tmp/obj/OpNameSelect/NameSelect - tmp/game_color - tmp/afk = FALSE - tmp/telnet = FALSE - tmp/away_at = 0 - tmp/away_reason - tmp/spam_num - tmp/flood_flag - tmp/flood_num - tmp/list/msgs - tmp/Channel/Chan - tmp/ColorView/CV - tmp/MessageHandler/MsgHand - - list - ignoring - fade_colors = list("#000000") - - time_format = list("\[","hh",":","mm",":","ss","]") - date_format = list("MMM"," ","MM",", `","YY") - long_date_format = list("Day",", ","Month"," ","DD",", ","YYYY") - say_format = list("$ts", " ","$name",": ","$msg") - rpsay_format = list("$ts", " ","$name"," ","$rp",": ","$msg") - me_format = list("$ts", " ", "$name", " ", "$msg") - - filtered_words - - tmp/msgHandlers - tmp/Tags = list("\[b]" = "\[/b]", - "\[i]" = "\[/i]", - "\[u]" = "\[/u]", - "\[s]" = "\[/s]", - "\[code]" = "\[/code]") - tmp/Smileys = list(":)",":(",":D","<:(",">:(",">:D") - tmp/Colors = list("#C00","#0C0","#00C","#CC0","#C0C","#0CC","#000") - - - New() - ..() - MsgHand = new(src) - CV = new(src) - - Login() - ..() - - if(!ChatMan.istelnet(key)) - src << output("Name:", "pub_chans.grid:1,1") - src << output("Founder:", "pub_chans.grid:2,1") - src << output("Description:", "pub_chans.grid:3,1") - src << output("Chatters:", "pub_chans.grid:4,1") - if(winget(src, "default", "is-maximized")=="true") - winset(src, "default", "is-maximized=false;size='484x244'") - else - winset(src, "default", "size='484x244';") - if(!fade_name) - if(name_color) - fade_name = "[name]" - else - fade_name = name - if(!gender) gender = client.gender - if(!NetMan.HostCheck(client)) - if(Home) - ChanMan.Join(src, Home) - else - winset(src, "default.output", "is-visible=true") - winset(src, "default.child", "is-visible=false") - src << output("Please wait while your host configures the channel...", "default.output") - while(!Home) sleep(10) - winset(src, "default.output", "is-visible=false") - winset(src, "default.child", "is-visible=true") - ChanMan.Join(src, Home) - else if(Home) - ChanMan.Join(src, Home) - for(var/obj/help/topic/T in world) - src << output("[T.name]", "topics_grid.output") - spawn() Ticker() - - // Telnet users login differently - else - //Set options suited for telnet. - telnet = TRUE - show_colors = FALSE - show_smileys = FALSE - show_highlight = FALSE - onJoin = "" - onQuit = "" - - if(!fade_name) fade_name = name - if(!gender) gender = client.gender - if(!NetMan.HostCheck(client)) - if(Home) ChanMan.Join(src, Home) - - Stat() - ..() - if(src.telnet) return - if(auto_away && (auto_away < client.inactivity/600) && !afk) afk(auto_reason) - if(Chan && Chan.players && Chan.players.len) - if(src in Chan.players) - if(winget(src,"games", "is-visible")=="false") - Chan.players -= src - Chan.players = Chan.SortWho(Chan.players) - GameMan.UpdateWho(Chan) - if(afk) ReturnAFK() - if(src.msgHandlers && src.msgHandlers.len) - for(var/msgHandler in msgHandlers) - var/open = winget(src, "cim_[msgHandler]", "is-visible") - if(open == "false") - src << output(null, "cim_[msgHandler].output") - winset(src, "cim_[msgHandler].input", "text=") - for(var/i=1,i<=3,i++) - winset(src, "cim_[msgHandler].tag[i]", "is-checked=false") - for(var/i=1,i<=7,i++) - winset(src, "cim_[msgHandler].color[i]", "is-checked=false;text=") - var/C = src.Colors[i] - src.Colors[C] = null - var/Messenger/M = msgHandlers[msgHandler] - msgHandlers -= msgHandler - del(M) - if(src.Painter) - var/open = winget(src, "map", "is-visible") - if(open == "false") - del(src.Painter) - - Click() - call(usr, "LookAt")(key) - - - Logout() - if(Console && Chan) ChanMan.Quit(src, Chan) - ..() - sleep(50) + +mob + chatter + var + name_color + text_color + background + fade_name + show_colors = TRUE + + _24hr_time = TRUE + time_offset = 0 + auto_away = 15 + auto_reason = "I have gone auto-AFK." + + default_output_style = ".code{color:#000000}.ident {color:#606}.comment {color:#666}.preproc {color:#008000}.keyword {color:#00f}.string {color:#0096b4}.number {color:#800000}body {text-indent: -8px;}" + ticker = 0 + + show_smileys = TRUE + show_images = TRUE + forced_punctuation = FALSE + + picture + age = "No age given." + location = "No location provided." + description = "No description available." + interests = "No interests supplied." + + onJoin = "me(\"enters the channel.\")" + onQuit = "me(\"exits the channel.\")" + + filter = 2 + replacement_word = "" + + quickbar = TRUE + showwho = TRUE + showtopic = TRUE + swaped_panes = FALSE + show_title = TRUE + show_welcome = TRUE + show_motd = TRUE + show_qotd = TRUE + show_highlight = TRUE + + clear_on_reboot = FALSE + max_output = 1000 + + telnet_pass + + winsize = "640x480" + + im_sounds = TRUE + im_volume = 100 + got_msg_snd = "./data/sndfx/mallert 010.wav" + snt_msg_snd = "./data/sndfx/mallert 009.wav" + + // Added to notify a user if his name has been said in conversation. + // + name_notify = FALSE + + tmp/Painter/Painter + + tmp/OpRank/RankSelect + tmp/OpPrivilege/PrivSelectLeft + tmp/OpPrivilege/PrivSelectRight + + tmp/obj/OpNameSelect/NameSelect + tmp/game_color + tmp/afk = FALSE + tmp/telnet = FALSE + tmp/away_at = 0 + tmp/away_reason + tmp/spam_num + tmp/flood_flag + tmp/flood_num + tmp/list/msgs + tmp/Channel/Chan + tmp/ColorView/CV + tmp/MessageHandler/MsgHand + + list + ignoring + fade_colors = list("#000000") + + time_format = list("\[","hh",":","mm",":","ss","]") + date_format = list("MMM"," ","MM",", `","YY") + long_date_format = list("Day",", ","Month"," ","DD",", ","YYYY") + say_format = list("$ts", " ","$name",": ","$msg") + rpsay_format = list("$ts", " ","$name"," ","$rp",": ","$msg") + me_format = list("$ts", " ", "$name", " ", "$msg") + + filtered_words + + tmp/msgHandlers + tmp/Tags = list("\[b]" = "\[/b]", + "\[i]" = "\[/i]", + "\[u]" = "\[/u]", + "\[s]" = "\[/s]", + "\[code]" = "\[/code]") + tmp/Smileys = list(":)",":(",":D","<:(",">:(",">:D") + tmp/Colors = list("#C00","#0C0","#00C","#CC0","#C0C","#0CC","#000") + + + New() + ..() + MsgHand = new(src) + CV = new(src) + + Login() + ..() + + if(!ChatMan.istelnet(key)) + src << output("Name:", "pub_chans.grid:1,1") + src << output("Founder:", "pub_chans.grid:2,1") + src << output("Description:", "pub_chans.grid:3,1") + src << output("Chatters:", "pub_chans.grid:4,1") + if(winget(src, "default", "is-maximized")=="true") + winset(src, "default", "is-maximized=false;size='484x244'") + else + winset(src, "default", "size='484x244';") + if(!fade_name) + if(name_color) + fade_name = "[name]" + else + fade_name = name + if(!gender) gender = client.gender + if(Home) + ChanMan.Join(src, Home) + else + winset(src, "default.output", "is-visible=true") + winset(src, "default.child", "is-visible=false") + src << output("Please wait while your host configures the channel...", "default.output") + while(!Home) sleep(10) + winset(src, "default.output", "is-visible=false") + winset(src, "default.child", "is-visible=true") + ChanMan.Join(src, Home) + for(var/obj/help/topic/T in world) + src << output("[T.name]", "topics_grid.output") + spawn() Ticker() + + // Telnet users login differently + else + //Set options suited for telnet. + telnet = TRUE + show_colors = FALSE + show_smileys = FALSE + show_highlight = FALSE + onJoin = "" + onQuit = "" + + if(!fade_name) fade_name = name + if(!gender) gender = client.gender + if(Home) ChanMan.Join(src, Home) + + Stat() + ..() + if(src.telnet) return + if(auto_away && (auto_away < client.inactivity/600) && !afk) afk(auto_reason) + if(Chan && Chan.players && Chan.players.len) + if(src in Chan.players) + if(winget(src,"games", "is-visible")=="false") + Chan.players -= src + Chan.players = Chan.SortWho(Chan.players) + GameMan.UpdateWho(Chan) + if(afk) ReturnAFK() + if(src.msgHandlers && src.msgHandlers.len) + for(var/msgHandler in msgHandlers) + var/open = winget(src, "cim_[msgHandler]", "is-visible") + if(open == "false") + src << output(null, "cim_[msgHandler].output") + winset(src, "cim_[msgHandler].input", "text=") + for(var/i=1,i<=3,i++) + winset(src, "cim_[msgHandler].tag[i]", "is-checked=false") + for(var/i=1,i<=7,i++) + winset(src, "cim_[msgHandler].color[i]", "is-checked=false;text=") + var/C = src.Colors[i] + src.Colors[C] = null + var/Messenger/M = msgHandlers[msgHandler] + msgHandlers -= msgHandler + del(M) + if(src.Painter) + var/open = winget(src, "map", "is-visible") + if(open == "false") + del(src.Painter) + + Click() + call(usr, "LookAt")(key) + + + Logout() + if(Console && Chan) ChanMan.Quit(src, Chan) + ..() + sleep(50) if(!client) del(src) \ No newline at end of file diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 0113ae2..083e9c9 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -1,599 +1,598 @@ -mob - chatter - verb - // Temporary, toggle name notify. - Notify() - name_notify = !name_notify - - src << "You will no[name_notify ? "w" : "t"] be notified if your name is said." - - - Vote(ballot as text|null) - var/OpRank/Rank = ChatMan.Rank(name) - if(!ballot) - usr << output("Voting Failed. usage: /Vote Privilege Name", "[ckey(Chan.name)].chat.default_output") - usr << output("Available privileges: Promote Demote Mute Voice Kick Ban Unban", "[ckey(Chan.name)].chat.default_output") - return - var/space = findtext(ballot, " ") - var/privilege = lowertext(copytext(ballot, 1, space)) - var/target - if(space && (length(ballot) > space)) - target = copytext(ballot, space+1) - switch(privilege) - if("promote") votePromote(privilege, Rank, target) - if("demote") voteDemote (privilege, Rank, target) - if("mute") voteMute (privilege, Rank, target) - if("voice") voteVoice (privilege, Rank, target) - if("kick") voteKick (privilege, Rank, target) - if("ban") voteBan (privilege, Rank, target) - if("unban") voteUnban (privilege, Rank, target) - - Send(target as text|null|mob in Home.chatters, file as file|null) - if(!target) - target = input("Who would you like to send a file to?", "Send File") as text|null - if(!target) return - var/mob/chatter/C - if(ismob(target)) C = target - else C = ChatMan.Get(target) - if(!C) - if(src.Chan) - src << output("[target] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert("[target] is not currently online.", "Unable to locate chatter") - else - if(ismob(C)) - var/ign = C.ignoring(ckey) - if(ign & FILES_IGNORE) - alert("[C.name] is currently ignoring files from you.", "Unable to Transfer File") - return - if(!file) - file = input("Select the file you wish to send to [C.name]", "Upload File") as file|null - if(!file) return - if(length(file) > MAX_FILE_SIZE) - alert("This file ([fsize(file)]) exceeds the limit of [fsize(MAX_FILE_SIZE)].","File Size Limit Exceeded.") - fdel(file) - return - switch(alert(C, "[name] is trying to send you a file: [file] ([fsize(file)])","[name] File Transfer","Accept","Reject","Ignore")) - if("Accept") - C << ftp(file) - alert("File ([file]) accepted by [C.name].","File Transfer Complete") - if("Reject") - alert("File ([file]) rejected by [C.name].","File Transfer Failed") - if("Ignore") - C.Ignore(name,"files") - alert("File ([file]) rejected by [C.name].","File Transfer Failed") - - login(telnet_key as text|null) - set hidden = 1 - if(!telnet_key) return - if(!telnet) return - var/savefile/S = new("./data/saves/tel.net") - if(!S || !length(S)) return - var/list/L = new - S["telnet"] >> L - if(!L || !L.len) return - var/key_hash = md5(telnet_key) - if(key_hash in L) - var/telnet_pass = input("Please enter your telnet password:", "Telnet Key Login") as password|null - if(!telnet_pass) - del(L) - return - if(L[key_hash] != md5(telnet_pass)) - del(L) - return - del(L) - name = telnet_key - fade_name = name - Home.UpdateWho() - - Set() - call(usr, "ShowSet")() - - Help() - ShowHelp() - - Cmail() - //ShowChattersMail() - - Say(msg as text|null) - if(!msg) return - if(afk) ReturnAFK() - for(var/i=1,i<=5,i++) - if(!client) continue - winset(src, "[ckey(Home.name)].tag[i]", "is-checked=false") - for(var/i=1,i<=7,i++) - if(!client) continue - winset(src, "[ckey(Home.name)].color[i]", "is-checked=false;text=") - var/C = src.Colors[i] - src.Colors[C] = null - Chan.Say(src, msg) - - Me(msg as text|null) - if(!msg) return - if(afk) ReturnAFK() - Chan.Me(src, msg) - - My(msg as text|null) - if(!msg) return - if(afk) ReturnAFK() - Chan.My(src, msg) - - IM(target as text|null|mob in Home.chatters, msg as text|null) - if(!target) - var/Messenger/im = new(src) - im.Display(src) - return - var/mob/C - if(ismob(target)) C = target - else C = ChatMan.Get(target) - for(var/i=1,i<=3,i++) - if(!client) continue - winset(src, "cim_[C.ckey].tag[i]", "is-checked=false") - for(var/i=1,i<=7,i++) - if(!client) continue - winset(src, "cim_[C.ckey].color[i]", "is-checked=false;text=") - var/N = src.Colors[i] - src.Colors[N] = null - if(!C) - if(src.Chan) - src << output("[target] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert(src, "[target] is not currently online.", "Unable to locate chatter") - else - if(ismob(C)) - if(!msg) - var/Messenger/im = new(src, C.name) - im.Display(src) - return - if(length(msg)>512) - var/part2 = copytext(msg, 513) - msg = copytext(msg, 1, 513) - spawn(20) IM(C.name, part2) - - var/Messenger/im = new(src, C.name) - im.Display(src) - MsgMan.RouteMsg(src, C, msg) - else - if(!msg) - var/Messenger/im = new(src, C) - im.Display(src) - return - if(length(msg)>512) - var/part2 = copytext(msg, 513) - msg = copytext(msg, 1, 513) - spawn(20) IM(C, part2) - - var/Messenger/im = new(src, C) - im.Display(src) - var/savefile/S = new() - var/mob/chatter/M = new() - - M.name = name - M.name_color = name_color - M.text_color = text_color - M.fade_name = fade_name - M.picture = picture - M.age = age - M.location = location - M.description = description - M.interests = interests - - S["from"] << M - S["msg"] << msg - S["to"] << C - - src << output(src.ParseMsg(src, msg, src.say_format), "cim_[C.ckey].output") - world.Export("[NetMan.Chatters[C]]?dest=msgman&action=msg",S) - - Ignore(mob/target as text|null|mob in Home.chatters, scope as text|null|anything in list("im", "chat", "fade", "colors", "smileys", "images", "files", "full")) - if(!target) - if(src.Chan) - src << output("Please provide a name. Proper usage: /Ignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("Please provide a name. Proper usage: /Ignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "Ignore") - return - if(!ignoring) ignoring = new - if(ismob(target)) target = target.name - var/is_ignored = ignoring(target) - if(is_ignored == FULL_IGNORE) - if(src.Chan) - src << output("You are already ignoring [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are already ignoring [target].", "Unable to ignore chatter") - return - if(!scope) scope = "[FULL_IGNORE]" - var/ignore_type = "this scope" - switch(scope) - if("im") - scope = "[IM_IGNORE]" - ignore_type = "instant messages" - if("chat") - scope = "[CHAT_IGNORE]" - ignore_type = "chat messages" - if("fade") - scope = "[FADE_IGNORE]" - ignore_type = "fades" - if("colors") - scope = "[COLOR_IGNORE]" - ignore_type = "colors" - if("smileys") - scope = "[SMILEY_IGNORE]" - ignore_type = "smileys" - if("images") - scope = "[IMAGES_IGNORE]" - ignore_type = "images" - if("files") - scope = "[FILES_IGNORE]" - ignore_type = "files" - if("full") scope = "[FULL_IGNORE]" - var/num = text2num(scope) - if(num && isnum(num)) - if(num & is_ignored) - if(src.Chan) - src << output("You are already ignoring [ignore_type] from [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are already ignoring [ignore_type] from [target].","Unable to ignore chatter") - return - num += is_ignored - ignore_type = "" - if(num == 31) num = FULL_IGNORE - if(num & FULL_IGNORE) scope = FULL_IGNORE - else - scope = 0 - if(num & IM_IGNORE) - scope |= IM_IGNORE - ignore_type += "\n - instant messages" - if(ckey(target) in msgHandlers) - winset(src, "cim_[ckey(target)]", "is-visible=false") - if(num & CHAT_IGNORE) - scope |= CHAT_IGNORE - ignore_type += "\n - chat messages" - if(num & FADE_IGNORE) - scope |= FADE_IGNORE - ignore_type += "\n - fade name" - if(num & COLOR_IGNORE) - scope |= COLOR_IGNORE - ignore_type += "\n - colors" - if(num & SMILEY_IGNORE) - scope |= SMILEY_IGNORE - ignore_type += "\n - smileys" - if(num & IMAGES_IGNORE) - scope |= IMAGES_IGNORE - ignore_type += "\n - images" - if(num & FILES_IGNORE) - scope |= FILES_IGNORE - ignore_type += "\n - files" - if(!scope) - if(src.Chan) - src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full","Unable to ignore chatter") - return - else - if(src.Chan) - src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full", "[ckey(Home.name)].chat.default_output") - else - alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full","Unable to ignore chatter") - return - if(!is_ignored) ignoring += ckey(target) - ignoring[ckey(target)] = scope - if(length(ignore_type)) - if(src.Chan) - src << output("You are now ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") - else - alert("You are now ignoring the following from [target]: [ignore_type]", "Ignoring chatter") - else - if(src.Chan) - src << output("You are now fully ignoring [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are now fully ignoring [target].", "Ignoring chatter") - ChatMan.Save(src) - - - Unignore(mob/target as text|null|anything in ignoring, scope as text|null|anything in list("im", "chat", "fade", "colors", "smileys", "images", "files", "full")) - if(!target) - if(src.Chan) - src << output("Please provide a name. Proper usage: /Unignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("Please provide a name. Proper usage: /Unignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "Unignore") - return - if(!ignoring || !ignoring.len) - if(src.Chan) - src << output("You are not currently ignoring any chatters.", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring any chatters.", "Unable to unignore chatter") - return - if(ismob(target)) target = target.name - var/ign = ignoring(target) - if(!ign) - if(src.Chan) - src << output("You are not currently ignoring [target]", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring [target]", "Unable to unignore chatter") - return - if(!scope) scope = "[FULL_IGNORE]" - var/ignore_type = "this scope" - switch(scope) - if("im") - scope = "[IM_IGNORE]" - ignore_type = "instant messages" - if("chat") - scope = "[CHAT_IGNORE]" - ignore_type = "chat messages" - if("fade") - scope = "[FADE_IGNORE]" - ignore_type = "fades" - if("colors") - scope = "[COLOR_IGNORE]" - ignore_type = "colors" - if("smileys") - scope = "[SMILEY_IGNORE]" - ignore_type = "smileys" - if("images") - scope = "[IMAGES_IGNORE]" - ignore_type = "images" - if("files") - scope = "[FILES_IGNORE]" - ignore_type = "files" - if("full") scope = "[FULL_IGNORE]" - var/num = text2num(scope) - if(num && isnum(num)) - if((num != FULL_IGNORE) && !(num & ign)) - if(src.Chan) - src << output("You are not currently ignoring [ignore_type] from [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring [ignore_type] from [target].","Unable to unignore chatter") - return - ignore_type = "" - if(num == 31) num = FULL_IGNORE - if(num & FULL_IGNORE) scope = FULL_IGNORE - else - scope = 0 - if(num & IM_IGNORE) - scope |= IM_IGNORE - if(ign - IM_IGNORE) - ignore_type += "\n - instant messages" - if(num & CHAT_IGNORE) - scope |= CHAT_IGNORE - if(ign - CHAT_IGNORE) - ignore_type += "\n - chat messages" - if(num & FADE_IGNORE) - scope |= FADE_IGNORE - if(ign - FADE_IGNORE) - ignore_type += "\n - fade name" - if(num & COLOR_IGNORE) - scope |= COLOR_IGNORE - if(ign - COLOR_IGNORE) - ignore_type += "\n - colors" - if(num & SMILEY_IGNORE) - scope |= SMILEY_IGNORE - if(ign - SMILEY_IGNORE) - ignore_type += "\n - smileys" - if(num & IMAGES_IGNORE) - scope |= IMAGES_IGNORE - if(ign - IMAGES_IGNORE) - ignore_type += "\n - images" - if(num & FILES_IGNORE) - scope |= FILES_IGNORE - if(ign - FILES_IGNORE) - ignore_type += "\n - files" - if(!scope) - if(src.Chan) - src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full","Unable to unignore chatter") - return - else - if(src.Chan) - src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full","Unable to unignore chatter") - return - if(scope == FULL_IGNORE) ignoring -= ckey(target) - else ignoring[ckey(target)] &= ~scope - if(!ignoring[ckey(target)]) - ignoring -= ckey(target) - ignore_type = "" - if(length(ignore_type)) - if(src.Chan) - src << output("You are no longer ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") - else - alert("You are no longer ignoring the following from [target]: [ignore_type]", "Unignoring chatter") - else - if(src.Chan) - src << output("You are no longer ignoring [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are no longer ignoring [target].", "Unignoring chatter") - ChatMan.Save(src) - - Ignoring(mob/target as text|null|anything in ignoring) - if(!ignoring || !ignoring.len) - if(src.Chan) - src << output("You are not currently ignoring any chatters.", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring any chatters.", "No chatters ignored") - return - if(!target) - var/ignored - for(var/i in ignoring) - var/scoped - if((ignoring[i] & FULL_IGNORE)) scoped = "Full ignore" - else - if((ignoring[i] & IM_IGNORE)) - if(!scoped) scoped = "IMs" - else scoped += ", IMs" - if((ignoring[i] & CHAT_IGNORE)) - if(!scoped) scoped = "chat" - else scoped += ", chat" - if((ignoring[i] & FADE_IGNORE)) - if(!scoped) scoped = "fade name" - else scoped += ", fade name" - if((ignoring[i] & COLOR_IGNORE)) - if(!scoped) scoped = "colors" - else scoped += ", colors" - if((ignoring[i] & SMILEY_IGNORE)) - if(!scoped) scoped = "smileys" - else scoped += ", smileys" - if((ignoring[i] & IMAGES_IGNORE)) - if(!scoped) scoped = "images" - else scoped += ", images" - if((ignoring[i] & FILES_IGNORE)) - if(!scoped) scoped = "files" - else scoped += ", files" - ignored += "\n[i] - [scoped]" - if(src.Chan) - src << output("You are currently ignoring the following chatters.[ignored]", "[ckey(Home.name)].chat.default_output") - else - alert("You are currently ignoring the following chatters.[ignored]", "Not Ignoring chatter") - return - if(ismob(target)) target = target.name - var/ign = ignoring(target) - if(!ign) - if(src.Chan) - src << output("You are not currently ignoring [target]", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring [target]", "Not Ignoring chatter") - return - var/ignore_type = "" - if(!(ign & FULL_IGNORE)) - if(ign & IM_IGNORE) - if(ign - IM_IGNORE) - ignore_type += "\n - instant messages" - if(ign & CHAT_IGNORE) - if(ign - CHAT_IGNORE) - ignore_type += "\n - chat messages" - if(ign & FADE_IGNORE) - if(ign - FADE_IGNORE) - ignore_type += "\n - fade name" - if(ign & COLOR_IGNORE) - if(ign - COLOR_IGNORE) - ignore_type += "\n - colors" - if(ign & SMILEY_IGNORE) - if(ign - SMILEY_IGNORE) - ignore_type += "\n - smileys" - if(ign & IMAGES_IGNORE) - if(ign - IMAGES_IGNORE) - ignore_type += "\n - images" - if(ign & FILES_IGNORE) - if(ign - FILES_IGNORE) - ignore_type += "\n - files" - if(length(ignore_type)) - if(src.Chan) - src << output("You are ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") - else - alert("You are ignoring the following from [target]: [ignore_type]", "Ignoring chatter") - else - if(src.Chan) - src << output("You are fully ignoring [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are fully ignoring [target].", "Ignoring chatter") - - Look() - if(!Chan) return - if(!Chan.room_desc) - src << output("Looking around, you see....\n\tAn average looking room.", "[ckey(Chan.name)].chat.default_output") - return - if(Chan.room_desc_size >= 500) - switch(alert("This room description exceeds the recomended room description size. (500 characters) Would you like to view it anyways?","Room Description Size Alert! [Chan.room_desc_size] characters!","Yes","No")) - if("No") return - src << output("Looking around, you see....\n\t[Chan.room_desc]", "[ckey(Chan.name)].chat.default_output") - - - LookAt(t as text|null|mob in Home.chatters) - if(!t) return - var/mob/chatter/C - if(ismob(t)) C = t - else C = ChatMan.Get(t) - if(!C) - if(src.Chan) - src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert(src, "[t] is not currently online.", "Unable to locate chatter") - else - src << output(null, "profile.output") - if(C.picture) - src << output("\...", "profile.output") - else - src << browse_rsc('./resources/images/noimage.png', "noimage.png") - src << output("\...", "profile.output") - winset(src, "profile.key", "text=' [TextMan.escapeQuotes(C.name)]") - winset(src, "profile.age", "text=' [TextMan.escapeQuotes(C.age)]") - winset(src, "profile.gender", "text=' [C.gender]") - winset(src, "profile.location", "text=' [TextMan.escapeQuotes(C.location)]") - winset(src, "profile.description", "text=' [TextMan.escapeQuotes(C.description)]") - winset(src, "profile.interests", "text=' [TextMan.escapeQuotes(C.interests)]") - winset(src, "profile", "is-visible=true") - winset(src, "profile.show_button", "command='ShowCode \"[C.name]\"';") - winset(src, "profile.im_button", "command='IM \"[C.name]\"';") - - ShowCode(t as text|null|mob in Home.chatters) - if(afk) ReturnAFK() - var/showcode_snippet/S = new - if(t) - var/mob/chatter/C - if(ismob(t)) C = t - else C = ChatMan.Get(t) - if(!C) - if(src.Chan) - src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert(src, "[t] is not currently online.", "Unable to locate chatter") - else - var/ign = C.ignoring(src) - if(ign && CHAT_IGNORE) - src << "Unable to show code!" - src << "[C.name] is ignoring you." - return - S.target = C.ckey - else - if(!src.Chan || Chan.ismute(src)) - if(src.Chan) src.Chan.chanbot.Say("I'm sorry, but you appear to be muted.", src) - return - - var/iCode = input("Paste your code below") as message - S.owner = "[src.name]" - S.code = iCode - S.Send(1) - - ShowText(t as text|null|mob in Home.chatters) - if(afk) ReturnAFK() - - var/showcode_snippet/S = new - if(t) - var/mob/chatter/C - if(ismob(t)) C = t - else C = ChatMan.Get(t) - if(!C) - if(src.Chan) - src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert(src, "[t] is not currently online.", "Unable to locate chatter") - else - var/ign = C.ignoring(src) - if(ign && CHAT_IGNORE) - src << "Unable to show code!" - src << "[C.name] is ignoring you." - return - S.target = C.ckey - else - if(!src.Chan || Chan.ismute(src)) - if(src.Chan) src.Chan.chanbot.Say("I'm sorry, but you appear to be muted.", src) - return - - var/iCode = input("Paste your text below") as message - S.owner = "[src.name]" - S.code = iCode - S.Send() - - afk(msg as text|null) - if(!Chan) return - if(!afk) - if(!msg) msg = auto_reason - Home.GoAFK(src, msg) - else - ReturnAFK() - Filter(msg as text|null) - switch(ckey(msg)) - if("on","1") filter=2 - if("off","0") filter=0 +mob + chatter + verb + // Temporary, toggle name notify. + Notify() + name_notify = !name_notify + + src << "You will no[name_notify ? "w" : "t"] be notified if your name is said." + + + Vote(ballot as text|null) + var/OpRank/Rank = ChatMan.Rank(name) + if(!ballot) + usr << output("Voting Failed. usage: /Vote Privilege Name", "[ckey(Chan.name)].chat.default_output") + usr << output("Available privileges: Promote Demote Mute Voice Kick Ban Unban", "[ckey(Chan.name)].chat.default_output") + return + var/space = findtext(ballot, " ") + var/privilege = lowertext(copytext(ballot, 1, space)) + var/target + if(space && (length(ballot) > space)) + target = copytext(ballot, space+1) + switch(privilege) + if("promote") votePromote(privilege, Rank, target) + if("demote") voteDemote (privilege, Rank, target) + if("mute") voteMute (privilege, Rank, target) + if("voice") voteVoice (privilege, Rank, target) + if("kick") voteKick (privilege, Rank, target) + if("ban") voteBan (privilege, Rank, target) + if("unban") voteUnban (privilege, Rank, target) + + Send(target as text|null|mob in Home.chatters, file as file|null) + if(!target) + target = input("Who would you like to send a file to?", "Send File") as text|null + if(!target) return + var/mob/chatter/C + if(ismob(target)) C = target + else C = ChatMan.Get(target) + if(!C) + if(src.Chan) + src << output("[target] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert("[target] is not currently online.", "Unable to locate chatter") + else + if(ismob(C)) + var/ign = C.ignoring(ckey) + if(ign & FILES_IGNORE) + alert("[C.name] is currently ignoring files from you.", "Unable to Transfer File") + return + if(!file) + file = input("Select the file you wish to send to [C.name]", "Upload File") as file|null + if(!file) return + if(length(file) > MAX_FILE_SIZE) + alert("This file ([fsize(file)]) exceeds the limit of [fsize(MAX_FILE_SIZE)].","File Size Limit Exceeded.") + fdel(file) + return + switch(alert(C, "[name] is trying to send you a file: [file] ([fsize(file)])","[name] File Transfer","Accept","Reject","Ignore")) + if("Accept") + C << ftp(file) + alert("File ([file]) accepted by [C.name].","File Transfer Complete") + if("Reject") + alert("File ([file]) rejected by [C.name].","File Transfer Failed") + if("Ignore") + C.Ignore(name,"files") + alert("File ([file]) rejected by [C.name].","File Transfer Failed") + + login(telnet_key as text|null) + set hidden = 1 + if(!telnet_key) return + if(!telnet) return + var/savefile/S = new("./data/saves/tel.net") + if(!S || !length(S)) return + var/list/L = new + S["telnet"] >> L + if(!L || !L.len) return + var/key_hash = md5(telnet_key) + if(key_hash in L) + var/telnet_pass = input("Please enter your telnet password:", "Telnet Key Login") as password|null + if(!telnet_pass) + del(L) + return + if(L[key_hash] != md5(telnet_pass)) + del(L) + return + del(L) + name = telnet_key + fade_name = name + Home.UpdateWho() + + Set() + call(usr, "ShowSet")() + + Help() + ShowHelp() + + Cmail() + //ShowChattersMail() + + Say(msg as text|null) + if(!msg) return + if(afk) ReturnAFK() + for(var/i=1,i<=5,i++) + if(!client) continue + winset(src, "[ckey(Home.name)].tag[i]", "is-checked=false") + for(var/i=1,i<=7,i++) + if(!client) continue + winset(src, "[ckey(Home.name)].color[i]", "is-checked=false;text=") + var/C = src.Colors[i] + src.Colors[C] = null + Chan.Say(src, msg) + + Me(msg as text|null) + if(!msg) return + if(afk) ReturnAFK() + Chan.Me(src, msg) + + My(msg as text|null) + if(!msg) return + if(afk) ReturnAFK() + Chan.My(src, msg) + + IM(target as text|null|mob in Home.chatters, msg as text|null) + if(!target) + var/Messenger/im = new(src) + im.Display(src) + return + var/mob/C + if(ismob(target)) C = target + else C = ChatMan.Get(target) + for(var/i=1,i<=3,i++) + if(!client) continue + winset(src, "cim_[C.ckey].tag[i]", "is-checked=false") + for(var/i=1,i<=7,i++) + if(!client) continue + winset(src, "cim_[C.ckey].color[i]", "is-checked=false;text=") + var/N = src.Colors[i] + src.Colors[N] = null + if(!C) + if(src.Chan) + src << output("[target] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert(src, "[target] is not currently online.", "Unable to locate chatter") + else + if(ismob(C)) + if(!msg) + var/Messenger/im = new(src, C.name) + im.Display(src) + return + if(length(msg)>512) + var/part2 = copytext(msg, 513) + msg = copytext(msg, 1, 513) + spawn(20) IM(C.name, part2) + + var/Messenger/im = new(src, C.name) + im.Display(src) + MsgMan.RouteMsg(src, C, msg) + else + if(!msg) + var/Messenger/im = new(src, C) + im.Display(src) + return + if(length(msg)>512) + var/part2 = copytext(msg, 513) + msg = copytext(msg, 1, 513) + spawn(20) IM(C, part2) + + var/Messenger/im = new(src, C) + im.Display(src) + var/savefile/S = new() + var/mob/chatter/M = new() + + M.name = name + M.name_color = name_color + M.text_color = text_color + M.fade_name = fade_name + M.picture = picture + M.age = age + M.location = location + M.description = description + M.interests = interests + + S["from"] << M + S["msg"] << msg + S["to"] << C + + src << output(src.ParseMsg(src, msg, src.say_format), "cim_[C.ckey].output") + + Ignore(mob/target as text|null|mob in Home.chatters, scope as text|null|anything in list("im", "chat", "fade", "colors", "smileys", "images", "files", "full")) + if(!target) + if(src.Chan) + src << output("Please provide a name. Proper usage: /Ignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("Please provide a name. Proper usage: /Ignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "Ignore") + return + if(!ignoring) ignoring = new + if(ismob(target)) target = target.name + var/is_ignored = ignoring(target) + if(is_ignored == FULL_IGNORE) + if(src.Chan) + src << output("You are already ignoring [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are already ignoring [target].", "Unable to ignore chatter") + return + if(!scope) scope = "[FULL_IGNORE]" + var/ignore_type = "this scope" + switch(scope) + if("im") + scope = "[IM_IGNORE]" + ignore_type = "instant messages" + if("chat") + scope = "[CHAT_IGNORE]" + ignore_type = "chat messages" + if("fade") + scope = "[FADE_IGNORE]" + ignore_type = "fades" + if("colors") + scope = "[COLOR_IGNORE]" + ignore_type = "colors" + if("smileys") + scope = "[SMILEY_IGNORE]" + ignore_type = "smileys" + if("images") + scope = "[IMAGES_IGNORE]" + ignore_type = "images" + if("files") + scope = "[FILES_IGNORE]" + ignore_type = "files" + if("full") scope = "[FULL_IGNORE]" + var/num = text2num(scope) + if(num && isnum(num)) + if(num & is_ignored) + if(src.Chan) + src << output("You are already ignoring [ignore_type] from [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are already ignoring [ignore_type] from [target].","Unable to ignore chatter") + return + num += is_ignored + ignore_type = "" + if(num == 31) num = FULL_IGNORE + if(num & FULL_IGNORE) scope = FULL_IGNORE + else + scope = 0 + if(num & IM_IGNORE) + scope |= IM_IGNORE + ignore_type += "\n - instant messages" + if(ckey(target) in msgHandlers) + winset(src, "cim_[ckey(target)]", "is-visible=false") + if(num & CHAT_IGNORE) + scope |= CHAT_IGNORE + ignore_type += "\n - chat messages" + if(num & FADE_IGNORE) + scope |= FADE_IGNORE + ignore_type += "\n - fade name" + if(num & COLOR_IGNORE) + scope |= COLOR_IGNORE + ignore_type += "\n - colors" + if(num & SMILEY_IGNORE) + scope |= SMILEY_IGNORE + ignore_type += "\n - smileys" + if(num & IMAGES_IGNORE) + scope |= IMAGES_IGNORE + ignore_type += "\n - images" + if(num & FILES_IGNORE) + scope |= FILES_IGNORE + ignore_type += "\n - files" + if(!scope) + if(src.Chan) + src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full","Unable to ignore chatter") + return + else + if(src.Chan) + src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full", "[ckey(Home.name)].chat.default_output") + else + alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full","Unable to ignore chatter") + return + if(!is_ignored) ignoring += ckey(target) + ignoring[ckey(target)] = scope + if(length(ignore_type)) + if(src.Chan) + src << output("You are now ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") + else + alert("You are now ignoring the following from [target]: [ignore_type]", "Ignoring chatter") + else + if(src.Chan) + src << output("You are now fully ignoring [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are now fully ignoring [target].", "Ignoring chatter") + ChatMan.Save(src) + + + Unignore(mob/target as text|null|anything in ignoring, scope as text|null|anything in list("im", "chat", "fade", "colors", "smileys", "images", "files", "full")) + if(!target) + if(src.Chan) + src << output("Please provide a name. Proper usage: /Unignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("Please provide a name. Proper usage: /Unignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "Unignore") + return + if(!ignoring || !ignoring.len) + if(src.Chan) + src << output("You are not currently ignoring any chatters.", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring any chatters.", "Unable to unignore chatter") + return + if(ismob(target)) target = target.name + var/ign = ignoring(target) + if(!ign) + if(src.Chan) + src << output("You are not currently ignoring [target]", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring [target]", "Unable to unignore chatter") + return + if(!scope) scope = "[FULL_IGNORE]" + var/ignore_type = "this scope" + switch(scope) + if("im") + scope = "[IM_IGNORE]" + ignore_type = "instant messages" + if("chat") + scope = "[CHAT_IGNORE]" + ignore_type = "chat messages" + if("fade") + scope = "[FADE_IGNORE]" + ignore_type = "fades" + if("colors") + scope = "[COLOR_IGNORE]" + ignore_type = "colors" + if("smileys") + scope = "[SMILEY_IGNORE]" + ignore_type = "smileys" + if("images") + scope = "[IMAGES_IGNORE]" + ignore_type = "images" + if("files") + scope = "[FILES_IGNORE]" + ignore_type = "files" + if("full") scope = "[FULL_IGNORE]" + var/num = text2num(scope) + if(num && isnum(num)) + if((num != FULL_IGNORE) && !(num & ign)) + if(src.Chan) + src << output("You are not currently ignoring [ignore_type] from [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring [ignore_type] from [target].","Unable to unignore chatter") + return + ignore_type = "" + if(num == 31) num = FULL_IGNORE + if(num & FULL_IGNORE) scope = FULL_IGNORE + else + scope = 0 + if(num & IM_IGNORE) + scope |= IM_IGNORE + if(ign - IM_IGNORE) + ignore_type += "\n - instant messages" + if(num & CHAT_IGNORE) + scope |= CHAT_IGNORE + if(ign - CHAT_IGNORE) + ignore_type += "\n - chat messages" + if(num & FADE_IGNORE) + scope |= FADE_IGNORE + if(ign - FADE_IGNORE) + ignore_type += "\n - fade name" + if(num & COLOR_IGNORE) + scope |= COLOR_IGNORE + if(ign - COLOR_IGNORE) + ignore_type += "\n - colors" + if(num & SMILEY_IGNORE) + scope |= SMILEY_IGNORE + if(ign - SMILEY_IGNORE) + ignore_type += "\n - smileys" + if(num & IMAGES_IGNORE) + scope |= IMAGES_IGNORE + if(ign - IMAGES_IGNORE) + ignore_type += "\n - images" + if(num & FILES_IGNORE) + scope |= FILES_IGNORE + if(ign - FILES_IGNORE) + ignore_type += "\n - files" + if(!scope) + if(src.Chan) + src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full","Unable to unignore chatter") + return + else + if(src.Chan) + src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full","Unable to unignore chatter") + return + if(scope == FULL_IGNORE) ignoring -= ckey(target) + else ignoring[ckey(target)] &= ~scope + if(!ignoring[ckey(target)]) + ignoring -= ckey(target) + ignore_type = "" + if(length(ignore_type)) + if(src.Chan) + src << output("You are no longer ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") + else + alert("You are no longer ignoring the following from [target]: [ignore_type]", "Unignoring chatter") + else + if(src.Chan) + src << output("You are no longer ignoring [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are no longer ignoring [target].", "Unignoring chatter") + ChatMan.Save(src) + + Ignoring(mob/target as text|null|anything in ignoring) + if(!ignoring || !ignoring.len) + if(src.Chan) + src << output("You are not currently ignoring any chatters.", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring any chatters.", "No chatters ignored") + return + if(!target) + var/ignored + for(var/i in ignoring) + var/scoped + if((ignoring[i] & FULL_IGNORE)) scoped = "Full ignore" + else + if((ignoring[i] & IM_IGNORE)) + if(!scoped) scoped = "IMs" + else scoped += ", IMs" + if((ignoring[i] & CHAT_IGNORE)) + if(!scoped) scoped = "chat" + else scoped += ", chat" + if((ignoring[i] & FADE_IGNORE)) + if(!scoped) scoped = "fade name" + else scoped += ", fade name" + if((ignoring[i] & COLOR_IGNORE)) + if(!scoped) scoped = "colors" + else scoped += ", colors" + if((ignoring[i] & SMILEY_IGNORE)) + if(!scoped) scoped = "smileys" + else scoped += ", smileys" + if((ignoring[i] & IMAGES_IGNORE)) + if(!scoped) scoped = "images" + else scoped += ", images" + if((ignoring[i] & FILES_IGNORE)) + if(!scoped) scoped = "files" + else scoped += ", files" + ignored += "\n[i] - [scoped]" + if(src.Chan) + src << output("You are currently ignoring the following chatters.[ignored]", "[ckey(Home.name)].chat.default_output") + else + alert("You are currently ignoring the following chatters.[ignored]", "Not Ignoring chatter") + return + if(ismob(target)) target = target.name + var/ign = ignoring(target) + if(!ign) + if(src.Chan) + src << output("You are not currently ignoring [target]", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring [target]", "Not Ignoring chatter") + return + var/ignore_type = "" + if(!(ign & FULL_IGNORE)) + if(ign & IM_IGNORE) + if(ign - IM_IGNORE) + ignore_type += "\n - instant messages" + if(ign & CHAT_IGNORE) + if(ign - CHAT_IGNORE) + ignore_type += "\n - chat messages" + if(ign & FADE_IGNORE) + if(ign - FADE_IGNORE) + ignore_type += "\n - fade name" + if(ign & COLOR_IGNORE) + if(ign - COLOR_IGNORE) + ignore_type += "\n - colors" + if(ign & SMILEY_IGNORE) + if(ign - SMILEY_IGNORE) + ignore_type += "\n - smileys" + if(ign & IMAGES_IGNORE) + if(ign - IMAGES_IGNORE) + ignore_type += "\n - images" + if(ign & FILES_IGNORE) + if(ign - FILES_IGNORE) + ignore_type += "\n - files" + if(length(ignore_type)) + if(src.Chan) + src << output("You are ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") + else + alert("You are ignoring the following from [target]: [ignore_type]", "Ignoring chatter") + else + if(src.Chan) + src << output("You are fully ignoring [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are fully ignoring [target].", "Ignoring chatter") + + Look() + if(!Chan) return + if(!Chan.room_desc) + src << output("Looking around, you see....\n\tAn average looking room.", "[ckey(Chan.name)].chat.default_output") + return + if(Chan.room_desc_size >= 500) + switch(alert("This room description exceeds the recomended room description size. (500 characters) Would you like to view it anyways?","Room Description Size Alert! [Chan.room_desc_size] characters!","Yes","No")) + if("No") return + src << output("Looking around, you see....\n\t[Chan.room_desc]", "[ckey(Chan.name)].chat.default_output") + + + LookAt(t as text|null|mob in Home.chatters) + if(!t) return + var/mob/chatter/C + if(ismob(t)) C = t + else C = ChatMan.Get(t) + if(!C) + if(src.Chan) + src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert(src, "[t] is not currently online.", "Unable to locate chatter") + else + src << output(null, "profile.output") + if(C.picture) + src << output("\...", "profile.output") + else + src << browse_rsc('./resources/images/noimage.png', "noimage.png") + src << output("\...", "profile.output") + winset(src, "profile.key", "text=' [TextMan.escapeQuotes(C.name)]") + winset(src, "profile.age", "text=' [TextMan.escapeQuotes(C.age)]") + winset(src, "profile.gender", "text=' [C.gender]") + winset(src, "profile.location", "text=' [TextMan.escapeQuotes(C.location)]") + winset(src, "profile.description", "text=' [TextMan.escapeQuotes(C.description)]") + winset(src, "profile.interests", "text=' [TextMan.escapeQuotes(C.interests)]") + winset(src, "profile", "is-visible=true") + winset(src, "profile.show_button", "command='ShowCode \"[C.name]\"';") + winset(src, "profile.im_button", "command='IM \"[C.name]\"';") + + ShowCode(t as text|null|mob in Home.chatters) + if(afk) ReturnAFK() + var/showcode_snippet/S = new + if(t) + var/mob/chatter/C + if(ismob(t)) C = t + else C = ChatMan.Get(t) + if(!C) + if(src.Chan) + src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert(src, "[t] is not currently online.", "Unable to locate chatter") + else + var/ign = C.ignoring(src) + if(ign && CHAT_IGNORE) + src << "Unable to show code!" + src << "[C.name] is ignoring you." + return + S.target = C.ckey + else + if(!src.Chan || Chan.ismute(src)) + if(src.Chan) src.Chan.chanbot.Say("I'm sorry, but you appear to be muted.", src) + return + + var/iCode = input("Paste your code below") as message + S.owner = "[src.name]" + S.code = iCode + S.Send(1) + + ShowText(t as text|null|mob in Home.chatters) + if(afk) ReturnAFK() + + var/showcode_snippet/S = new + if(t) + var/mob/chatter/C + if(ismob(t)) C = t + else C = ChatMan.Get(t) + if(!C) + if(src.Chan) + src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert(src, "[t] is not currently online.", "Unable to locate chatter") + else + var/ign = C.ignoring(src) + if(ign && CHAT_IGNORE) + src << "Unable to show code!" + src << "[C.name] is ignoring you." + return + S.target = C.ckey + else + if(!src.Chan || Chan.ismute(src)) + if(src.Chan) src.Chan.chanbot.Say("I'm sorry, but you appear to be muted.", src) + return + + var/iCode = input("Paste your text below") as message + S.owner = "[src.name]" + S.code = iCode + S.Send() + + afk(msg as text|null) + if(!Chan) return + if(!afk) + if(!msg) msg = auto_reason + Home.GoAFK(src, msg) + else + ReturnAFK() + Filter(msg as text|null) + switch(ckey(msg)) + if("on","1") filter=2 + if("off","0") filter=0 src << "Filter set [msg]" \ No newline at end of file diff --git a/code/models/chatter/controls.dm b/code/models/chatter/controls.dm index 53dd5c0..c093974 100644 --- a/code/models/chatter/controls.dm +++ b/code/models/chatter/controls.dm @@ -1,423 +1,422 @@ - -mob - chatter - verb - - SwapPanes(nosave as num|null) - set hidden = 1 - if(!src.Chan) return - if(!src.showwho) return - src.swaped_panes ^= 1 - var/splitter = text2num(winget(src, "[ckey(Home.name)].child", "splitter")) - winset(src, "[ckey(Home.name)].child", "splitter=[100-splitter]") - if(src.swaped_panes) - winset(src, "[ckey(Home.name)].child", "left='[ckey(Home.name)].who'") - winset(src, "[ckey(Home.name)].child", "right='[ckey(Home.name)].chat'") - winset(src, "[ckey(Home.name)].topic_label", "pos='132,0'") - winset(src, "[ckey(Home.name)].online", "is-visible=false") - winset(src, "[ckey(Home.name)].online_left", "is-visible=true") - else - winset(src, "[ckey(Home.name)].child", "left='[ckey(Home.name)].chat'") - winset(src, "[ckey(Home.name)].child", "right='[ckey(Home.name)].who'") - winset(src, "[ckey(Home.name)].topic_label", "pos='0,0'") - winset(src, "[ckey(Home.name)].online", "is-visible=true") - winset(src, "[ckey(Home.name)].online_left", "is-visible=false") - if(!nosave) - winsize = winget(src, "default", "size") - ChatMan.Save(src) - - ToggleTopic(nosave as num|null) - set hidden = 1 - if(!src.Chan) return - if(src.showtopic) - winset(src, "[ckey(Home.name)].topic_label", "is-visible=false") - src.showtopic = FALSE - if(Host == src) winset(src, "host.topic_toggle", "is-checked=false;") - else winset(src, "menu.topic_toggle", "is-checked=false;") - if(!showwho && !nosave) - var/size = winget(src, "default.child", "size") - var/X = copytext(size, 1, findtext(size, "x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))+20 - winset(src, "default.child", "pos='0,-20';size='[X]x[Y]'") - else - winset(src, "[ckey(Home.name)].topic_label", "is-visible=true") - src.showtopic = TRUE - if(Host == src) winset(src, "host.topic_toggle", "is-checked=true;") - else winset(src, "menu.topic_toggle", "is-checked=true;") - if(!showwho && !nosave) - var/size = winget(src, "default.child", "size") - var/X = copytext(size, 1, findtext(size, "x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))-20 - winset(src, "default.child", "pos='0,0';size='[X]x[Y]'") - if(!nosave) - winsize = winget(src, "default", "size") - ChatMan.Save(src) - - ToggleWho(nosave as num|null) - set hidden = 1 - if(!src.Chan) return - var/pos = "right" - if(src.swaped_panes) pos = "left" - if(src.showwho) - winset(src, "[ckey(Home.name)].child", "[pos]=") - winset(src, "[ckey(Home.name)].online", "is-visible=false") - src.showwho = FALSE - if(Host == src) winset(src, "host.who_toggle", "is-checked=false;") - else winset(src, "menu.who_toggle", "is-checked=false;") - if(!showtopic) - var/size = winget(src, "default.child", "size") - var/X = copytext(size, 1, findtext(size, "x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))+20 - winset(src, "default.child", "pos='0,-20';size='[X]x[Y]'") - - else - winset(src, "[ckey(Home.name)].child", "[pos]='[ckey(Home.name)].who'") - winset(src, "[ckey(Home.name)].online", "is-visible=true") - src.showwho = TRUE - if(Host == src) winset(src, "host.who_toggle", "is-checked=true;") - else winset(src, "menu.who_toggle", "is-checked=true;") - if(!showtopic) - var/size = winget(src, "default.child", "size") - var/X = copytext(size, 1, findtext(size, "x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))-20 - winset(src, "default.child", "pos='0,0';size='[X]x[Y]'") - if(!nosave) - winsize = winget(src, "default", "size") - ChatMan.Save(src) - - ToggleQuickBar(nosave as num|null) - set hidden = 1 - if(!Chan) return - var/i - var/size = winget(src, "[ckey(Home.name)].child", "size") - var/seperator = findtext(size, "x") - var/X = copytext(size,1,seperator) - var/Y = text2num(copytext(size,seperator+1)) - var/window = ckey(Home.name) - if(src.quickbar) - Y += 16 - for(i=1, i<=5, i++) - winset(src, "[window].tag[i]","is-visible=false") - for(i=1, i<=6, i++) - winset(src, "[window].smiley[i]","is-visible=false") - for(i=1, i<=7, i++) - winset(src, "[window].color[i]","is-visible=false") - winset(src, "[window].toggle_quickbar", "text='+'") - quickbar = FALSE - if(Host == src) winset(src, "host.quickbar_toggle", "is-checked=false;") - else winset(src, "menu.quickbar_toggle", "is-checked=false;") - else - Y -= 16 - for(i=1, i<=5, i++) - winset(src, "[window].tag[i]","is-visible=true") - for(i=1, i<=6, i++) - winset(src, "[window].smiley[i]","is-visible=true") - for(i=1, i<=7, i++) - winset(src, "[window].color[i]","is-visible=true") - winset(src, "[window].toggle_quickbar", "text='-'") - quickbar = TRUE - if(Host == src) winset(src, "host.quickbar_toggle", "is-checked=true;") - else winset(src, "menu.quickbar_toggle", "is-checked=true;") - winset(src, null, "[window].child.size=[X]x[Y];\ - [window].default_input.focus=true;") - if(!nosave) - winsize = winget(src, "default", "size") - ChatMan.Save(src) - - - ToggleCIMBar(window as text|null) - set hidden = 1 - if(!window) return - window = "cim_[ckey(window)]" - var/i - - var/outsize = winget(src, "[window].output", "size") - var/outseperator = findtext(outsize, "x") - var/outX = copytext(outsize,1,outseperator) - var/outY = text2num(copytext(outsize,outseperator+1)) - - var/profpos = winget(src, "[window].profile", "pos") - var/profseperator = findtext(profpos, ",") - var/profX = copytext(profpos,1,profseperator) - var/profY = text2num(copytext(profpos,profseperator+1)) - - var/showpos = winget(src, "[window].show", "pos") - var/showseperator = findtext(showpos, ",") - var/showX = copytext(showpos,1,showseperator) - var/showY = text2num(copytext(showpos,showseperator+1)) - - var/sharepos = winget(src, "[window].share", "pos") - var/shareseperator = findtext(sharepos, ",") - var/shareX = copytext(sharepos,1,shareseperator) - var/shareY = text2num(copytext(sharepos,shareseperator+1)) - - var/invpos = winget(src, "[window].invite", "pos") - var/invseperator = findtext(invpos, ",") - var/invX = copytext(invpos,1,invseperator) - var/invY = text2num(copytext(invpos,invseperator+1)) - - var/joinpos = winget(src, "[window].join", "pos") - var/joinseperator = findtext(joinpos, ",") - var/joinX = copytext(joinpos,1,joinseperator) - var/joinY = text2num(copytext(joinpos,joinseperator+1)) - - if(winget(src, "[window].tag1", "is-visible") == "true") - outY += 20 - profY += 20 - showY += 20 - shareY += 20 - invY += 20 - joinY += 20 - for(i=1, i<=3, i++) - winset(src, "[window].tag[i]","is-visible=false") - for(i=1, i<=6, i++) - winset(src, "[window].smiley[i]","is-visible=false") - for(i=1, i<=7, i++) - winset(src, "[window].color[i]","is-visible=false") - winset(src, "[window].toggle_quickbar", "text='+'") - else - outY -= 20 - profY -= 20 - showY -= 20 - shareY -= 20 - invY -= 20 - joinY -= 20 - for(i=1, i<=3, i++) - winset(src, "[window].tag[i]","is-visible=true") - for(i=1, i<=6, i++) - winset(src, "[window].smiley[i]","is-visible=true") - for(i=1, i<=7, i++) - winset(src, "[window].color[i]","is-visible=true") - winset(src, "[window].toggle_quickbar", "text='-'") - winset(src, "[window].profile", "pos=[profX],[profY]") - winset(src, "[window].show", "pos=[showX],[showY]") - winset(src, "[window].share", "pos=[shareX],[shareY]") - winset(src, "[window].invite", "pos=[invX],[invY]") - winset(src, "[window].join", "pos=[joinX],[joinY]") - winset(src, "[window].output", "size=[outX]x[outY]") - winset(src, "[window].input", "focus=true") - - NewInstantMessage() - set hidden = 1 - var/Messenger/im = new(src) - im.Display(src) - - ShowGameWindow() - set hidden = 1 - winshow(src, "game", 1) - - HideGameWindow() - set hidden = 1 - winshow(src, "game", 0) - - ShowChattersMail() - set hidden = 1 - winshow(src, "cmail", 1) - - HideChattersMail() - set hidden = 1 - winshow(src, "cmail", 0) - - ShowAbout() - set hidden = 1 - winshow(src, "about", 1) - - HideAbout() - set hidden = 1 - winshow(src, "about", 0) - - ShowCredits() - set hidden = 1 - winshow(src, "credits", 1) - - HideCredits() - set hidden = 1 - winshow(src, "credits", 0) - - ShowPublicChannels() - set hidden = 1 - NetMan.UpdatePubChans(src) - winshow(src, "pub_chans", 1) - - HidePublicChannels() - set hidden = 1 - winshow(src, "pub_chans", 0) - - ShowHelp(t as text|null) - set hidden = 1 - if(!t) t = "index" - var/HelpView/HV = new() - HV.Display(src, t) - del(HV) - winshow(src, "help", 1) - - HideHelp() - set hidden = 1 - winshow(src, "help", 0) - - SearchHelp(t as text|null) - set hidden = 1 - if(!t) t = winget(src, "help.search", "text") - else winset(src, "help.search", "text='[t]'") - var/HelpView/HV = new() - HV.Display(src, "search", t) - del(HV) - - ShowProfile() - set hidden = 1 - src << output(null, "profile.output") - if(src.picture) src << output("\...", "profile.output") - else - src << output("\...", "profile.output") - winset(src, "profile.key", "text=' [src.name]") - winset(src, "profile.age", "text=' [src.age]") - winset(src, "profile.gender", "text=' [src.gender]") - winset(src, "profile.location", "text=' [src.location]") - winset(src, "profile.description", "text=' [src.description]") - winset(src, "profile.interests", "text=' [src.interests]") - winset(src, "profile", "is-visible=true") - winset(src, "profile.im_button", "command='IM \"[src.name]\"';") - - HideProfile() - set hidden = 1 - winshow(src, "profile", 0) - - SelectColor(scope as text|null) - set hidden = 1 - if(!scope) return - CV.Display(scope) - - InsertColor(color as text|null, window as text|null) - set hidden = 1 - if(!color) return - if(!Chan) return - var/input - if(!window) - window = "[ckey(Home.name)]" - input = "default_input" - else - window = "cim_[ckey(window)]" - input = "input" - var/msg_value = winget(src, "[window].[input]", "text") - var/down = winget(src, "[window].[color]", "is-checked") - if(down == "false") - msg_value += "\[/#]" - var/index = text2num(copytext(color, 6)) - src.Colors[src.Colors[index]] = null - winset(src, "[window].[color]", "text=''") - else - for(var/i=1,i<=7,i++) - var/C = src.Colors[i] - if(src.Colors[C] == "selected") - msg_value += "\[/#]" - src.Colors[C] = null - winset(src, "[window].color[i]", "text=''") - winset(src, "[window].color[i]", "is-checked=false") - switch(color) - if("color1") - msg_value += "\[[src.Colors[1]]]" - src.Colors[src.Colors[1]] = "selected" - if("color2") - msg_value += "\[[src.Colors[2]]]" - src.Colors[src.Colors[2]] = "selected" - if("color3") - msg_value += "\[[src.Colors[3]]]" - src.Colors[src.Colors[3]] = "selected" - if("color4") - msg_value += "\[[src.Colors[4]]]" - src.Colors[src.Colors[4]] = "selected" - if("color5") - msg_value += "\[[src.Colors[5]]]" - src.Colors[src.Colors[5]] = "selected" - if("color6") - msg_value += "\[[src.Colors[6]]]" - src.Colors[src.Colors[6]] = "selected" - if("color7") - msg_value += "\[[src.Colors[7]]]" - src.Colors[src.Colors[7]] = "selected" - winset(src, "[window].[color]", "text='*'") - winset(src, "[window].[input]", "text='[TextMan.escapeQuotes(msg_value)]'") - winset(src, "[window].[input]", "focus=true") - - InsertTag(tag as text|null, window as text|null) - set hidden = 1 - if(!tag) return - if(!Chan) return - var/input - if(!window) - window = "[ckey(Home.name)]" - input = "default_input" - else - window = "cim_[ckey(window)]" - input = "input" - var/msg_value = winget(src, "[window].[input]", "text") - var/down = winget(src, "[window].[tag]", "is-checked") - switch(tag) - if("tag1") - var/open = src.Tags[1] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - if("tag2") - var/open = src.Tags[2] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - if("tag3") - var/open = src.Tags[3] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - if("tag4") - var/open = src.Tags[4] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - if("tag5") - var/open = src.Tags[5] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - winset(src, "[window].[input]", "text='[TextMan.escapeQuotes(msg_value)]'") - winset(src, "[window].[input]", "focus=true") - - InsertSmiley(smiley as text|null, window as text|null) - set hidden = 1 - if(!smiley) return - if(!Chan) return - if(!window) window = "[ckey(Home.name)].default_input" - else window = "cim_[ckey(window)].input" - var/msg_value = winget(src, "[window]", "text") - switch(smiley) - if("smiley1") - msg_value += src.Smileys[1] - if("smiley2") - msg_value += src.Smileys[2] - if("smiley3") - msg_value += src.Smileys[3] - if("smiley4") - msg_value += src.Smileys[4] - if("smiley5") - msg_value += src.Smileys[5] - if("smiley6") - msg_value += src.Smileys[6] - winset(src, "[window]", "text='[TextMan.escapeQuotes(msg_value)]'") - winset(src, "[window]", "focus=true") - - Join() - set hidden = 1 - if(afk) ReturnAFK() - ChanMan.Join(src, Home) - - Quit() - set hidden = 1 - ChanMan.Quit(src, Home) - - SayAlias(msg as text|null) - set name = ">" - Say(msg) + +mob + chatter + verb + + SwapPanes(nosave as num|null) + set hidden = 1 + if(!src.Chan) return + if(!src.showwho) return + src.swaped_panes ^= 1 + var/splitter = text2num(winget(src, "[ckey(Home.name)].child", "splitter")) + winset(src, "[ckey(Home.name)].child", "splitter=[100-splitter]") + if(src.swaped_panes) + winset(src, "[ckey(Home.name)].child", "left='[ckey(Home.name)].who'") + winset(src, "[ckey(Home.name)].child", "right='[ckey(Home.name)].chat'") + winset(src, "[ckey(Home.name)].topic_label", "pos='132,0'") + winset(src, "[ckey(Home.name)].online", "is-visible=false") + winset(src, "[ckey(Home.name)].online_left", "is-visible=true") + else + winset(src, "[ckey(Home.name)].child", "left='[ckey(Home.name)].chat'") + winset(src, "[ckey(Home.name)].child", "right='[ckey(Home.name)].who'") + winset(src, "[ckey(Home.name)].topic_label", "pos='0,0'") + winset(src, "[ckey(Home.name)].online", "is-visible=true") + winset(src, "[ckey(Home.name)].online_left", "is-visible=false") + if(!nosave) + winsize = winget(src, "default", "size") + ChatMan.Save(src) + + ToggleTopic(nosave as num|null) + set hidden = 1 + if(!src.Chan) return + if(src.showtopic) + winset(src, "[ckey(Home.name)].topic_label", "is-visible=false") + src.showtopic = FALSE + if(Host == src) winset(src, "host.topic_toggle", "is-checked=false;") + else winset(src, "menu.topic_toggle", "is-checked=false;") + if(!showwho && !nosave) + var/size = winget(src, "default.child", "size") + var/X = copytext(size, 1, findtext(size, "x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))+20 + winset(src, "default.child", "pos='0,-20';size='[X]x[Y]'") + else + winset(src, "[ckey(Home.name)].topic_label", "is-visible=true") + src.showtopic = TRUE + if(Host == src) winset(src, "host.topic_toggle", "is-checked=true;") + else winset(src, "menu.topic_toggle", "is-checked=true;") + if(!showwho && !nosave) + var/size = winget(src, "default.child", "size") + var/X = copytext(size, 1, findtext(size, "x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))-20 + winset(src, "default.child", "pos='0,0';size='[X]x[Y]'") + if(!nosave) + winsize = winget(src, "default", "size") + ChatMan.Save(src) + + ToggleWho(nosave as num|null) + set hidden = 1 + if(!src.Chan) return + var/pos = "right" + if(src.swaped_panes) pos = "left" + if(src.showwho) + winset(src, "[ckey(Home.name)].child", "[pos]=") + winset(src, "[ckey(Home.name)].online", "is-visible=false") + src.showwho = FALSE + if(Host == src) winset(src, "host.who_toggle", "is-checked=false;") + else winset(src, "menu.who_toggle", "is-checked=false;") + if(!showtopic) + var/size = winget(src, "default.child", "size") + var/X = copytext(size, 1, findtext(size, "x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))+20 + winset(src, "default.child", "pos='0,-20';size='[X]x[Y]'") + + else + winset(src, "[ckey(Home.name)].child", "[pos]='[ckey(Home.name)].who'") + winset(src, "[ckey(Home.name)].online", "is-visible=true") + src.showwho = TRUE + if(Host == src) winset(src, "host.who_toggle", "is-checked=true;") + else winset(src, "menu.who_toggle", "is-checked=true;") + if(!showtopic) + var/size = winget(src, "default.child", "size") + var/X = copytext(size, 1, findtext(size, "x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))-20 + winset(src, "default.child", "pos='0,0';size='[X]x[Y]'") + if(!nosave) + winsize = winget(src, "default", "size") + ChatMan.Save(src) + + ToggleQuickBar(nosave as num|null) + set hidden = 1 + if(!Chan) return + var/i + var/size = winget(src, "[ckey(Home.name)].child", "size") + var/seperator = findtext(size, "x") + var/X = copytext(size,1,seperator) + var/Y = text2num(copytext(size,seperator+1)) + var/window = ckey(Home.name) + if(src.quickbar) + Y += 16 + for(i=1, i<=5, i++) + winset(src, "[window].tag[i]","is-visible=false") + for(i=1, i<=6, i++) + winset(src, "[window].smiley[i]","is-visible=false") + for(i=1, i<=7, i++) + winset(src, "[window].color[i]","is-visible=false") + winset(src, "[window].toggle_quickbar", "text='+'") + quickbar = FALSE + if(Host == src) winset(src, "host.quickbar_toggle", "is-checked=false;") + else winset(src, "menu.quickbar_toggle", "is-checked=false;") + else + Y -= 16 + for(i=1, i<=5, i++) + winset(src, "[window].tag[i]","is-visible=true") + for(i=1, i<=6, i++) + winset(src, "[window].smiley[i]","is-visible=true") + for(i=1, i<=7, i++) + winset(src, "[window].color[i]","is-visible=true") + winset(src, "[window].toggle_quickbar", "text='-'") + quickbar = TRUE + if(Host == src) winset(src, "host.quickbar_toggle", "is-checked=true;") + else winset(src, "menu.quickbar_toggle", "is-checked=true;") + winset(src, null, "[window].child.size=[X]x[Y];\ + [window].default_input.focus=true;") + if(!nosave) + winsize = winget(src, "default", "size") + ChatMan.Save(src) + + + ToggleCIMBar(window as text|null) + set hidden = 1 + if(!window) return + window = "cim_[ckey(window)]" + var/i + + var/outsize = winget(src, "[window].output", "size") + var/outseperator = findtext(outsize, "x") + var/outX = copytext(outsize,1,outseperator) + var/outY = text2num(copytext(outsize,outseperator+1)) + + var/profpos = winget(src, "[window].profile", "pos") + var/profseperator = findtext(profpos, ",") + var/profX = copytext(profpos,1,profseperator) + var/profY = text2num(copytext(profpos,profseperator+1)) + + var/showpos = winget(src, "[window].show", "pos") + var/showseperator = findtext(showpos, ",") + var/showX = copytext(showpos,1,showseperator) + var/showY = text2num(copytext(showpos,showseperator+1)) + + var/sharepos = winget(src, "[window].share", "pos") + var/shareseperator = findtext(sharepos, ",") + var/shareX = copytext(sharepos,1,shareseperator) + var/shareY = text2num(copytext(sharepos,shareseperator+1)) + + var/invpos = winget(src, "[window].invite", "pos") + var/invseperator = findtext(invpos, ",") + var/invX = copytext(invpos,1,invseperator) + var/invY = text2num(copytext(invpos,invseperator+1)) + + var/joinpos = winget(src, "[window].join", "pos") + var/joinseperator = findtext(joinpos, ",") + var/joinX = copytext(joinpos,1,joinseperator) + var/joinY = text2num(copytext(joinpos,joinseperator+1)) + + if(winget(src, "[window].tag1", "is-visible") == "true") + outY += 20 + profY += 20 + showY += 20 + shareY += 20 + invY += 20 + joinY += 20 + for(i=1, i<=3, i++) + winset(src, "[window].tag[i]","is-visible=false") + for(i=1, i<=6, i++) + winset(src, "[window].smiley[i]","is-visible=false") + for(i=1, i<=7, i++) + winset(src, "[window].color[i]","is-visible=false") + winset(src, "[window].toggle_quickbar", "text='+'") + else + outY -= 20 + profY -= 20 + showY -= 20 + shareY -= 20 + invY -= 20 + joinY -= 20 + for(i=1, i<=3, i++) + winset(src, "[window].tag[i]","is-visible=true") + for(i=1, i<=6, i++) + winset(src, "[window].smiley[i]","is-visible=true") + for(i=1, i<=7, i++) + winset(src, "[window].color[i]","is-visible=true") + winset(src, "[window].toggle_quickbar", "text='-'") + winset(src, "[window].profile", "pos=[profX],[profY]") + winset(src, "[window].show", "pos=[showX],[showY]") + winset(src, "[window].share", "pos=[shareX],[shareY]") + winset(src, "[window].invite", "pos=[invX],[invY]") + winset(src, "[window].join", "pos=[joinX],[joinY]") + winset(src, "[window].output", "size=[outX]x[outY]") + winset(src, "[window].input", "focus=true") + + NewInstantMessage() + set hidden = 1 + var/Messenger/im = new(src) + im.Display(src) + + ShowGameWindow() + set hidden = 1 + winshow(src, "game", 1) + + HideGameWindow() + set hidden = 1 + winshow(src, "game", 0) + + ShowChattersMail() + set hidden = 1 + winshow(src, "cmail", 1) + + HideChattersMail() + set hidden = 1 + winshow(src, "cmail", 0) + + ShowAbout() + set hidden = 1 + winshow(src, "about", 1) + + HideAbout() + set hidden = 1 + winshow(src, "about", 0) + + ShowCredits() + set hidden = 1 + winshow(src, "credits", 1) + + HideCredits() + set hidden = 1 + winshow(src, "credits", 0) + + ShowPublicChannels() + set hidden = 1 + winshow(src, "pub_chans", 1) + + HidePublicChannels() + set hidden = 1 + winshow(src, "pub_chans", 0) + + ShowHelp(t as text|null) + set hidden = 1 + if(!t) t = "index" + var/HelpView/HV = new() + HV.Display(src, t) + del(HV) + winshow(src, "help", 1) + + HideHelp() + set hidden = 1 + winshow(src, "help", 0) + + SearchHelp(t as text|null) + set hidden = 1 + if(!t) t = winget(src, "help.search", "text") + else winset(src, "help.search", "text='[t]'") + var/HelpView/HV = new() + HV.Display(src, "search", t) + del(HV) + + ShowProfile() + set hidden = 1 + src << output(null, "profile.output") + if(src.picture) src << output("\...", "profile.output") + else + src << output("\...", "profile.output") + winset(src, "profile.key", "text=' [src.name]") + winset(src, "profile.age", "text=' [src.age]") + winset(src, "profile.gender", "text=' [src.gender]") + winset(src, "profile.location", "text=' [src.location]") + winset(src, "profile.description", "text=' [src.description]") + winset(src, "profile.interests", "text=' [src.interests]") + winset(src, "profile", "is-visible=true") + winset(src, "profile.im_button", "command='IM \"[src.name]\"';") + + HideProfile() + set hidden = 1 + winshow(src, "profile", 0) + + SelectColor(scope as text|null) + set hidden = 1 + if(!scope) return + CV.Display(scope) + + InsertColor(color as text|null, window as text|null) + set hidden = 1 + if(!color) return + if(!Chan) return + var/input + if(!window) + window = "[ckey(Home.name)]" + input = "default_input" + else + window = "cim_[ckey(window)]" + input = "input" + var/msg_value = winget(src, "[window].[input]", "text") + var/down = winget(src, "[window].[color]", "is-checked") + if(down == "false") + msg_value += "\[/#]" + var/index = text2num(copytext(color, 6)) + src.Colors[src.Colors[index]] = null + winset(src, "[window].[color]", "text=''") + else + for(var/i=1,i<=7,i++) + var/C = src.Colors[i] + if(src.Colors[C] == "selected") + msg_value += "\[/#]" + src.Colors[C] = null + winset(src, "[window].color[i]", "text=''") + winset(src, "[window].color[i]", "is-checked=false") + switch(color) + if("color1") + msg_value += "\[[src.Colors[1]]]" + src.Colors[src.Colors[1]] = "selected" + if("color2") + msg_value += "\[[src.Colors[2]]]" + src.Colors[src.Colors[2]] = "selected" + if("color3") + msg_value += "\[[src.Colors[3]]]" + src.Colors[src.Colors[3]] = "selected" + if("color4") + msg_value += "\[[src.Colors[4]]]" + src.Colors[src.Colors[4]] = "selected" + if("color5") + msg_value += "\[[src.Colors[5]]]" + src.Colors[src.Colors[5]] = "selected" + if("color6") + msg_value += "\[[src.Colors[6]]]" + src.Colors[src.Colors[6]] = "selected" + if("color7") + msg_value += "\[[src.Colors[7]]]" + src.Colors[src.Colors[7]] = "selected" + winset(src, "[window].[color]", "text='*'") + winset(src, "[window].[input]", "text='[TextMan.escapeQuotes(msg_value)]'") + winset(src, "[window].[input]", "focus=true") + + InsertTag(tag as text|null, window as text|null) + set hidden = 1 + if(!tag) return + if(!Chan) return + var/input + if(!window) + window = "[ckey(Home.name)]" + input = "default_input" + else + window = "cim_[ckey(window)]" + input = "input" + var/msg_value = winget(src, "[window].[input]", "text") + var/down = winget(src, "[window].[tag]", "is-checked") + switch(tag) + if("tag1") + var/open = src.Tags[1] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + if("tag2") + var/open = src.Tags[2] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + if("tag3") + var/open = src.Tags[3] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + if("tag4") + var/open = src.Tags[4] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + if("tag5") + var/open = src.Tags[5] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + winset(src, "[window].[input]", "text='[TextMan.escapeQuotes(msg_value)]'") + winset(src, "[window].[input]", "focus=true") + + InsertSmiley(smiley as text|null, window as text|null) + set hidden = 1 + if(!smiley) return + if(!Chan) return + if(!window) window = "[ckey(Home.name)].default_input" + else window = "cim_[ckey(window)].input" + var/msg_value = winget(src, "[window]", "text") + switch(smiley) + if("smiley1") + msg_value += src.Smileys[1] + if("smiley2") + msg_value += src.Smileys[2] + if("smiley3") + msg_value += src.Smileys[3] + if("smiley4") + msg_value += src.Smileys[4] + if("smiley5") + msg_value += src.Smileys[5] + if("smiley6") + msg_value += src.Smileys[6] + winset(src, "[window]", "text='[TextMan.escapeQuotes(msg_value)]'") + winset(src, "[window]", "focus=true") + + Join() + set hidden = 1 + if(afk) ReturnAFK() + ChanMan.Join(src, Home) + + Quit() + set hidden = 1 + ChanMan.Quit(src, Home) + + SayAlias(msg as text|null) + set name = ">" + Say(msg) diff --git a/code/world.dm b/code/world.dm index 9d31963..1058823 100644 --- a/code/world.dm +++ b/code/world.dm @@ -1,51 +1,46 @@ - -world - version = 0 - name = "Chatters" - hub = "Xooxer.Chatters" - hub_password = "rbl9FQ0hzWtOEKtg" // my eyes only 0_0 - - view = "13x11" - - cache_lifespan = 1 - - mob = /mob/Temp // default temporary mob - turf = /turf/void // default temporary turf - visibility = 1 // Set to 0 in LoadServerCfg if we're not public, leave otherwise. - - New() - var/rsc_check = VerifyResources() - if(!rsc_check) - spawn(10) - if(Host && Host.client) - Host << output("Chatters.rsc is missing, corrupt or out of date!\nPlease check your Options & Messages and correct the error.\nShutting down...", "main_menu_output.output") - del(src) - else if(rsc_check == "unpakit") // Unpack the hosting package - var/zipfile/Z = new("./Chatters.zip") // Dantom.zipfile ftw! - for(var/z in Z.Flist()) Z.Export("./", z) // export host files here - Reboot() // Restart server to ensure proper boot environment - ..() - Console = new() // spawn the Console <-- This starts everything else - swapmaps_mode = SWAPMAPS_SAV // set SwapMaps to use savfiles - - Del() - Export("[NetMan.addr]:[NetMan.port]?dest=chanman&action=delserver") - del(Console) // last ditch effort to save before the world dies - ..() - - - Topic(Text,Addr) - ..() - Text+="&addr=[Addr]" - Console.Topic(Text) - - - OpenPort(Port) - if(isnull(Port)) - NetMan.Disconnect() - return - Port = NetMan.PreConnect(Port) - var/oldport = port - ..() - NetMan.PostConnect(Port, oldport) - + +world + version = 0 + name = "Chatters" + hub = "Xooxer.Chatters" + hub_password = "rbl9FQ0hzWtOEKtg" // my eyes only 0_0 + + view = "13x11" + + cache_lifespan = 1 + + mob = /mob/Temp // default temporary mob + turf = /turf/void // default temporary turf + visibility = 1 // Set to 0 in LoadServerCfg if we're not public, leave otherwise. + + New() + var/rsc_check = VerifyResources() + if(!rsc_check) + spawn(10) + if(Host && Host.client) + Host << output("Chatters.rsc is missing, corrupt or out of date!\nPlease check your Options & Messages and correct the error.\nShutting down...", "main_menu_output.output") + del(src) + else if(rsc_check == "unpakit") // Unpack the hosting package + var/zipfile/Z = new("./Chatters.zip") // Dantom.zipfile ftw! + for(var/z in Z.Flist()) Z.Export("./", z) // export host files here + Reboot() // Restart server to ensure proper boot environment + ..() + Console = new() // spawn the Console <-- This starts everything else + swapmaps_mode = SWAPMAPS_SAV // set SwapMaps to use savfiles + + Del() + del(Console) // last ditch effort to save before the world dies + ..() + + + Topic(Text,Addr) + ..() + Text+="&addr=[Addr]" + Console.Topic(Text) + + + OpenPort(Port) + if(isnull(Port)) + return + ..() + From fd3f4fb99b062804588772241b09f858ba60be33 Mon Sep 17 00:00:00 2001 From: Stephen Badger Date: Thu, 14 Jun 2012 21:22:47 +0100 Subject: [PATCH 04/15] Updates gitignore to ignore release zip Updates gitignore to ignore release zip. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9177790..466e840 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ changes *.rsc *.int *.lk +Chatters.zip data/saves/logs data/saves/channels packet From db9cf799ad4cb4e74f26b04b0c1e4f3e69060f52 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Jun 2012 18:48:05 -0400 Subject: [PATCH 05/15] Removed telnet echo. Telnet command defaults to Say(). Escape commands with "/". Update who no longer updates telnet clients. Telnet login() disallows multiple logins. Filter toggle altered to allow toggle despite unrecognized arguments. --- Chatters.dme | 74 +++++++++++++++++++++++++++++++++ code/_global.dm | 3 -- code/client.dm | 21 +++++----- code/models/channel.dm | 12 +----- code/models/chatter/commands.dm | 9 ++-- 5 files changed, 92 insertions(+), 27 deletions(-) diff --git a/Chatters.dme b/Chatters.dme index a5a2efa..4c337bd 100644 --- a/Chatters.dme +++ b/Chatters.dme @@ -6,6 +6,80 @@ // END_INTERNALS // BEGIN_FILE_DIR #define FILE_DIR . +#define FILE_DIR ".git" +#define FILE_DIR ".git/hooks" +#define FILE_DIR ".git/info" +#define FILE_DIR ".git/logs" +#define FILE_DIR ".git/logs/refs" +#define FILE_DIR ".git/logs/refs/heads" +#define FILE_DIR ".git/logs/refs/remotes" +#define FILE_DIR ".git/logs/refs/remotes/origin" +#define FILE_DIR ".git/objects" +#define FILE_DIR ".git/objects/pack" +#define FILE_DIR ".git/refs" +#define FILE_DIR ".git/refs/heads" +#define FILE_DIR ".git/refs/remotes" +#define FILE_DIR ".git/refs/remotes/origin" +#define FILE_DIR "code" +#define FILE_DIR "code/controllers" +#define FILE_DIR "code/controllers/managers" +#define FILE_DIR "code/libraries" +#define FILE_DIR "code/libraries/rc5" +#define FILE_DIR "code/libraries/s_smiley" +#define FILE_DIR "code/libraries/swapmaps" +#define FILE_DIR "code/libraries/syntaxhighlighter" +#define FILE_DIR "code/libraries/test" +#define FILE_DIR "code/libraries/texthandling" +#define FILE_DIR "code/libraries/xml" +#define FILE_DIR "code/libraries/zipfile" +#define FILE_DIR "code/models" +#define FILE_DIR "code/models/chatter" +#define FILE_DIR "code/models/painter" +#define FILE_DIR "code/views" +#define FILE_DIR "code/views/color" +#define FILE_DIR "code/views/games" +#define FILE_DIR "code/views/help" +#define FILE_DIR "code/views/open_chan" +#define FILE_DIR "code/views/ops" +#define FILE_DIR "code/views/paint" +#define FILE_DIR "code/views/set" +#define FILE_DIR "code/views/set/style" +#define FILE_DIR "data" +#define FILE_DIR "data/saves" +#define FILE_DIR "data/saves/channels" +#define FILE_DIR "data/saves/logs" +#define FILE_DIR "data/sndfx" +#define FILE_DIR "data/xml" +#define FILE_DIR "data/xml/help" +#define FILE_DIR "data/xml/help/topics" +#define FILE_DIR "data/xml/help/topics/1" +#define FILE_DIR "data/xml/help/topics/1/1" +#define FILE_DIR "data/xml/help/topics/1/2" +#define FILE_DIR "data/xml/help/topics/4" +#define FILE_DIR "data/xml/help/topics/4/2" +#define FILE_DIR "data/xml/help/topics/4/3" +#define FILE_DIR "data/xml/help/topics/4/3/1" +#define FILE_DIR "data/xml/help/topics/4/3/4" +#define FILE_DIR "data/xml/help/topics/4/8" +#define FILE_DIR "data/xml/help/topics/5" +#define FILE_DIR "data/xml/ops" +#define FILE_DIR "data/xml/ops/privileges" +#define FILE_DIR "data/xml/ops/ranks" +#define FILE_DIR "data/xml/quotes" +#define FILE_DIR "resources" +#define FILE_DIR "resources/icons" +#define FILE_DIR "resources/icons/atoms" +#define FILE_DIR "resources/icons/paint" +#define FILE_DIR "resources/icons/smileys" +#define FILE_DIR "resources/images" +#define FILE_DIR "resources/images/hangman" +#define FILE_DIR "resources/images/interface" +#define FILE_DIR "resources/images/interface/arrows" +#define FILE_DIR "resources/images/interface/locks" +#define FILE_DIR "resources/images/menu" +#define FILE_DIR "resources/images/smileys" +#define FILE_DIR "resources/maps" +#define FILE_DIR "resources/notes" // END_FILE_DIR #define FILE_DIR "resources" diff --git a/code/_global.dm b/code/_global.dm index bf67a99..1b1035c 100644 --- a/code/_global.dm +++ b/code/_global.dm @@ -53,9 +53,6 @@ // File Size Limit #define MAX_FILE_SIZE 5242880 // 5 Megabytes -// telnet echo ON -#define VERBOSE 1 - // Used to enable debugging output with debug() #define DEV_DEBUG diff --git a/code/client.dm b/code/client.dm index cad8988..057c3f2 100644 --- a/code/client.dm +++ b/code/client.dm @@ -13,16 +13,17 @@ client Command(command) - if(ChatMan.istelnet(key) && VERBOSE) //verbose - src << "[command]" - - var pos = findtext(command, " ") - var cmd = copytext(command, 1, pos) - var params - if(pos) params = copytext(command, pos + 1) - for(var/v in mob.verbs) - if(ckey(cmd) == ckey(v:name)) - call(mob, v:name)(params) + var/success=0 + if(findtext(command,"/",1,2)) + var/pos = findtext(command, " ") + var/cmd = copytext(command, 2, pos) + var/params + if(pos) params = copytext(command, pos + 1) + for(var/v in mob.verbs) + if(ckey(cmd) == ckey(v:name)) + call(mob, v:name)(params) + success=1 + if(!success) call(mob, "Say")(command) ..(command) verb diff --git a/code/models/channel.dm b/code/models/channel.dm index bff59e4..12c0e10 100644 --- a/code/models/channel.dm +++ b/code/models/channel.dm @@ -256,21 +256,11 @@ Channel UpdateWho() - //telnet update who - var chatter_array[] = list() - for(var/mob/chatter/C in chatters) - chatter_array += "[dd_replacetext(C.name, " ", "+")][C.afk ? "~" : ""]" - var display = dd_list2text(chatter_array, ",") - - for(var/mob/chatter/C in chatters) var/active = chatters.len - if(ChatMan.istelnet(C.key)) - C << ".who [display]" - - else + if(!ChatMan.istelnet(C.key)) for(var/i=1, i<=chatters.len, i++) var/mob/chatter/c = chatters[i] if(isnull(c)) diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 0113ae2..3bd8a90 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -65,8 +65,8 @@ mob login(telnet_key as text|null) set hidden = 1 - if(!telnet_key) return - if(!telnet) return + if(!telnet_key || !telnet) return + for(var/client/C) if(C.key && C.key==telnet_key) return var/savefile/S = new("./data/saves/tel.net") if(!S || !length(S)) return var/list/L = new @@ -596,4 +596,7 @@ mob switch(ckey(msg)) if("on","1") filter=2 if("off","0") filter=0 - src << "Filter set [msg]" \ No newline at end of file + else + if(!filter) filter=2 + else filter=0 + src << "Filter is now [filter ? "on" : "off"]." \ No newline at end of file From 102b3ed771d163e501380d4450dc116e64a1aef7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Jun 2012 21:38:54 -0400 Subject: [PATCH 06/15] Minor filter update. --- code/models/chatter/commands.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 3bd8a90..7822a68 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -596,7 +596,5 @@ mob switch(ckey(msg)) if("on","1") filter=2 if("off","0") filter=0 - else - if(!filter) filter=2 - else filter=0 + else filter=(!filter && 2) src << "Filter is now [filter ? "on" : "off"]." \ No newline at end of file From 88912520f5051360c93a6dc334050eb67393b608 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Jun 2012 12:41:20 -0400 Subject: [PATCH 07/15] Multi-login check checks other telnet logins as well. --- Chatters.dme | 25 +++++++++++++++++++++++-- code/models/chatter/commands.dm | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Chatters.dme b/Chatters.dme index 4c337bd..29a8648 100644 --- a/Chatters.dme +++ b/Chatters.dme @@ -15,11 +15,32 @@ #define FILE_DIR ".git/logs/refs/remotes" #define FILE_DIR ".git/logs/refs/remotes/origin" #define FILE_DIR ".git/objects" +#define FILE_DIR ".git/objects/05" +#define FILE_DIR ".git/objects/10" +#define FILE_DIR ".git/objects/12" +#define FILE_DIR ".git/objects/18" +#define FILE_DIR ".git/objects/1b" +#define FILE_DIR ".git/objects/1c" +#define FILE_DIR ".git/objects/1f" +#define FILE_DIR ".git/objects/25" +#define FILE_DIR ".git/objects/28" +#define FILE_DIR ".git/objects/38" +#define FILE_DIR ".git/objects/3b" +#define FILE_DIR ".git/objects/4c" +#define FILE_DIR ".git/objects/50" +#define FILE_DIR ".git/objects/56" +#define FILE_DIR ".git/objects/6b" +#define FILE_DIR ".git/objects/6f" +#define FILE_DIR ".git/objects/78" +#define FILE_DIR ".git/objects/79" +#define FILE_DIR ".git/objects/92" +#define FILE_DIR ".git/objects/ac" +#define FILE_DIR ".git/objects/db" +#define FILE_DIR ".git/objects/e1" +#define FILE_DIR ".git/objects/e9" #define FILE_DIR ".git/objects/pack" #define FILE_DIR ".git/refs" #define FILE_DIR ".git/refs/heads" -#define FILE_DIR ".git/refs/remotes" -#define FILE_DIR ".git/refs/remotes/origin" #define FILE_DIR "code" #define FILE_DIR "code/controllers" #define FILE_DIR "code/controllers/managers" diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 7822a68..806a148 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -66,7 +66,7 @@ mob login(telnet_key as text|null) set hidden = 1 if(!telnet_key || !telnet) return - for(var/client/C) if(C.key && C.key==telnet_key) return + for(var/mob/chatter/C in Home.chatters) if((C.key && C.key==telnet_key) || C.name==telnet_key) return var/savefile/S = new("./data/saves/tel.net") if(!S || !length(S)) return var/list/L = new From 9d6981952675c24255c2060ecd992a783cf50b4d Mon Sep 17 00:00:00 2001 From: HiroTDK Date: Sat, 16 Jun 2012 15:26:06 -0400 Subject: [PATCH 08/15] Removed who() from /client. Command only uses verbs under /mob, making this useless. --- code/client.dm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/code/client.dm b/code/client.dm index 057c3f2..9d46eee 100644 --- a/code/client.dm +++ b/code/client.dm @@ -24,9 +24,4 @@ client call(mob, v:name)(params) success=1 if(!success) call(mob, "Say")(command) - ..(command) - - verb - who() - var /mob/chatter/c = mob - c.Chan.UpdateWho() \ No newline at end of file + ..(command) \ No newline at end of file From 3a9791a17e8a0d5b14f9d35c3da6688e63a5272b Mon Sep 17 00:00:00 2001 From: HiroTDK Date: Sat, 16 Jun 2012 15:27:02 -0400 Subject: [PATCH 09/15] GameManager.UpdateWho() no longer spams telnet clients. --- code/controllers/managers/gameman.dm | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/code/controllers/managers/gameman.dm b/code/controllers/managers/gameman.dm index 2cce34b..0893b7a 100644 --- a/code/controllers/managers/gameman.dm +++ b/code/controllers/managers/gameman.dm @@ -23,22 +23,12 @@ GameManager UpdateWho(Channel/Chan) if(!Chan || !Chan.players || !Chan.players.len) return - //telnet update who - var chatter_array[] = list() - for(var/mob/chatter/C in Chan.players) - chatter_array += "[dd_replacetext(C.name, " ", "+")][C.afk ? "~" : ""]" - var display = dd_list2text(chatter_array, ",") - - for(var/mob/chatter/C in Chan.players) var/players = 0 var/idle = 0 - if(ChatMan.istelnet(C.key)) - C << ".who [display]" - - else + if(!ChatMan.istelnet(C.key)) for(var/i=1, i<=Chan.players.len, i++) var/mob/chatter/c = Chan.players[i] if(C.client) winset(C, "games_who.grid", "current-cell=1,[i]") From 802671564f16176ce7210e1d04535fa00f9d0b01 Mon Sep 17 00:00:00 2001 From: HiroTDK Date: Sat, 16 Jun 2012 15:28:12 -0400 Subject: [PATCH 10/15] Welcome message no longer missing line break. AFK messages respects show_colors. --- code/models/channel.dm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/code/models/channel.dm b/code/models/channel.dm index 12c0e10..5e7ca66 100644 --- a/code/models/channel.dm +++ b/code/models/channel.dm @@ -186,7 +186,8 @@ Channel if(C.show_title) if(C.show_colors) C << output({"[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] -[world.name] - Created by Xooxerand the BYOND Community +[world.name] - Created by Xooxer +and the BYOND Community [TextMan.fadetext("Still the greatest chat program on BYOND!", list("102000000","255000000","102000000","000000000","000000255"))] Source available on the Chatters Repository. Copyright � 2008 Andrew "Xooxer" Arnold @@ -196,7 +197,8 @@ Channel else C << output({"########################################## -[world.name] - Created by Xooxerand the BYOND Community +[world.name] - Created by Xooxer +and the BYOND Community Still the greatest chat program on BYOND! Source available on the Chatters Repository. Copyright � 2008 Andrew "Xooxer" Arnold @@ -468,11 +470,11 @@ Channel for(var/mob/chatter/c in chatters) if(!(c.ignoring(C) & CHAT_IGNORE)) if(!c.filter) - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [raw_msg])", "[ckey(name)].chat.default_output") + c << output("[c.ParseTime()] [c.show_colors ? "[C.name]" : "[C.name]"] is now AFK. (Reason: [raw_msg])", "[ckey(name)].chat.default_output") else if(c.filter == 1) - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [TextMan.FilterChat(raw_msg,c)])", "[ckey(name)].chat.default_output") + c << output("[c.ParseTime()] [c.show_colors ? "[C.name]" : "[C.name]"] is now AFK. (Reason: [TextMan.FilterChat(raw_msg,c)])", "[ckey(name)].chat.default_output") else - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [msg])", "[ckey(name)].chat.default_output") + c << output("[c.ParseTime()] [c.show_colors ? "[C.name]" : "[C.name]"] is now AFK. (Reason: [msg])", "[ckey(name)].chat.default_output") C << output("Your activity status is now set to Away From Keyboard.", "[ckey(name)].chat.default_output") From 46312c45be5119126f83c91f35c43e800fb2c2ed Mon Sep 17 00:00:00 2001 From: HiroTDK Date: Sat, 16 Jun 2012 15:30:04 -0400 Subject: [PATCH 11/15] Disabled Send() for telnet clients. Added who() verb for telnet clients. --- Chatters.dme | 6 ++++ code/models/chatter/commands.dm | 57 +++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/Chatters.dme b/Chatters.dme index 29a8648..0274e3a 100644 --- a/Chatters.dme +++ b/Chatters.dme @@ -24,20 +24,26 @@ #define FILE_DIR ".git/objects/1f" #define FILE_DIR ".git/objects/25" #define FILE_DIR ".git/objects/28" +#define FILE_DIR ".git/objects/29" #define FILE_DIR ".git/objects/38" #define FILE_DIR ".git/objects/3b" #define FILE_DIR ".git/objects/4c" #define FILE_DIR ".git/objects/50" #define FILE_DIR ".git/objects/56" +#define FILE_DIR ".git/objects/5c" #define FILE_DIR ".git/objects/6b" #define FILE_DIR ".git/objects/6f" #define FILE_DIR ".git/objects/78" #define FILE_DIR ".git/objects/79" +#define FILE_DIR ".git/objects/80" +#define FILE_DIR ".git/objects/88" #define FILE_DIR ".git/objects/92" #define FILE_DIR ".git/objects/ac" +#define FILE_DIR ".git/objects/c1" #define FILE_DIR ".git/objects/db" #define FILE_DIR ".git/objects/e1" #define FILE_DIR ".git/objects/e9" +#define FILE_DIR ".git/objects/ea" #define FILE_DIR ".git/objects/pack" #define FILE_DIR ".git/refs" #define FILE_DIR ".git/refs/heads" diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 806a148..29d2fb8 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -29,6 +29,7 @@ mob if("unban") voteUnban (privilege, Rank, target) Send(target as text|null|mob in Home.chatters, file as file|null) + if(telnet) return if(!target) target = input("Who would you like to send a file to?", "Send File") as text|null if(!target) return @@ -63,29 +64,6 @@ mob C.Ignore(name,"files") alert("File ([file]) rejected by [C.name].","File Transfer Failed") - login(telnet_key as text|null) - set hidden = 1 - if(!telnet_key || !telnet) return - for(var/mob/chatter/C in Home.chatters) if((C.key && C.key==telnet_key) || C.name==telnet_key) return - var/savefile/S = new("./data/saves/tel.net") - if(!S || !length(S)) return - var/list/L = new - S["telnet"] >> L - if(!L || !L.len) return - var/key_hash = md5(telnet_key) - if(key_hash in L) - var/telnet_pass = input("Please enter your telnet password:", "Telnet Key Login") as password|null - if(!telnet_pass) - del(L) - return - if(L[key_hash] != md5(telnet_pass)) - del(L) - return - del(L) - name = telnet_key - fade_name = name - Home.UpdateWho() - Set() call(usr, "ShowSet")() @@ -597,4 +575,35 @@ mob if("on","1") filter=2 if("off","0") filter=0 else filter=(!filter && 2) - src << "Filter is now [filter ? "on" : "off"]." \ No newline at end of file + src << "Filter is now [filter ? "on" : "off"]." + + who() + set hidden = 1 + if(!telnet) return + var chatter_array[] = list() + for(var/mob/chatter/C in Home.chatters) + chatter_array += "[C.name][C.afk ? "\[AFK\]" : ""]" + src << "Chatters: [dd_list2text(chatter_array, ", ")]" + + login(telnet_key as text|null) + set hidden = 1 + if(!telnet_key || !telnet) return + for(var/mob/chatter/C in Home.chatters) if((C.key && C.key==telnet_key) || C.name==telnet_key) return + var/savefile/S = new("./data/saves/tel.net") + if(!S || !length(S)) return + var/list/L = new + S["telnet"] >> L + if(!L || !L.len) return + var/key_hash = md5(telnet_key) + if(key_hash in L) + var/telnet_pass = input("Please enter your telnet password:", "Telnet Key Login") as password|null + if(!telnet_pass) + del(L) + return + if(L[key_hash] != md5(telnet_pass)) + del(L) + return + del(L) + name = telnet_key + fade_name = name + Home.UpdateWho() From 34debcbf7e2d24a32b96cc00f88192c8a8215887 Mon Sep 17 00:00:00 2001 From: HiroTDK Date: Sat, 16 Jun 2012 22:12:03 -0400 Subject: [PATCH 12/15] Added help for telnet clients. --- Chatters.dme | 19 +++++++++++++++++++ code/models/chatter/commands.dm | 26 ++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Chatters.dme b/Chatters.dme index 0274e3a..98e6f57 100644 --- a/Chatters.dme +++ b/Chatters.dme @@ -15,9 +15,13 @@ #define FILE_DIR ".git/logs/refs/remotes" #define FILE_DIR ".git/logs/refs/remotes/origin" #define FILE_DIR ".git/objects" +#define FILE_DIR ".git/objects/02" #define FILE_DIR ".git/objects/05" +#define FILE_DIR ".git/objects/08" #define FILE_DIR ".git/objects/10" #define FILE_DIR ".git/objects/12" +#define FILE_DIR ".git/objects/14" +#define FILE_DIR ".git/objects/17" #define FILE_DIR ".git/objects/18" #define FILE_DIR ".git/objects/1b" #define FILE_DIR ".git/objects/1c" @@ -26,24 +30,39 @@ #define FILE_DIR ".git/objects/28" #define FILE_DIR ".git/objects/29" #define FILE_DIR ".git/objects/38" +#define FILE_DIR ".git/objects/3a" #define FILE_DIR ".git/objects/3b" +#define FILE_DIR ".git/objects/40" +#define FILE_DIR ".git/objects/46" +#define FILE_DIR ".git/objects/4a" #define FILE_DIR ".git/objects/4c" #define FILE_DIR ".git/objects/50" #define FILE_DIR ".git/objects/56" #define FILE_DIR ".git/objects/5c" +#define FILE_DIR ".git/objects/5d" +#define FILE_DIR ".git/objects/5e" +#define FILE_DIR ".git/objects/65" #define FILE_DIR ".git/objects/6b" #define FILE_DIR ".git/objects/6f" +#define FILE_DIR ".git/objects/76" #define FILE_DIR ".git/objects/78" #define FILE_DIR ".git/objects/79" #define FILE_DIR ".git/objects/80" #define FILE_DIR ".git/objects/88" #define FILE_DIR ".git/objects/92" +#define FILE_DIR ".git/objects/9d" +#define FILE_DIR ".git/objects/a2" #define FILE_DIR ".git/objects/ac" +#define FILE_DIR ".git/objects/b2" +#define FILE_DIR ".git/objects/b7" #define FILE_DIR ".git/objects/c1" +#define FILE_DIR ".git/objects/ce" #define FILE_DIR ".git/objects/db" +#define FILE_DIR ".git/objects/de" #define FILE_DIR ".git/objects/e1" #define FILE_DIR ".git/objects/e9" #define FILE_DIR ".git/objects/ea" +#define FILE_DIR ".git/objects/f0" #define FILE_DIR ".git/objects/pack" #define FILE_DIR ".git/refs" #define FILE_DIR ".git/refs/heads" diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 29d2fb8..a7ffeaf 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -65,10 +65,26 @@ mob alert("File ([file]) rejected by [C.name].","File Transfer Failed") Set() + if(telnet) return call(usr, "ShowSet")() Help() - ShowHelp() + if(!telnet) ShowHelp() + else + src << {"//--------------------Help--------------------\\ +All input is, by default, parsed into the chat. Input preceded by a backslash (/), up to the first space, will be interpreted as a command. If none is found, it shall be parsed into the chat. + +Valid Commands: +Login name - Attempts to login as \[name\]. +Say message - Sends message to chat. +Me/My emote - Emotes: "\[Name\] \[emote\]!" / "\[Name\]'s \[emote\]!" +Who - Displays list of current chatters. +Fiter state - Toggles the swearing filter. Valid states: on, off, 1, 0. All others simply toggle the filter. +Ignore/Unignore chatter - Ignore or stop ignoring specified chatter. +Ignoring - Displays list of ignored chatters. +Look - Displays information about the room. +\\---------------------------------------------// +"} Cmail() //ShowChattersMail() @@ -97,6 +113,7 @@ mob Chan.My(src, msg) IM(target as text|null|mob in Home.chatters, msg as text|null) + if(telnet) return if(!target) var/Messenger/im = new(src) im.Display(src) @@ -478,7 +495,7 @@ mob LookAt(t as text|null|mob in Home.chatters) - if(!t) return + if(!t || telnet) return var/mob/chatter/C if(ismob(t)) C = t else C = ChatMan.Get(t) @@ -505,6 +522,7 @@ mob winset(src, "profile.im_button", "command='IM \"[C.name]\"';") ShowCode(t as text|null|mob in Home.chatters) + if(telnet) return if(afk) ReturnAFK() var/showcode_snippet/S = new if(t) @@ -534,8 +552,8 @@ mob S.Send(1) ShowText(t as text|null|mob in Home.chatters) + if(telnet) return if(afk) ReturnAFK() - var/showcode_snippet/S = new if(t) var/mob/chatter/C @@ -564,7 +582,7 @@ mob S.Send() afk(msg as text|null) - if(!Chan) return + if(!Chan || telnet) return if(!afk) if(!msg) msg = auto_reason Home.GoAFK(src, msg) From f45d657b942d02c46a1246bbe790056a5a5a4b5f Mon Sep 17 00:00:00 2001 From: Stephen Badger Date: Fri, 13 Jul 2012 12:22:46 +0100 Subject: [PATCH 13/15] Revert "Removes Network Manager" This reverts commit e05d9e70d94cd629188cf7f6076b43a6e2b4b251. --- Chatters.dme | 336 ++---- code/_global.dm | 409 +++---- code/controllers/console.dm | 284 ++--- code/controllers/managers/chanman.dm | 604 +++++----- code/controllers/managers/chatman.dm | 363 +++--- code/controllers/managers/helpman.dm | 167 +-- code/controllers/managers/msgman.dm | 89 +- code/controllers/managers/netman.dm | 557 +++++----- code/controllers/managers/opman.dm | 259 ++--- code/models/channel.dm | 1532 +++++++++++++------------- code/models/chatter/_main.dm | 390 +++---- code/models/chatter/commands.dm | 1195 ++++++++++---------- code/models/chatter/controls.dm | 845 +++++++------- code/world.dm | 97 +- 14 files changed, 3564 insertions(+), 3563 deletions(-) diff --git a/Chatters.dme b/Chatters.dme index 60b3e50..a5a2efa 100644 --- a/Chatters.dme +++ b/Chatters.dme @@ -1,236 +1,100 @@ -// DM Environment file for Chatters CS.dme. -// All manual changes should be made outside the BEGIN_ and END_ blocks. -// New source code should be placed in .dm files: choose File/New --> Code File. - -// BEGIN_INTERNALS -// END_INTERNALS -// BEGIN_FILE_DIR -#define FILE_DIR . -#define FILE_DIR ".git" -#define FILE_DIR ".git/hooks" -#define FILE_DIR ".git/info" -#define FILE_DIR ".git/logs" -#define FILE_DIR ".git/logs/refs" -#define FILE_DIR ".git/logs/refs/heads" -#define FILE_DIR ".git/logs/refs/remotes" -#define FILE_DIR ".git/logs/refs/remotes/kevans" -#define FILE_DIR ".git/logs/refs/remotes/origin" -#define FILE_DIR ".git/objects" -#define FILE_DIR ".git/objects/01" -#define FILE_DIR ".git/objects/04" -#define FILE_DIR ".git/objects/05" -#define FILE_DIR ".git/objects/09" -#define FILE_DIR ".git/objects/0a" -#define FILE_DIR ".git/objects/0d" -#define FILE_DIR ".git/objects/0e" -#define FILE_DIR ".git/objects/10" -#define FILE_DIR ".git/objects/12" -#define FILE_DIR ".git/objects/1d" -#define FILE_DIR ".git/objects/27" -#define FILE_DIR ".git/objects/37" -#define FILE_DIR ".git/objects/38" -#define FILE_DIR ".git/objects/3a" -#define FILE_DIR ".git/objects/3f" -#define FILE_DIR ".git/objects/41" -#define FILE_DIR ".git/objects/4b" -#define FILE_DIR ".git/objects/54" -#define FILE_DIR ".git/objects/55" -#define FILE_DIR ".git/objects/57" -#define FILE_DIR ".git/objects/5a" -#define FILE_DIR ".git/objects/5c" -#define FILE_DIR ".git/objects/61" -#define FILE_DIR ".git/objects/67" -#define FILE_DIR ".git/objects/6d" -#define FILE_DIR ".git/objects/79" -#define FILE_DIR ".git/objects/85" -#define FILE_DIR ".git/objects/86" -#define FILE_DIR ".git/objects/88" -#define FILE_DIR ".git/objects/89" -#define FILE_DIR ".git/objects/8a" -#define FILE_DIR ".git/objects/90" -#define FILE_DIR ".git/objects/92" -#define FILE_DIR ".git/objects/95" -#define FILE_DIR ".git/objects/9a" -#define FILE_DIR ".git/objects/9b" -#define FILE_DIR ".git/objects/a5" -#define FILE_DIR ".git/objects/ad" -#define FILE_DIR ".git/objects/af" -#define FILE_DIR ".git/objects/b1" -#define FILE_DIR ".git/objects/b3" -#define FILE_DIR ".git/objects/ba" -#define FILE_DIR ".git/objects/bb" -#define FILE_DIR ".git/objects/bd" -#define FILE_DIR ".git/objects/bf" -#define FILE_DIR ".git/objects/c1" -#define FILE_DIR ".git/objects/c4" -#define FILE_DIR ".git/objects/c6" -#define FILE_DIR ".git/objects/ca" -#define FILE_DIR ".git/objects/d0" -#define FILE_DIR ".git/objects/da" -#define FILE_DIR ".git/objects/e0" -#define FILE_DIR ".git/objects/e1" -#define FILE_DIR ".git/objects/e3" -#define FILE_DIR ".git/objects/e6" -#define FILE_DIR ".git/objects/ee" -#define FILE_DIR ".git/objects/f2" -#define FILE_DIR ".git/objects/fc" -#define FILE_DIR ".git/objects/fd" -#define FILE_DIR ".git/objects/fe" -#define FILE_DIR ".git/objects/pack" -#define FILE_DIR ".git/refs" -#define FILE_DIR ".git/refs/heads" -#define FILE_DIR ".git/refs/remotes" -#define FILE_DIR ".git/refs/remotes/kevans" -#define FILE_DIR ".git/refs/remotes/origin" -#define FILE_DIR ".git/refs/tags" -#define FILE_DIR "code" -#define FILE_DIR "code/controllers" -#define FILE_DIR "code/controllers/managers" -#define FILE_DIR "code/libraries" -#define FILE_DIR "code/libraries/rc5" -#define FILE_DIR "code/libraries/s_smiley" -#define FILE_DIR "code/libraries/swapmaps" -#define FILE_DIR "code/libraries/syntaxhighlighter" -#define FILE_DIR "code/libraries/test" -#define FILE_DIR "code/libraries/texthandling" -#define FILE_DIR "code/libraries/xml" -#define FILE_DIR "code/libraries/zipfile" -#define FILE_DIR "code/models" -#define FILE_DIR "code/models/chatter" -#define FILE_DIR "code/models/painter" -#define FILE_DIR "code/views" -#define FILE_DIR "code/views/color" -#define FILE_DIR "code/views/games" -#define FILE_DIR "code/views/help" -#define FILE_DIR "code/views/open_chan" -#define FILE_DIR "code/views/ops" -#define FILE_DIR "code/views/paint" -#define FILE_DIR "code/views/set" -#define FILE_DIR "code/views/set/style" -#define FILE_DIR "data" -#define FILE_DIR "data/saves" -#define FILE_DIR "data/saves/channels" -#define FILE_DIR "data/saves/logs" -#define FILE_DIR "data/sndfx" -#define FILE_DIR "data/xml" -#define FILE_DIR "data/xml/help" -#define FILE_DIR "data/xml/help/topics" -#define FILE_DIR "data/xml/help/topics/1" -#define FILE_DIR "data/xml/help/topics/1/1" -#define FILE_DIR "data/xml/help/topics/1/2" -#define FILE_DIR "data/xml/help/topics/4" -#define FILE_DIR "data/xml/help/topics/4/2" -#define FILE_DIR "data/xml/help/topics/4/3" -#define FILE_DIR "data/xml/help/topics/4/3/1" -#define FILE_DIR "data/xml/help/topics/4/3/4" -#define FILE_DIR "data/xml/help/topics/4/8" -#define FILE_DIR "data/xml/help/topics/5" -#define FILE_DIR "data/xml/ops" -#define FILE_DIR "data/xml/ops/privileges" -#define FILE_DIR "data/xml/ops/ranks" -#define FILE_DIR "data/xml/quotes" -#define FILE_DIR "resources" -#define FILE_DIR "resources/icons" -#define FILE_DIR "resources/icons/atoms" -#define FILE_DIR "resources/icons/paint" -#define FILE_DIR "resources/icons/smileys" -#define FILE_DIR "resources/images" -#define FILE_DIR "resources/images/hangman" -#define FILE_DIR "resources/images/interface" -#define FILE_DIR "resources/images/interface/arrows" -#define FILE_DIR "resources/images/interface/locks" -#define FILE_DIR "resources/images/menu" -#define FILE_DIR "resources/images/smileys" -#define FILE_DIR "resources/maps" -#define FILE_DIR "resources/notes" -// END_FILE_DIR -#define FILE_DIR "resources" - -// BEGIN_PREFERENCES -#define DEBUG -// END_PREFERENCES - -// BEGIN_INCLUDE -#include "code\_global.dm" -#include "code\client.dm" -#include "code\world.dm" -#include "code\controllers\console.dm" -#include "code\controllers\managers\botman.dm" -#include "code\controllers\managers\chanman.dm" -#include "code\controllers\managers\chatman.dm" -#include "code\controllers\managers\errman.dm" -#include "code\controllers\managers\eventman.dm" -#include "code\controllers\managers\gameman.dm" -#include "code\controllers\managers\helpman.dm" -#include "code\controllers\managers\listman.dm" -#include "code\controllers\managers\logman.dm" -#include "code\controllers\managers\mapman.dm" -#include "code\controllers\managers\msghand.dm" -#include "code\controllers\managers\msgman.dm" -#include "code\controllers\managers\opman.dm" -#include "code\controllers\managers\paintman.dm" -#include "code\controllers\managers\textman.dm" -#include "code\libraries\rc5\rc5.dm" -#include "code\libraries\s_smiley\alphabetics.dm" -#include "code\libraries\s_smiley\replacetext.dm" -#include "code\libraries\s_smiley\replaceword.dm" -#include "code\libraries\s_smiley\s_smiley.dm" -#include "code\libraries\swapmaps\SwapMaps.dm" -#include "code\libraries\syntaxhighlighter\SyntaxHighlighter.dm" -#include "code\libraries\test\Test.dm" -#include "code\libraries\texthandling\TextHandling.dm" -#include "code\libraries\xml\Element.dm" -#include "code\libraries\xml\Parser.dm" -#include "code\libraries\xml\Prolog.dm" -#include "code\libraries\xml\Tree.dm" -#include "code\libraries\xml\XML.dm" -#include "code\libraries\zipfile\zipfile.dm" -#include "code\models\atoms.dm" -#include "code\models\bot.dm" -#include "code\models\channel.dm" -#include "code\models\icons.dm" -#include "code\models\messenger.dm" -#include "code\models\op.dm" -#include "code\models\player.dm" -#include "code\models\showcode_snippet.dm" -#include "code\models\tempmob.dm" -#include "code\models\chatter\_main.dm" -#include "code\models\chatter\commands.dm" -#include "code\models\chatter\controls.dm" -#include "code\models\chatter\procs.dm" -#include "code\models\painter\_main.dm" -#include "code\models\painter\colorboxes.dm" -#include "code\models\painter\controls.dm" -#include "code\models\painter\procs.dm" -#include "code\models\painter\tools.dm" -#include "code\views\default.dmf" -#include "code\views\color\_main.dm" -#include "code\views\games\_main.dm" -#include "code\views\games\roll_play.dm" -#include "code\views\help\_main.dm" -#include "code\views\open_chan\_main.dm" -#include "code\views\open_chan\index.dm" -#include "code\views\open_chan\load_chan.dm" -#include "code\views\open_chan\new_chan.dm" -#include "code\views\ops\_main.dm" -#include "code\views\ops\general.dm" -#include "code\views\ops\privileges.dm" -#include "code\views\ops\ranks.dm" -#include "code\views\paint\_main.dm" -#include "code\views\paint\canvas.dm" -#include "code\views\paint\pallete.dm" -#include "code\views\paint\window.dm" -#include "code\views\set\_main.dm" -#include "code\views\set\events.dm" -#include "code\views\set\filters.dm" -#include "code\views\set\general.dm" -#include "code\views\set\icons.dm" -#include "code\views\set\security.dm" -#include "code\views\set\style.dm" -#include "code\views\set\system.dm" -#include "code\views\set\style\colors.dm" -#include "code\views\set\style\default.dm" -#include "code\views\set\style\formats.dm" -// END_INCLUDE - - +// DM Environment file for Chatters CS.dme. +// All manual changes should be made outside the BEGIN_ and END_ blocks. +// New source code should be placed in .dm files: choose File/New --> Code File. + +// BEGIN_INTERNALS +// END_INTERNALS +// BEGIN_FILE_DIR +#define FILE_DIR . +// END_FILE_DIR +#define FILE_DIR "resources" + +// BEGIN_PREFERENCES +// END_PREFERENCES + +// BEGIN_INCLUDE +#include "code\_global.dm" +#include "code\client.dm" +#include "code\world.dm" +#include "code\controllers\console.dm" +#include "code\controllers\managers\botman.dm" +#include "code\controllers\managers\chanman.dm" +#include "code\controllers\managers\chatman.dm" +#include "code\controllers\managers\errman.dm" +#include "code\controllers\managers\eventman.dm" +#include "code\controllers\managers\gameman.dm" +#include "code\controllers\managers\helpman.dm" +#include "code\controllers\managers\listman.dm" +#include "code\controllers\managers\logman.dm" +#include "code\controllers\managers\mapman.dm" +#include "code\controllers\managers\msghand.dm" +#include "code\controllers\managers\msgman.dm" +#include "code\controllers\managers\netman.dm" +#include "code\controllers\managers\opman.dm" +#include "code\controllers\managers\paintman.dm" +#include "code\controllers\managers\textman.dm" +#include "code\libraries\rc5\rc5.dm" +#include "code\libraries\s_smiley\alphabetics.dm" +#include "code\libraries\s_smiley\replacetext.dm" +#include "code\libraries\s_smiley\replaceword.dm" +#include "code\libraries\s_smiley\s_smiley.dm" +#include "code\libraries\swapmaps\SwapMaps.dm" +#include "code\libraries\syntaxhighlighter\SyntaxHighlighter.dm" +#include "code\libraries\test\Test.dm" +#include "code\libraries\texthandling\TextHandling.dm" +#include "code\libraries\xml\Element.dm" +#include "code\libraries\xml\Parser.dm" +#include "code\libraries\xml\Prolog.dm" +#include "code\libraries\xml\Tree.dm" +#include "code\libraries\xml\XML.dm" +#include "code\libraries\zipfile\zipfile.dm" +#include "code\models\atoms.dm" +#include "code\models\bot.dm" +#include "code\models\channel.dm" +#include "code\models\host.dm" +#include "code\models\icons.dm" +#include "code\models\messenger.dm" +#include "code\models\op.dm" +#include "code\models\player.dm" +#include "code\models\showcode_snippet.dm" +#include "code\models\tempmob.dm" +#include "code\models\chatter\_main.dm" +#include "code\models\chatter\commands.dm" +#include "code\models\chatter\controls.dm" +#include "code\models\chatter\procs.dm" +#include "code\models\painter\_main.dm" +#include "code\models\painter\colorboxes.dm" +#include "code\models\painter\controls.dm" +#include "code\models\painter\procs.dm" +#include "code\models\painter\tools.dm" +#include "code\views\default.dmf" +#include "code\views\color\_main.dm" +#include "code\views\games\_main.dm" +#include "code\views\games\roll_play.dm" +#include "code\views\help\_main.dm" +#include "code\views\open_chan\_main.dm" +#include "code\views\open_chan\index.dm" +#include "code\views\open_chan\load_chan.dm" +#include "code\views\open_chan\new_chan.dm" +#include "code\views\ops\_main.dm" +#include "code\views\ops\general.dm" +#include "code\views\ops\privileges.dm" +#include "code\views\ops\ranks.dm" +#include "code\views\paint\_main.dm" +#include "code\views\paint\canvas.dm" +#include "code\views\paint\pallete.dm" +#include "code\views\paint\window.dm" +#include "code\views\set\_main.dm" +#include "code\views\set\events.dm" +#include "code\views\set\filters.dm" +#include "code\views\set\general.dm" +#include "code\views\set\icons.dm" +#include "code\views\set\security.dm" +#include "code\views\set\style.dm" +#include "code\views\set\system.dm" +#include "code\views\set\style\colors.dm" +#include "code\views\set\style\default.dm" +#include "code\views\set\style\formats.dm" +// END_INCLUDE + + diff --git a/code/_global.dm b/code/_global.dm index 2f985c7..bf67a99 100644 --- a/code/_global.dm +++ b/code/_global.dm @@ -1,204 +1,205 @@ - -/* Chatters Channel Server - -* Copyright (c) 2008, Andrew "Xooxer" Arnold -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the Chatters Network nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY Andrew "Xooxer" Arnold ``AS IS'' AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL Andrew "Xooxer" Arnold BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -// Preprocessor Definitions - -// Network Status -#define FAILED 0 -#define CONTACTING 1 -#define VALIDATING 2 -#define CONNECTING 3 -#define CONNECTED 4 - -#define LIKEABOSS 16 - -// Ignore Scopes -#define NO_IGNORE 0 -#define IM_IGNORE 1 -#define CHAT_IGNORE 2 -#define FADE_IGNORE 4 -#define COLOR_IGNORE 8 -#define SMILEY_IGNORE 16 -#define IMAGES_IGNORE 32 -#define FILES_IGNORE 64 -#define FULL_IGNORE 128 - -// File Size Limit -#define MAX_FILE_SIZE 5242880 // 5 Megabytes - -// telnet echo ON -#define VERBOSE 1 - -// Used to enable debugging output with debug() -#define DEV_DEBUG - -// Paint canvas dimensions -#define CANVASX 32 -#define CANVASY 32 - -// Number of Undos allowed to painters -#define UNDONUM 99 - -// Swap two variables -// pass an unused temporary -// variable C so you can swap A and B -#define swapVars(A,B,C) C=(A);A=(B);B=(C) - -#define drawbound(x1,y1,x2,y2,L) \ -do { \ - L += x1; L += y1;\ - L += x2; L += y1;\ - L += x1; L += y2;\ - L += x2; L += y2 \ -} while(0) - -#define fillbound(x1,y1,x2,y2,L,i) \ -do { \ - for(i=y1,i<=y2,i++) { \ - L += x1; L += i;\ - L += x2; L += i \ - } \ -} while(0) - -// Global variables and procedures -var/global - mob/chatter // Current Host of the Channel Server - Host - - ServerConsole // Main controller handles all managers - Console - - Channel // Main server channel - Home - - // Global Managers - BotManager/BotMan - ChannelManager/ChanMan - ChatterManager/ChatMan - ErrorManager/ErrMan - EventManager/EventMan - GameManager/GameMan - HelpManager/HelpMan - ListManager/ListMan - LogManager/LogMan - MapManager/MapMan - MessageManager/MsgMan - OperatorManager/OpMan - PaintManager/PaintMan - TextManager/TextMan - - savefile_version = "0.1.6" // savefile versioning to reduce needless wipes - - - - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** // - // ***** IF YOU FAIL TO UPDATE THIS YOUR SERVER WILL NOT START ***** // - // ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - - - rscHash = "69d0703e66f36405aef2192008066790" // verifies the rsc file - - // Use Chatters Utilities to generate the rscHash after altering - // the rsc file. Paste the generated text here so that your code - // knows the current hash for the updated rsc file. - - // If you modify the rsc (by either altering, creating or removing - // icons, by including, removing or altering sounds, by modifying - // the DMF, by changing the DMMs, or by including any library or - // code that does any of the above, etc) and you fail to update the - // rscHash vairable with the Chatters Utility program, your server - // will not start. Instead you will recieve: - - // Chatter.rsc is out of date! - - // and the server will close. - - - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** // - // ***** IF YOU FAIL TO UPDATE THIS YOUR SERVER WILL NOT START ***** // - // ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // - - - - list/debugs // debug messages saved when host is offline - - -proc -// Global Procedure Aliases - debug (text) return Console.debug(text) - islist (list/L) return ListMan.isList(L) - text2list (text) return TextMan.List(text) - list2text (list/L) return ListMan.Text(L) - listOpen (list/L) return ListMan.Open(L) - listAdd () return ListMan.Add(args) - listRemove () return ListMan.Remove(args) - listClose (list/L) return ListMan.Close(L) - invertList (list/L) return ListMan.Invert(L) - stack (list/L, item, list_len) return ListMan.Stack(L, item, list_len) - implode (list/words, separator) return TextMan.Implode(words, separator) - explode (text, separator) return TextMan.Explode(text, separator) - trim (text) return TextMan.Trim(text) - ltrim (text) return TextMan.lTrim(text) - rtrim (text) return TextMan.rTrim(text) - line (x0, y0, x1, y1) return PaintMan.line(x0, y0, x1, y1) - ellipse (x1, y1, x2, y2, fill) return PaintMan.ellipse(x1, y1, x2, y2, fill) - escapeQuotes(txt) return TextMan.escapeQuotes(txt) - - - VerifyResources() // Makes sure the rsc file is up to date - return 1 - if(!fexists("./Chatters.rsc")) - if(!fexists("./Chatters.zip")) - // ErrMan doesn't exist yet, so send to world.log directly - world.log << "\nChatters.rsc not found!" - world.log << "Please include the Chatters.rsc file with the Chatters.dmb." - return - else return "unpakit" - return 1 - var/F = file("./Chatters.rsc") - if(!isfile(F)) - world.log << "\nChatters.rsc is not a valid file!" - world.log << "Please include a valid Chatters.rsc file with the Chatters.dmb." - return - var/md5 = md5(F) - if(md5 != rscHash) - world.log << "\nChatters.rsc is out of date!" - world.log << "Please include the proper Chatters.rsc file with the Chatters.dmb, or use the Chatters Utilities program to generate an updated rscHash, and recompile the DMB file." - return - return 1 - + +/* Chatters Channel Server + +* Copyright (c) 2008, Andrew "Xooxer" Arnold +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the Chatters Network nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY Andrew "Xooxer" Arnold ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL Andrew "Xooxer" Arnold BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +// Preprocessor Definitions + +// Network Status +#define FAILED 0 +#define CONTACTING 1 +#define VALIDATING 2 +#define CONNECTING 3 +#define CONNECTED 4 + +#define LIKEABOSS 16 + +// Ignore Scopes +#define NO_IGNORE 0 +#define IM_IGNORE 1 +#define CHAT_IGNORE 2 +#define FADE_IGNORE 4 +#define COLOR_IGNORE 8 +#define SMILEY_IGNORE 16 +#define IMAGES_IGNORE 32 +#define FILES_IGNORE 64 +#define FULL_IGNORE 128 + +// File Size Limit +#define MAX_FILE_SIZE 5242880 // 5 Megabytes + +// telnet echo ON +#define VERBOSE 1 + +// Used to enable debugging output with debug() +#define DEV_DEBUG + +// Paint canvas dimensions +#define CANVASX 32 +#define CANVASY 32 + +// Number of Undos allowed to painters +#define UNDONUM 99 + +// Swap two variables +// pass an unused temporary +// variable C so you can swap A and B +#define swapVars(A,B,C) C=(A);A=(B);B=(C) + +#define drawbound(x1,y1,x2,y2,L) \ +do { \ + L += x1; L += y1;\ + L += x2; L += y1;\ + L += x1; L += y2;\ + L += x2; L += y2 \ +} while(0) + +#define fillbound(x1,y1,x2,y2,L,i) \ +do { \ + for(i=y1,i<=y2,i++) { \ + L += x1; L += i;\ + L += x2; L += i \ + } \ +} while(0) + +// Global variables and procedures +var/global + mob/chatter // Current Host of the Channel Server + Host + + ServerConsole // Main controller handles all managers + Console + + Channel // Main server channel + Home + + // Global Managers + BotManager/BotMan + ChannelManager/ChanMan + ChatterManager/ChatMan + ErrorManager/ErrMan + EventManager/EventMan + GameManager/GameMan + HelpManager/HelpMan + ListManager/ListMan + LogManager/LogMan + MapManager/MapMan + MessageManager/MsgMan + NetworkManager/NetMan + OperatorManager/OpMan + PaintManager/PaintMan + TextManager/TextMan + + savefile_version = "0.1.6" // savefile versioning to reduce needless wipes + + + + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** // + // ***** IF YOU FAIL TO UPDATE THIS YOUR SERVER WILL NOT START ***** // + // ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + + + rscHash = "69d0703e66f36405aef2192008066790" // verifies the rsc file + + // Use Chatters Utilities to generate the rscHash after altering + // the rsc file. Paste the generated text here so that your code + // knows the current hash for the updated rsc file. + + // If you modify the rsc (by either altering, creating or removing + // icons, by including, removing or altering sounds, by modifying + // the DMF, by changing the DMMs, or by including any library or + // code that does any of the above, etc) and you fail to update the + // rscHash vairable with the Chatters Utility program, your server + // will not start. Instead you will recieve: + + // Chatter.rsc is out of date! + + // and the server will close. + + + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** // + // ***** IF YOU FAIL TO UPDATE THIS YOUR SERVER WILL NOT START ***** // + // ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + // ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** // + + + + list/debugs // debug messages saved when host is offline + + +proc +// Global Procedure Aliases + debug (text) return Console.debug(text) + islist (list/L) return ListMan.isList(L) + text2list (text) return TextMan.List(text) + list2text (list/L) return ListMan.Text(L) + listOpen (list/L) return ListMan.Open(L) + listAdd () return ListMan.Add(args) + listRemove () return ListMan.Remove(args) + listClose (list/L) return ListMan.Close(L) + invertList (list/L) return ListMan.Invert(L) + stack (list/L, item, list_len) return ListMan.Stack(L, item, list_len) + implode (list/words, separator) return TextMan.Implode(words, separator) + explode (text, separator) return TextMan.Explode(text, separator) + trim (text) return TextMan.Trim(text) + ltrim (text) return TextMan.lTrim(text) + rtrim (text) return TextMan.rTrim(text) + line (x0, y0, x1, y1) return PaintMan.line(x0, y0, x1, y1) + ellipse (x1, y1, x2, y2, fill) return PaintMan.ellipse(x1, y1, x2, y2, fill) + escapeQuotes(txt) return TextMan.escapeQuotes(txt) + + + VerifyResources() // Makes sure the rsc file is up to date + return 1 + if(!fexists("./Chatters.rsc")) + if(!fexists("./Chatters.zip")) + // ErrMan doesn't exist yet, so send to world.log directly + world.log << "\nChatters.rsc not found!" + world.log << "Please include the Chatters.rsc file with the Chatters.dmb." + return + else return "unpakit" + return 1 + var/F = file("./Chatters.rsc") + if(!isfile(F)) + world.log << "\nChatters.rsc is not a valid file!" + world.log << "Please include a valid Chatters.rsc file with the Chatters.dmb." + return + var/md5 = md5(F) + if(md5 != rscHash) + world.log << "\nChatters.rsc is out of date!" + world.log << "Please include the proper Chatters.rsc file with the Chatters.dmb, or use the Chatters Utilities program to generate an updated rscHash, and recompile the DMB file." + return + return 1 + diff --git a/code/controllers/console.dm b/code/controllers/console.dm index 0bd441f..691a1bf 100644 --- a/code/controllers/console.dm +++ b/code/controllers/console.dm @@ -1,140 +1,144 @@ - -ServerConsole // main controller - New() - ..() - // start the server managers - ListMan = new() - TextMan = new() - BotMan = new() - OpMan = new() - ChanMan = new(src) - ChatMan = new() - ErrMan = new() - EventMan = new() - GameMan = new() - HelpMan = new() - LogMan = new() - MapMan = new() - MsgMan = new() - PaintMan = new() - - Del() - del(BotMan) - del(OpMan) - del(ChanMan) - del(ChatMan) - del(ErrMan) - del(EventMan) - del(HelpMan) - del(LogMan) - del(MapMan) - del(MsgMan) - del(PaintMan) - del(TextMan) - del(ListMan) - ..() - - Topic(href, href_list[]) - if(!href_list) href_list = params2list(href) - ..() - switch(href_list["dest"]) - if("chanman") - ChanMan.Topic(href, href_list) - if("chatman") - ChatMan.Topic(href, href_list) - if("helpman") - HelpMan.Topic(href, href_list) - if("msgman") - MsgMan.Topic(href, href_list) - - - proc - Show() - winshow(Host, "console", 1) - winset(Host, "console.input", "focus=true;") - - Hide() - winshow(Host, "console", 0) - - debug(T) - #ifdef DEV_DEBUG - if(!T) return - var/online - for(var/mob/M in world) - if((M.ckey in ChanMan.devs) && M.client) - if(!online) online = TRUE - M << output("[T]", "console.output") - winshow(M, "console", 1) - if(!online) - debugs = debugs || new() - debugs += T - #endif - - LoadCFG(cfg) - if(!cfg || !fexists(cfg)) return - - var/list/config=new(),list/lines=new(),head - var/txt,l,line,fchar,cbracket,phead,sep,comm,param,value - - txt = file2text(cfg) - if(!txt || !length(txt)) return - - lines = explode(txt, "\n") - if(!lines || !lines.len) return - - config += "main" - - for(l in lines) - line = trim(l) - if(!line) continue - - fchar = copytext(line, 1, 2) - - switch(fchar) - if(";") continue - - if("#") continue - - if("\[") - cbracket = findtext(line, "]") - if(!cbracket) continue - - if(head) - phead = config[config.len] - config[phead] = head - config += lowertext(copytext(line, 2, cbracket)) - head = null - continue - - else if(config.len==1) - config = new() - config += lowertext(copytext(line, 2, cbracket)) - continue - - else - phead = config[config.len] - config -= phead - config += lowertext(copytext(line, 2, cbracket)) - - else - sep = findtext(line, "=") - if(!sep) sep = findtext(line, ":") - if(!sep) continue - - comm = findtext(line, ";") - if(!comm) comm = findtext(line, "#") - if(comm && (comm < sep)) continue - if(sep == length(line)) continue - - param = lowertext(trim(copytext(line, 1, sep))) - value = trim(copytext(line, sep+1, comm)) - - if(head) head += "&"+param - else head = param - head += "="+value - - if(head) - phead = config[config.len] - config[phead] = head - - return config + +ServerConsole // main controller + New() + ..() + // start the server managers + ListMan = new() + TextMan = new() + BotMan = new() + OpMan = new() + ChanMan = new() + ChatMan = new() + ErrMan = new() + EventMan = new() + GameMan = new() + HelpMan = new() + LogMan = new() + MapMan = new() + MsgMan = new() + NetMan = new() + PaintMan = new() + + Del() + del(BotMan) + del(OpMan) + del(ChanMan) + del(ChatMan) + del(ErrMan) + del(EventMan) + del(HelpMan) + del(LogMan) + del(MapMan) + del(MsgMan) + del(NetMan) + del(PaintMan) + del(TextMan) + del(ListMan) + ..() + + Topic(href, href_list[]) + if(!href_list) href_list = params2list(href) + ..() + switch(href_list["dest"]) + if("chanman") + ChanMan.Topic(href, href_list) + if("chatman") + ChatMan.Topic(href, href_list) + if("helpman") + HelpMan.Topic(href, href_list) + if("msgman") + MsgMan.Topic(href, href_list) + if("netman") + NetMan.Topic(href, href_list) + + + proc + Show() + winshow(Host, "console", 1) + winset(Host, "console.input", "focus=true;") + + Hide() + winshow(Host, "console", 0) + + debug(T) + #ifdef DEV_DEBUG + if(!T) return + var/online + for(var/mob/M in world) + if((M.ckey in ChanMan.devs) && M.client) + if(!online) online = TRUE + M << output("[T]", "console.output") + winshow(M, "console", 1) + if(!online) + debugs = debugs || new() + debugs += T + #endif + + LoadCFG(cfg) + if(!cfg || !fexists(cfg)) return + + var/list/config=new(),list/lines=new(),head + var/txt,l,line,fchar,cbracket,phead,sep,comm,param,value + + txt = file2text(cfg) + if(!txt || !length(txt)) return + + lines = explode(txt, "\n") + if(!lines || !lines.len) return + + config += "main" + + for(l in lines) + line = trim(l) + if(!line) continue + + fchar = copytext(line, 1, 2) + + switch(fchar) + if(";") continue + + if("#") continue + + if("\[") + cbracket = findtext(line, "]") + if(!cbracket) continue + + if(head) + phead = config[config.len] + config[phead] = head + config += lowertext(copytext(line, 2, cbracket)) + head = null + continue + + else if(config.len==1) + config = new() + config += lowertext(copytext(line, 2, cbracket)) + continue + + else + phead = config[config.len] + config -= phead + config += lowertext(copytext(line, 2, cbracket)) + + else + sep = findtext(line, "=") + if(!sep) sep = findtext(line, ":") + if(!sep) continue + + comm = findtext(line, ";") + if(!comm) comm = findtext(line, "#") + if(comm && (comm < sep)) continue + if(sep == length(line)) continue + + param = lowertext(trim(copytext(line, 1, sep))) + value = trim(copytext(line, sep+1, comm)) + + if(head) head += "&"+param + else head = param + head += "="+value + + if(head) + phead = config[config.len] + config[phead] = head + + return config diff --git a/code/controllers/managers/chanman.dm b/code/controllers/managers/chanman.dm index 9608b8d..fbbbc7c 100644 --- a/code/controllers/managers/chanman.dm +++ b/code/controllers/managers/chanman.dm @@ -1,259 +1,345 @@ - -ChannelManager - var/host - var/port - var/telnet_pass - var/telnet_attempts - var/NameResult=1 - var/list/devs - - New(var/ServerConsole/console) - ..() - LoadServerCfg(console) - - Del() - if(Home) SaveChan(Home) - ..() - - Topic(href, href_list[]) - ..() - switch(href_list["action"]) - if("newchan") - NewChan(href_list) - if("loadchan") - Home = LoadChan(href_list["chan"]) - Home.chanbot = BotMan.LoadBot(Home) - ProcessChan() - if("delchan") - switch(alert("Are you sure you want to delete [href_list["chan"]]?", "Confirm Delete", "Yes", "No")) - if("Yes") DelChan(href_list["chan"]) - var/OpenChannel/OC = new() - OC.Display("load_chan") - del(OC) - - proc - NewChan(list/params) - var/Channel/Chan = new(params) - Home = Chan - ProcessChan() - - DelChan(chan) - fdel("./data/saves/channels/[chan].sav") - - isTaken(Name) - return 0 - - Join(mob/chatter/C, Channel/Chan) - Chan.Join(C) - - Quit(mob/chatter/C, Channel/Chan) - Chan.Quit(C) - - Say(mob/chatter/C, msg) - C.Chan.Say(C, msg) - - ProcessChan() - Home.LoadOps() - SaveChan(Home) - BotMan.SaveBot(Home.chanbot) - if(Host && Host.client) - call(Host,"Join")(Home) - winshow(Host, "open_chan", 0) - winset(Host, "main_menu.info_top", "text='Publishing channel to the network...'") - world.status = "[Home.name] founded by [Home.founder] - [(Home.chatters ? Home.chatters.len : 0)] chatter\s" - if(Home.publicity != "public") world.visibility = 0 - var/savefile/F = new("packet") - F["founder"] << Home.founder - F["name"] << Home.name - F["desc"] << Home.desc - F["topic"] << Home.topic - F["password"] << Home.pass - F["locked"] << Home.locked - F["chatters"] << (Home.chatters ? Home.chatters.len : 0) - F["supernode"] << Home.SuperNode - F["maxnodes"] << Home.MaxNodes - - SaveChan(Channel/Chan) - var/savefile/S = new("./data/saves/channels/[ckey(Chan.name)].sav") - S["founder"] << Chan.founder - S["name"] << Chan.name - S["publicity"] << Chan.publicity - S["desc"] << Chan.desc - S["room_desc"] << Chan.room_desc - S["room_desc_size"] << Chan.room_desc_size - S["topic"] << Chan.topic - S["pass"] << Chan.pass - S["locked"] << Chan.locked - S["telpass"] << Chan.telnet_pass - S["telatmpts"] << Chan.telnet_attempts - S["mute"] << Chan.mute - S["banned"] << Chan.banned - if(Chan.operators && Chan.operators.len) - var/list/ops = new() - for(var/cKey in Chan.operators) - var/Op/O = Chan.operators[cKey] - ops += O.name - ops[O.name] = O.Rank.pos - S["operators"] << ops - - LoadChan(chan, telpass, telatmpts) - var/savefile/S = new("./data/saves/channels/[ckey(chan)].sav") - var/Channel/Chan = new() - S["founder"] >> Chan.founder - S["name"] >> Chan.name - S["publicity"] >> Chan.publicity - S["desc"] >> Chan.desc - S["room_desc"] >> Chan.room_desc - S["room_desc_size"] >> Chan.room_desc_size - S["topic"] >> Chan.topic - S["pass"] >> Chan.pass - S["locked"] >> Chan.locked - Chan.telnet_pass = telnet_pass - Chan.telnet_attempts = telnet_attempts - if(!Chan.telnet_pass && telpass) Chan.telnet_pass = telpass - if(!Chan.telnet_attempts && telatmpts) Chan.telnet_attempts = telatmpts - S["mute"] >> Chan.mute - S["banned"] >> Chan.banned - return Chan - - LoadServerCfg(var/ServerConsole/console) - var/list/config = console.LoadCFG("./data/saves/server.cfg") - if(!config || !config.len) return - - var/list/H = params2list(config["main"]) - if(!H || !H.len) return - host = ckey(H["host"]) - port = text2num(H["port"]) - - var/list/D = params2list(config["devs"]) - if(D && D.len) - - if(!devs) devs = new - for(var/d in D) devs += ckey(D[d]) - - var/list/muteList = params2list(config["mute"]) - var/list/banList = params2list(config["bans"]) - var/list/opList = params2list(config["ops"]) - - var/list/S = params2list(config["server"]) - if(S && S.len) - - telnet_pass = S["telnet_pass"] - telnet_attempts = (text2num(S["telnet_attempts"]) || -1) - - var/AutoStart = text2num(S["auto_start"]) ? 1 : 0 - if(AutoStart) - var/HomeChan = S["home_chan"] - if(!HomeChan) - return - else if(!fexists("./data/saves/channels/[ckey(HomeChan)].sav")) - var/Password = S["password"] - var/Founder = S["founder"] - var/ChanDesc = S["desc"] - var/ChanTopic = S["topic"] - var/SuperNode = text2num(S["super_name"]) ? 1 : 0 - var/MaxNodes = text2num(S["max_nodes"]) - var/Publicity = S["publicity"] - var/Locked = S["locked"] - - var/botName = S["bot_name"] - var/botNameColor = S["bot_name_color"] - var/botTextColor = S["bot_text_color"] - - var/botSpamControls= text2num(S["bot_spam_control"]) ? 1 : 0 - var/botSpamLimit = text2num(S["bot_spam_limit"]) - var/botFloodLimit = text2num(S["bot_flood_limit"]) - var/botSmileysLimit= text2num(S["bot_smileys_limit"]) - var/botMaxMsgs = text2num(S["bot_max_msgs"]) - var/botMinDelay = text2num(S["bot_min_delay"]) - - Home = new(list( - "Founder"=Founder, - "Name"=HomeChan, - "Publicity"=Publicity, - "Desc"=ChanDesc, - "Topic"=ChanTopic, - "Pass"=Password, - "Locked"=Locked, - "TelPass"=telnet_pass, - "TelAtmpts"=telnet_attempts, - "SuperNode"=SuperNode, - "MaxNodes"=MaxNodes)) - if(Publicity != "public") world.visibility = 0 - - Home.chanbot.SetName(botName) - Home.chanbot.SetNameColor("#"+botNameColor) - Home.chanbot.SetTextColor("#"+botTextColor) - Home.chanbot.SetSpamControl(botSpamControls) - Home.chanbot.SetSpamLimit(botSpamLimit) - Home.chanbot.SetFloodLimit(botFloodLimit) - Home.chanbot.SetSmileysLimit(botSmileysLimit) - Home.chanbot.SetMaxMsgs(botMaxMsgs) - Home.chanbot.SetMinDelay(botMinDelay) - - if(muteList && muteList.len) - Home.mute = new - for(var/i in muteList) - Home.mute += ckey(i) - - if(banList && banList.len) - Home.banned = new - for(var/i in banList) - Home.banned += ckey(i) - - if(opList && opList.len) - Home.operators = new - for(var/Name in opList) - if(!findtext(Name, "_")) - var/opKey = ckey(opList[Name]) - var/rankIndex = text2num(opList["[Name]_level"]) -/* var/rankPrivs = opList[Name + "_privs"] // Not sure what to do with this. - if(rankPrivs != "default") - // Do something -*/ - var/OpRank/Rank = Home.op_ranks[rankIndex] - Home.operators[opKey] = new/Op(opList[Name], Rank) - - var/savefile/F = new() - F["founder"] << Home.founder - F["name"] << Home.name - F["desc"] << Home.desc - F["topic"] << Home.topic - F["password"] << Home.pass - F["locked"] << Home.locked - F["supernode"] << Home.SuperNode - F["maxnodes"] << Home.MaxNodes - if(Home.chatters) - F["chatters"] << Home.chatters.len - else - F["chatters"] << 0 - else - Home = LoadChan(HomeChan, telnet_pass, telnet_attempts) - Home.chanbot = BotMan.LoadBot(Home) - Home.LoadOps() - if(muteList && muteList.len) - Home.mute = listOpen(Home.mute) - for(var/i in muteList) - var/cval = ckey(i) - if(!(cval in Home.mute)) Home.mute += cval - - if(banList && banList.len) - Home.banned = listOpen(Home.banned) - for(var/i in banList) - var/cval = ckey(i) - if(!(cval in Home.banned)) Home.banned += cval - -/* if(opList && opList.len) - Home.operators = listOpen(Home.operators) - for(var/Name in opList) - if(!findtext(Name, "_")) - var/opKey = ckey(opList[Name]) - var/rankIndex = text2num(opList["[Name]_level"]) - var/rankPrivs = opList[Name + "_privs"] // Not sure what to do with this. - if(rankPrivs != "default") - // Do something -*/ - var/OpRank/Rank = Home.op_ranks[rankIndex] - Home.operators[opKey] = new/Op(opList[Name], Rank) - // TODO: Remove this once the Chatters Network is properly implemented. - world.OpenPort(port) \ No newline at end of file + +ChannelManager + var/host + var/telnet_pass + var/telnet_attempts + var/NameResult=1 + var/list/devs + + New() + ..() + spawn() + LoadServerCfg() + + Del() + if(Home) SaveChan(Home) + ..() + + Topic(href, href_list[]) + ..() + switch(href_list["action"]) + if("namecheck") + if(NetMan.Status != CONNECTED) + alert(Host, "You are not currently connected to the Chatters network. You may create a private channel, but you may need to change its name if you wish go connect publicly to the network.", "Unable to Check Name") + return + var/result = isTaken(href_list["Name"]) + if(result) alert(Host, "[href_list["Name"]] is already in use.", "Name Taken") + else alert(Host, "[href_list["Name"]] is free!", "Name Available") + if("newchan") + NewChan(href_list) + if("loadchan") + Home = LoadChan(href_list["chan"]) + Home.chanbot = BotMan.LoadBot(Home) + ProcessChan() + if("delchan") + switch(alert("Are you sure you want to delete [href_list["chan"]]?", "Confirm Delete", "Yes", "No")) + if("Yes") DelChan(href_list["chan"]) + var/OpenChannel/OC = new() + OC.Display("load_chan") + del(OC) + if("connected") + NetMan.Status = CONNECTED + if(Host && Host.client) + winset(Host, "main_menu.info_top", "text='Channel successfully published to the network.'") + sleep(30) + winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") + Host << output("Hosting [Home.name]", "main_menu_output.output") + NetMan.Query("getchans") + NetMan.Query("getchatters") + if("checkedname") + var/result = href_list["result"] + if(NameResult) + world.visibility = 0 + NetMan.Status = FAILED + if(Host && Host.client) + spawn() alert(Host, "The name you chose for your channel is already in use. Plaese choose a different name before reconnecting to the network.","Network Disconnected") + + else + if(result == "true") NameResult = TRUE + else NameResult = FALSE + + proc + NewChan(list/params) + var/Channel/Chan = new(params) + Home = Chan + ProcessChan() + + DelChan(chan) + fdel("./data/saves/channels/[chan].sav") + + isTaken(Name) + var/timeout = 300 + NameResult = null + world.Export("[NetMan.addr]:[NetMan.port]?dest=chanman&action=checkname&name=[Name]") + while(isnull(NameResult) && timeout--) sleep(1) + return NameResult + + Join(mob/chatter/C, Channel/Chan) + Chan.Join(C) + + Quit(mob/chatter/C, Channel/Chan) + Chan.Quit(C) + + Say(mob/chatter/C, msg) + C.Chan.Say(C, msg) + + ProcessChan() + Home.LoadOps() + SaveChan(Home) + BotMan.SaveBot(Home.chanbot) + if(Host && Host.client) + call(Host,"Join")(Home) + winshow(Host, "open_chan", 0) + winset(Host, "main_menu.info_top", "text='Publishing channel to the network...'") + world.status = "[Home.name] founded by [Home.founder] - [(Home.chatters ? Home.chatters.len : 0)] chatter\s" + if(Home.publicity != "public") world.visibility = 0 + var/savefile/F = new("packet") + F["founder"] << Home.founder + F["name"] << Home.name + F["desc"] << Home.desc + F["topic"] << Home.topic + F["password"] << Home.pass + F["locked"] << Home.locked + F["chatters"] << (Home.chatters ? Home.chatters.len : 0) + F["supernode"] << Home.SuperNode + F["maxnodes"] << Home.MaxNodes + NetMan.Status = CONNECTING + var/retries = NetMan.retry + spawn(20) + do + world.Export("[NetMan.addr]:[NetMan.port]?dest=chanman&action=connect",F) + sleep(NetMan.timeout) + if(NetMan.Status == CONNECTING) + if(Host && Host.client) winset(Host, "main_menu.info_top", "text='Connection timed out.'") + sleep(20) + if(!--retries) break + if(NetMan.Status == CONNECTING) + if(Host && Host.client) winset(Host, "main_menu.info_top", "text='Publishing channel to the network...'") + while(NetMan.Status == CONNECTING) + if(NetMan.Status == CONNECTING || NetMan.Status == FAILED) + NetMan.Status = FAILED + if(Host && Host.client) + winset(Host, "main_menu.info_top", "text='Problem contacting network!'") + winset(Host, "main_menu.cim", "is-disabled=true;") + winset(Host, "main_menu.public_chans", "is-disabled=true;") + winset(Host, "main_menu.cmail", "is-disabled=true;") + winset(Host, "main_menu.info_bottom", "text=") + fdel("packet") + + + SaveChan(Channel/Chan) + var/savefile/S = new("./data/saves/channels/[ckey(Chan.name)].sav") + S["founder"] << Chan.founder + S["name"] << Chan.name + S["publicity"] << Chan.publicity + S["desc"] << Chan.desc + S["room_desc"] << Chan.room_desc + S["room_desc_size"] << Chan.room_desc_size + S["topic"] << Chan.topic + S["pass"] << Chan.pass + S["locked"] << Chan.locked + S["telpass"] << Chan.telnet_pass + S["telatmpts"] << Chan.telnet_attempts + S["mute"] << Chan.mute + S["banned"] << Chan.banned + if(Chan.operators && Chan.operators.len) + var/list/ops = new() + for(var/cKey in Chan.operators) + var/Op/O = Chan.operators[cKey] + ops += O.name + ops[O.name] = O.Rank.pos + S["operators"] << ops + + LoadChan(chan, telpass, telatmpts) + var/savefile/S = new("./data/saves/channels/[ckey(chan)].sav") + var/Channel/Chan = new() + S["founder"] >> Chan.founder + S["name"] >> Chan.name + S["publicity"] >> Chan.publicity + S["desc"] >> Chan.desc + S["room_desc"] >> Chan.room_desc + S["room_desc_size"] >> Chan.room_desc_size + S["topic"] >> Chan.topic + S["pass"] >> Chan.pass + S["locked"] >> Chan.locked + Chan.telnet_pass = telnet_pass + Chan.telnet_attempts = telnet_attempts + if(!Chan.telnet_pass && telpass) Chan.telnet_pass = telpass + if(!Chan.telnet_attempts && telatmpts) Chan.telnet_attempts = telatmpts + S["mute"] >> Chan.mute + S["banned"] >> Chan.banned + return Chan + + LoadServerCfg() + var/list/config = Console.LoadCFG("./data/saves/server.cfg") + if(!config || !config.len) return + + var/list/H = params2list(config["main"]) + if(!H || !H.len) return + host = ckey(H["host"]) + NetMan.Port = text2num(H["port"]) + + var/list/D = params2list(config["devs"]) + if(D && D.len) + + if(!devs) devs = new + for(var/d in D) devs += ckey(D[d]) + + var/list/muteList = params2list(config["mute"]) + var/list/banList = params2list(config["bans"]) + var/list/opList = params2list(config["ops"]) + + var/list/S = params2list(config["server"]) + if(S && S.len) + + telnet_pass = S["telnet_pass"] + telnet_attempts = (text2num(S["telnet_attempts"]) || -1) + + var/AutoStart = text2num(S["auto_start"]) ? 1 : 0 + if(AutoStart) + var/HomeChan = S["home_chan"] + if(!HomeChan) + return + else if(!fexists("./data/saves/channels/[ckey(HomeChan)].sav")) + var/Password = S["password"] + var/Founder = S["founder"] + var/ChanDesc = S["desc"] + var/ChanTopic = S["topic"] + var/SuperNode = text2num(S["super_name"]) ? 1 : 0 + var/MaxNodes = text2num(S["max_nodes"]) + var/Publicity = S["publicity"] + var/Locked = S["locked"] + + var/botName = S["bot_name"] + var/botNameColor = S["bot_name_color"] + var/botTextColor = S["bot_text_color"] + + var/botSpamControls= text2num(S["bot_spam_control"]) ? 1 : 0 + var/botSpamLimit = text2num(S["bot_spam_limit"]) + var/botFloodLimit = text2num(S["bot_flood_limit"]) + var/botSmileysLimit= text2num(S["bot_smileys_limit"]) + var/botMaxMsgs = text2num(S["bot_max_msgs"]) + var/botMinDelay = text2num(S["bot_min_delay"]) + + Home = new(list( + "Founder"=Founder, + "Name"=HomeChan, + "Publicity"=Publicity, + "Desc"=ChanDesc, + "Topic"=ChanTopic, + "Pass"=Password, + "Locked"=Locked, + "TelPass"=telnet_pass, + "TelAtmpts"=telnet_attempts, + "SuperNode"=SuperNode, + "MaxNodes"=MaxNodes)) + if(Publicity != "public") world.visibility = 0 + + Home.chanbot.SetName(botName) + Home.chanbot.SetNameColor("#"+botNameColor) + Home.chanbot.SetTextColor("#"+botTextColor) + Home.chanbot.SetSpamControl(botSpamControls) + Home.chanbot.SetSpamLimit(botSpamLimit) + Home.chanbot.SetFloodLimit(botFloodLimit) + Home.chanbot.SetSmileysLimit(botSmileysLimit) + Home.chanbot.SetMaxMsgs(botMaxMsgs) + Home.chanbot.SetMinDelay(botMinDelay) + + if(muteList && muteList.len) + Home.mute = new + for(var/i in muteList) + Home.mute += ckey(i) + + if(banList && banList.len) + Home.banned = new + for(var/i in banList) + Home.banned += ckey(i) + + if(opList && opList.len) + Home.operators = new + for(var/Name in opList) + if(!findtext(Name, "_")) + var/opKey = ckey(opList[Name]) + var/rankIndex = text2num(opList["[Name]_level"]) +/* var/rankPrivs = opList[Name + "_privs"] // Not sure what to do with this. + if(rankPrivs != "default") + // Do something +*/ + var/OpRank/Rank = Home.op_ranks[rankIndex] + Home.operators[opKey] = new/Op(opList[Name], Rank) + + if(NetMan.Status != FAILED) spawn() + NetMan.Status = CONTACTING + var/retries = NetMan.retry + sleep(10) + do + world.Export("[NetMan.addr]:[NetMan.port]?dest=netman&action=newserver") + sleep(NetMan.timeout) + if(NetMan.Status == CONTACTING) if(!--retries) break + while(NetMan.Status == CONTACTING) + if(NetMan.Status == CONTACTING) + NetMan.Status = FAILED + return +/* + var/a_pos = findtext(world.address, ".", 1) + var/b_pos = findtext(world.address, ".", a_pos+1) + var/c_pos = findtext(world.address, ".", b_pos+1) + var/a = num2hex(text2num(copytext(world.address, 1, a_pos))) + ascii2text(rand(103,122)) + var/b = num2hex(text2num(copytext(world.address, a_pos+1, b_pos))) + ascii2text(rand(103,122)) + var/c = num2hex(text2num(copytext(world.address, b_pos+1, c_pos))) + ascii2text(rand(103,122)) + var/d = num2hex(text2num(copytext(world.address, c_pos+1))) + ascii2text(rand(103,122)) + var/e = num2hex(world.port) + + world.status = "[lowertext(a+b+c+d+e)]
[Home.name] founded by [Home.founder]" +*/ + var/savefile/F = new() + F["founder"] << Home.founder + F["name"] << Home.name + F["desc"] << Home.desc + F["topic"] << Home.topic + F["password"] << Home.pass + F["locked"] << Home.locked + F["supernode"] << Home.SuperNode + F["maxnodes"] << Home.MaxNodes + if(Home.chatters) + F["chatters"] << Home.chatters.len + else + F["chatters"] << 0 + NetMan.Status = CONNECTING + sleep(20) + do + world.Export("[NetMan.addr]:[NetMan.port]?dest=chanman&action=connect",F) + sleep(NetMan.timeout) + if(NetMan.Status == CONNECTING) if(!--retries) break + while(NetMan.Status == CONNECTING) + if(NetMan.Status == CONNECTING) NetMan.Status = FAILED + else + Home = LoadChan(HomeChan, telnet_pass, telnet_attempts) + Home.chanbot = BotMan.LoadBot(Home) + Home.LoadOps() + if(muteList && muteList.len) + Home.mute = listOpen(Home.mute) + for(var/i in muteList) + var/cval = ckey(i) + if(!(cval in Home.mute)) Home.mute += cval + + if(banList && banList.len) + Home.banned = listOpen(Home.banned) + for(var/i in banList) + var/cval = ckey(i) + if(!(cval in Home.banned)) Home.banned += cval + + if(opList && opList.len) + Home.operators = listOpen(Home.operators) + for(var/Name in opList) + if(!findtext(Name, "_")) + var/opKey = ckey(opList[Name]) + var/rankIndex = text2num(opList["[Name]_level"]) +/* var/rankPrivs = opList[Name + "_privs"] // Not sure what to do with this. + if(rankPrivs != "default") + // Do something +*/ + var/OpRank/Rank = Home.op_ranks[rankIndex] + Home.operators[opKey] = new/Op(opList[Name], Rank) + // TODO: Remove this once the Chatters Network is properly implemented. + world.OpenPort(NetMan.Port) \ No newline at end of file diff --git a/code/controllers/managers/chatman.dm b/code/controllers/managers/chatman.dm index 13a92a5..e075777 100644 --- a/code/controllers/managers/chatman.dm +++ b/code/controllers/managers/chatman.dm @@ -1,168 +1,195 @@ - -ChatterManager - - var - tmp/list/Dummies - - Topic(href, href_list) - ..() - switch(href_list["action"]) - if("showcode") - var/mob/chatter/Target = locate(href_list["target"]) - var/showcode_snippet/snippet = Home.showcodes[text2num(href_list["index"])] - if (snippet.target && snippet.target != usr.ckey && usr.ckey != Target.ckey) - // This is a private message they are not allowed to view. - return - else - usr << browse(snippet.ReturnHtml(Target, 1), "window=showcode_[snippet.id];display=1;size=800x500;border=1;can_close=1;can_resize=1;titlebar=1") - if("showtext") - var/mob/chatter/Target = locate(href_list["target"]) - var/showcode_snippet/snippet = Home.showcodes[text2num(href_list["index"])] - if (snippet.target && snippet.target != usr.ckey && usr.ckey != Target.ckey) - // This is a private message they are not allowed to view. - return - else - usr << browse(snippet.ReturnHtml(Target), "window=showtext_[snippet.id];display=1;size=800x500;border=1;can_close=1;can_resize=1;titlebar=1") - - proc - Usher(mob/Temp/T) - if(!T || !T.client) - del T - return - - var/mob/chatter/C = new() - - // Do not call client.Import on telnet users - if(!istelnet(T.key)) - var/client_file - client_file = T.client.Import() - if(client_file == "-1.sav") client_file = null - if(client_file) - if(!Load(C, client_file)) - // Out of date or bad savefile, discard. - T.client.Export() - C.name = T.name - C.key = T.key - else - C.name = T.name - C.key = T.key - var/SetView/SV = new(); SV.Initialize(C); del(SV) - var/HelpView/HV = new(); HV.Initialize(C); del(SV) - var/GamesView/GV = new(); GV.Initialize(C); del(SV) - else - C.name = T.name - C.key = T.key - - del(T) - - - // Tests if the key is a telnet key eg: Telnet @127.000.000.001 - istelnet(key) - if(findtext(key, "Telnet @") == 1) - return 1 - - - Get(chatter, local) - if(!length(chatter)) return - - if(Home && Home.chatters) - var first_char = text2ascii(copytext(chatter, 1, 2)) - // If search starts with a number, search IPs. - if(first_char > 47 && first_char < 58) - // Exact IP first - for(var/mob/chatter/C in Home.chatters) - if(C.client.address == chatter) - return C - - // Partial IP second - for(var/mob/chatter/C in Home.chatters) - if(TextMan.Match(C.client.address, chatter)) - return C - - else - // Exact key search. - for(var/mob/chatter/C in Home.chatters) - if(ckey(C.name) == ckey(chatter)) return C - - // Partial case-sensitive key search - for(var/mob/chatter/C in Home.chatters) - if(TextMan.Match(C.key, chatter)) return C - - // Partial non-case-sensitive key search - for(var/mob/chatter/C in Home.chatters) - if(TextMan.Match(C.ckey, chatter)) return C - - - Rank(chatter) - if(Home && chatter) - var/cKey = ckey(chatter) - if(cKey in Home.operators) - var/Op/O = Home.operators[cKey] - return O.Rank - return "All" - - - ParseFormat(format, variables[], required[]) - if(!format || !variables || !variables.len) return FALSE - if(required) - for(var/r in required) - if(!findtext(format, r)) return FALSE - var/list/L = new() - var/temp = format - for(var/v in variables) - var/pos = findtext(format, v) - if(pos) variables[v] = pos - else variables -= v - for(var/v = variables.len, v >= 1, v--) - for(var/i = 1, i < v, i++) - if(variables[variables[i]] > variables[variables[i+1]]) - variables.Swap( i, i+1) - else if(variables[variables[i]] == variables[variables[i+1]]) - variables -= variables[i+1] - if(v > variables.len) break - for(var/v in variables) - var/pos = findtext(temp, v) - if(pos > 1) - L += copytext(temp, 1, pos) - L += v - temp = copytext(temp, pos+length(v)) - if(length(temp)) - L += temp - return L - - Load(mob/chatter/C, client_file) - var/savefile/F = new(client_file) - var/version - F["version"] >> version - - if(version == "0.1.5" && ("CRYPTO" in F.dir)) - var/crypto - F["CRYPTO"] >> crypto - crypto = RC5_Decrypt(crypto, md5(world.hub_password)) - for(var/i = 1; i <= length(crypto); ++i) - if(text2ascii(crypto, i) < 32) return FALSE - F.dir -= "CRYPTO" - F.ImportText("/", crypto) - C.Read(F) - // Save an updated savefile. - Save(C) - return TRUE - else if(version == savefile_version) - C.Read(F) - return TRUE - else - return FALSE - - Save(mob/chatter/C) - var/savefile/S = new() - C.Write(S) - S["version"] << savefile_version - sleep(5) - C.client.Export(S) - - - EditSave(var/save) - if(!save) return - var/savefile/F = new(save) - var/text = F.ExportText("/") - return text + +ChatterManager + + var + tmp/list/Dummies + + Topic(href, href_list) + ..() + switch(href_list["action"]) + if("showcode") + var/mob/chatter/Target = locate(href_list["target"]) + var/showcode_snippet/snippet = Home.showcodes[text2num(href_list["index"])] + if (snippet.target && snippet.target != usr.ckey && usr.ckey != Target.ckey) + // This is a private message they are not allowed to view. + return + else + usr << browse(snippet.ReturnHtml(Target, 1), "window=showcode_[snippet.id];display=1;size=800x500;border=1;can_close=1;can_resize=1;titlebar=1") + if("showtext") + var/mob/chatter/Target = locate(href_list["target"]) + var/showcode_snippet/snippet = Home.showcodes[text2num(href_list["index"])] + if (snippet.target && snippet.target != usr.ckey && usr.ckey != Target.ckey) + // This is a private message they are not allowed to view. + return + else + usr << browse(snippet.ReturnHtml(Target), "window=showtext_[snippet.id];display=1;size=800x500;border=1;can_close=1;can_resize=1;titlebar=1") + + proc + Usher(mob/Temp/T) + if(!T || !T.client) + del T + return + + var/mob/chatter/C = new() + + // Do not call client.Import on telnet users + if(!istelnet(T.key)) + var/client_file + client_file = T.client.Import() + if(client_file == "-1.sav") client_file = null + if(client_file) + if(!Load(C, client_file)) + // Out of date or bad savefile, discard. + T.client.Export() + C.name = T.name + C.key = T.key + else + C.name = T.name + C.key = T.key + var/SetView/SV = new(); SV.Initialize(C); del(SV) + var/HelpView/HV = new(); HV.Initialize(C); del(SV) + var/GamesView/GV = new(); GV.Initialize(C); del(SV) + else + C.name = T.name + C.key = T.key + + del(T) + + + // Tests if the key is a telnet key eg: Telnet @127.000.000.001 + istelnet(key) + if(findtext(key, "Telnet @") == 1) + return 1 + + + Get(chatter, local) + if(!length(chatter)) return + if(!Home || !Home.chatters && NetMan.Status != CONNECTED) return + + if(Home && Home.chatters) + var first_char = text2ascii(copytext(chatter, 1, 2)) + // If search starts with a number, search IPs. + if(first_char > 47 && first_char < 58) + // Exact IP first + for(var/mob/chatter/C in Home.chatters) + if(C.client.address == chatter) + return C + + // Partial IP second + for(var/mob/chatter/C in Home.chatters) + if(TextMan.Match(C.client.address, chatter)) + return C + + else + // Exact key search. + for(var/mob/chatter/C in Home.chatters) + if(ckey(C.name) == ckey(chatter)) return C + + // Partial case-sensitive key search + for(var/mob/chatter/C in Home.chatters) + if(TextMan.Match(C.key, chatter)) return C + + // Partial non-case-sensitive key search + for(var/mob/chatter/C in Home.chatters) + if(TextMan.Match(C.ckey, chatter)) return C + + if(!local && NetMan.Status == CONNECTED) + if(!NetMan || !NetMan.Chatters || !NetMan.Chatters.len) + return + // Exact key search. + for(var/mob/chatter/C in world) + if(ckey(C.name) == ckey(chatter)) return C + + // Partial case-sensitive key search + for(var/mob/chatter/C in world) + if(TextMan.Match(C.key, chatter)) return C + + // Partial non-case-sensitive key search + for(var/mob/chatter/C in world) + if(TextMan.Match(C.ckey, chatter)) return C + // Exact key search. + for(var/C in NetMan.Chatters) + if(ckey(C) == ckey(chatter)) return C + + // Partial case-sensitive key search + for(var/C in NetMan.Chatters) + if(TextMan.Match(C, chatter)) return C + + // Partial non-case-sensitive key search + for(var/C in NetMan.Chatters) + if(TextMan.Match(ckey(C), chatter)) return C + + + Rank(chatter) + if(Home && chatter) + var/cKey = ckey(chatter) + if(cKey in Home.operators) + var/Op/O = Home.operators[cKey] + return O.Rank + return "All" + + + ParseFormat(format, variables[], required[]) + if(!format || !variables || !variables.len) return FALSE + if(required) + for(var/r in required) + if(!findtext(format, r)) return FALSE + var/list/L = new() + var/temp = format + for(var/v in variables) + var/pos = findtext(format, v) + if(pos) variables[v] = pos + else variables -= v + for(var/v = variables.len, v >= 1, v--) + for(var/i = 1, i < v, i++) + if(variables[variables[i]] > variables[variables[i+1]]) + variables.Swap( i, i+1) + else if(variables[variables[i]] == variables[variables[i+1]]) + variables -= variables[i+1] + if(v > variables.len) break + for(var/v in variables) + var/pos = findtext(temp, v) + if(pos > 1) + L += copytext(temp, 1, pos) + L += v + temp = copytext(temp, pos+length(v)) + if(length(temp)) + L += temp + return L + + Load(mob/chatter/C, client_file) + var/savefile/F = new(client_file) + var/version + F["version"] >> version + + if(version == "0.1.5" && ("CRYPTO" in F.dir)) + var/crypto + F["CRYPTO"] >> crypto + crypto = RC5_Decrypt(crypto, md5(world.hub_password)) + for(var/i = 1; i <= length(crypto); ++i) + if(text2ascii(crypto, i) < 32) return FALSE + F.dir -= "CRYPTO" + F.ImportText("/", crypto) + C.Read(F) + // Save an updated savefile. + Save(C) + return TRUE + else if(version == savefile_version) + C.Read(F) + return TRUE + else + return FALSE + + Save(mob/chatter/C) + var/savefile/S = new() + C.Write(S) + S["version"] << savefile_version + sleep(5) + C.client.Export(S) + + + EditSave(var/save) + if(!save) return + var/savefile/F = new(save) + var/text = F.ExportText("/") + return text diff --git a/code/controllers/managers/helpman.dm b/code/controllers/managers/helpman.dm index 61f2bbe..2a4e683 100644 --- a/code/controllers/managers/helpman.dm +++ b/code/controllers/managers/helpman.dm @@ -1,83 +1,84 @@ - -HelpManager - - var - obj/help/chapter/Main - list - Contents - Topics - - New() - ..() - LoadXML() - - Topic(href, href_list) - ..() - var/cKey = ckey(href_list["source"]) - var/mob/chatter/M = ChatMan.Get(cKey) - if(!M) for(var/mob/chatter/c in world) - if(cKey == c.ckey) M = c - if(!M) return - switch(href_list["action"]) - if("open") - for(var/obj/help/chapter/C in world) - if(C.name == url_decode(href_list["target"])) - C.open(M) - if("close") - for(var/obj/help/chapter/C in world) - if(C.name == url_decode(href_list["target"])) - C.close(M) - if("view_topic") - for(var/obj/help/topic/T in world) - if(T.name == url_decode(href_list["target"])) - T.show(M, href_list["page"]) - - proc - LoadXML() - if(!fexists("./data/xml/help/contents.xml")) - ErrMan.Topic("300") - return - var/XML/Element/contents_root = xmlRootFromFile("./data/xml/help/contents.xml") - if(!contents_root) - ErrMan.Topic("301") - return - var/XML/Element/topics_root = xmlRootFromPath("./data/xml/help/topics") - if(!topics_root) - ErrMan.Topic("302") - return - Contents = contents_root.ChildElements("chapter") - Topics = topics_root.Descendants("topic") - BuildContents() - - BuildContents() - Main = new() - Main.name = "Table of Contents" - Main = GetContents(Main, Contents, "./data/xml/help/topics", 1) - - GetContents(obj/help/chapter/container, contents[], path) - var/j = 1 - for(var/XML/Element/C in contents) - var/obj/help/chapter/O = new() - O.indent = container.indent+1 - O.name = C.Attribute("name") - var/list/Chapters = C.ChildElements("chapter") - if(Chapters && Chapters.len) - O = GetContents(O, Chapters, path+"/[j]") - var/list/topics = C.ChildElements("topic") - var/n = 1 - for(var/XML/Element/T in topics) - var/obj/help/topic/t = new() - t.indent = O.indent+1 - t.name = T.Text() - for(var/XML/Element/E in Topics) - if(E.Attribute("file_path") == "[path]/[j]/[n].xml") - var/XML/Element/info = E.Descendant("info") - var/TXT = info.Text() - if(TXT) t.Text = TXT - break - n++ - O.contents += t - container.contents += O - j++ - return container - + +HelpManager + + var + obj/help/chapter/Main + list + Contents + Topics + + New() + ..() + spawn() + LoadXML() + + Topic(href, href_list) + ..() + var/cKey = ckey(href_list["source"]) + var/mob/chatter/M = ChatMan.Get(cKey) + if(!M) for(var/mob/chatter/c in world) + if(cKey == c.ckey) M = c + if(!M) return + switch(href_list["action"]) + if("open") + for(var/obj/help/chapter/C in world) + if(C.name == url_decode(href_list["target"])) + C.open(M) + if("close") + for(var/obj/help/chapter/C in world) + if(C.name == url_decode(href_list["target"])) + C.close(M) + if("view_topic") + for(var/obj/help/topic/T in world) + if(T.name == url_decode(href_list["target"])) + T.show(M, href_list["page"]) + + proc + LoadXML() + if(!fexists("./data/xml/help/contents.xml")) + ErrMan.Topic("300") + return + var/XML/Element/contents_root = xmlRootFromFile("./data/xml/help/contents.xml") + if(!contents_root) + ErrMan.Topic("301") + return + var/XML/Element/topics_root = xmlRootFromPath("./data/xml/help/topics") + if(!topics_root) + ErrMan.Topic("302") + return + Contents = contents_root.ChildElements("chapter") + Topics = topics_root.Descendants("topic") + BuildContents() + + BuildContents() + Main = new() + Main.name = "Table of Contents" + Main = GetContents(Main, Contents, "./data/xml/help/topics", 1) + + GetContents(obj/help/chapter/container, contents[], path) + var/j = 1 + for(var/XML/Element/C in contents) + var/obj/help/chapter/O = new() + O.indent = container.indent+1 + O.name = C.Attribute("name") + var/list/Chapters = C.ChildElements("chapter") + if(Chapters && Chapters.len) + O = GetContents(O, Chapters, path+"/[j]") + var/list/topics = C.ChildElements("topic") + var/n = 1 + for(var/XML/Element/T in topics) + var/obj/help/topic/t = new() + t.indent = O.indent+1 + t.name = T.Text() + for(var/XML/Element/E in Topics) + if(E.Attribute("file_path") == "[path]/[j]/[n].xml") + var/XML/Element/info = E.Descendant("info") + var/TXT = info.Text() + if(TXT) t.Text = TXT + break + n++ + O.contents += t + container.contents += O + j++ + return container + diff --git a/code/controllers/managers/msgman.dm b/code/controllers/managers/msgman.dm index 2043fce..fd2d24f 100644 --- a/code/controllers/managers/msgman.dm +++ b/code/controllers/managers/msgman.dm @@ -1,45 +1,46 @@ - -MessageManager - var - isIgnoredResult = 1 - - Topic(href, href_list[]) - ..() - switch(href_list["action"]) - if("isIgnored") - var/From = href_list["from"] - var/T = href_list["to"] - var/mob/chatter/To = ChatMan.Get(T,1) - var/Addr = href_list["addr"] - if(To.ignoring(From) & IM_IGNORE) - world.Export("[Addr]?dest=msgman&action=isIgnoredResult&result=true") - else - world.Export("[Addr]?dest=msgman&action=isIgnoredResult&result=true") - if("isIgnoredResult") - isIgnoredResult = href_list["result"] - if("msg") - var/savefile/S = new(world.Import()) - var/mob/From, T, M - S["to"] >> T - S["from"] >> From - S["msg"] >> M - if(!ChatMan.Dummies) ChatMan.Dummies = new() - ChatMan.Dummies += From - var/mob/chatter/C = ChatMan.Get(T,1) - RouteMsg(From,C,M) - - - - proc - RouteMsg(mob/chatter/From, mob/chatter/To, msg, clean) - if(!msg) return - if(To.ignoring(From) & IM_IGNORE) - alert(From, "[To.name] is ignoring instant messages from you.", "Unable to IM chatter.") - return - To.MsgHand.GetMsg(From, msg, clean) - - isIgnoring(Name) - var/timeout = 300 - isIgnoredResult = null - while(isnull(isIgnoredResult) && timeout--) sleep(1) + +MessageManager + var + isIgnoredResult = 1 + + Topic(href, href_list[]) + ..() + switch(href_list["action"]) + if("isIgnored") + var/From = href_list["from"] + var/T = href_list["to"] + var/mob/chatter/To = ChatMan.Get(T,1) + var/Addr = href_list["addr"] + if(To.ignoring(From) & IM_IGNORE) + world.Export("[Addr]?dest=msgman&action=isIgnoredResult&result=true") + else + world.Export("[Addr]?dest=msgman&action=isIgnoredResult&result=true") + if("isIgnoredResult") + isIgnoredResult = href_list["result"] + if("msg") + var/savefile/S = new(world.Import()) + var/mob/From, T, M + S["to"] >> T + S["from"] >> From + S["msg"] >> M + if(!ChatMan.Dummies) ChatMan.Dummies = new() + ChatMan.Dummies += From + var/mob/chatter/C = ChatMan.Get(T,1) + RouteMsg(From,C,M) + + + + proc + RouteMsg(mob/chatter/From, mob/chatter/To, msg, clean) + if(!msg) return + if(To.ignoring(From) & IM_IGNORE) + alert(From, "[To.name] is ignoring instant messages from you.", "Unable to IM chatter.") + return + To.MsgHand.GetMsg(From, msg, clean) + + isIgnoring(Name) + var/timeout = 300 + isIgnoredResult = null + world.Export("[NetMan.Chatters[Name]]?dest=msgman&action=isIgnored&name=[Name]") + while(isnull(isIgnoredResult) && timeout--) sleep(1) return isIgnoredResult \ No newline at end of file diff --git a/code/controllers/managers/netman.dm b/code/controllers/managers/netman.dm index 6f731db..65265be 100644 --- a/code/controllers/managers/netman.dm +++ b/code/controllers/managers/netman.dm @@ -1,279 +1,280 @@ - -NetworkManager - var - name - desc - addr - port - Port - host - - ServerIP - - - Rebooting - Hosting - - timeout = 50 - retry = 3 - - Status - - MotD = "Thank you for helping test Chatters! Please post detailed bug reports so we can track down the problems and fix them." - - tmp/list - Chans - Chatters - - - New(var/ServerConsole/console) - ..() - LoadNetworkCfg(console) - - Topic(href, href_list) - ..() - switch(href_list["action"]) - if("validate") - if(Host && Host.client) winset(Host, "main_menu.info_top", - "text='Validating channel server...'") - var/Code = href_list["code"] - if(!ServerIP) ServerIP = copytext(href_list["ip"],1,findtext(href_list["ip"],":")) - var/Valid = md5("rbl9FQ0h[Code]zWtOEKtg") - Status = VALIDATING - var/retries = retry - sleep(20) - do - var/Name - if(Host && Host.client) Name = Host.name - else Name = ChanMan.host - world.Export("[addr]:[port]?dest=netman&action=validate&code=[Valid]&name=[ckey(Name)]") - sleep(timeout) - if(Status == VALIDATING) - if(Host && Host.client) - winset(Host, "main_menu.info_top", "text='Connection timed out.'") - sleep(20) - if(!--retries) break - if(Host && Host.client) - if(Status == VALIDATING) - winset(Host, "main_menu.info_top", "text='Validating channel server...'") - while(Status == VALIDATING) - if(Status == VALIDATING) - Status = FAILED - if(Host && Host.client) winset(Host, "main_menu.info_top", "text='Problem contacting network!'") - if("connected") - if(Host && Host.client) - winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") - winset(Host, "main_menu.cim", "is-disabled=false;") - winset(Host, "main_menu.public_chans", "is-disabled=false;") - winset(Host, "main_menu.cmail", "is-disabled=false;") - winset(Host, "main_menu.child", "left=main_menu_output") - winset(Host, "main_menu_output.network_label", "text='[NetMan.name]'") - Host << output(, "main_menu_output.output") - Host << output("Connected to the Chatters Network Server. \ -You may now open a public channel, or access the network features such as Cmail, CIMs, Groups and more. \ -Click Help for more information.", "main_menu_output.output") - call(Host,"ServerLink")() - Status = CONNECTED - Query("getchans") - Query("getchatters") - if("chanlist") - var/savefile/S = new(world.Import()) - S["chans"] >> Chans - if("chatlist") - var/savefile/S = new(world.Import()) - S["chatters"] >> Chatters - if("ping") - world.Export("[addr]:[port]?dest=netman&action=pong") - if("netmap") - Query("getchans") - Query("getchatters") - - proc - LoadNetworkCfg(var/ServerConsole/console) - var/list/config = console.LoadCFG("./data/saves/network.cfg") - if(!config || !config.len) ErrMan.Topic("100") - - var/list/Main = params2list(config["main"]) - - name = Main["name"] - if(!name) ErrMan.Topic("101") - - desc = Main["desc"] - if(!desc) ErrMan.Topic("102") - - addr = Main["addr"] - if(!addr) ErrMan.Topic("103") - - port = Main["port"] - if(!port) ErrMan.Topic("104") - - host = Main["host"] - if(!host) ErrMan.Topic("105") - - HostCheck(client/C) - if(ChanMan && ChanMan.devs && (C.ckey in ChanMan.devs)) - for(var/Command in (typesof(/Bot/verb)-/Bot/verb)) - C.verbs += Command - if(!Host && ((!ChanMan.host && (!C.address || C.address == "127.0.0.1")) || (ChanMan.host == C.ckey))) - Host = C.mob - winset(Host, "main_menu.close", "is-visible=false") - winset(Host, "default", "size=484x244") - winset(Host, "default.child", "left=main_menu") - for(var/Command in (typesof(/Host/proc)-/Host/proc)) - Host.verbs += Command - for(var/Command in (typesof(/Operator/proc)-/Operator/proc)) - Host.verbs += Command - call(Host, "ShowMainMenu")() - if(debugs) - for(var/d in debugs) - Host << output("[d]", "console.output") - winshow(Host, "console", 1) - debugs = null - return 1 - return 0 - - - PreConnect(newport) - //if(newport != "none") - // opening server - //else - // closing server - return newport - - - PostConnect(newport, oldport) - if(!world.port && !oldport && (newport != "none")) - Status = FAILED - // ErrMan.Topic("200", newport) - if(Host) winset(Host, "main_menu.info_top", "text='Unable to open port [newport]!'") - // problem opening the server - //else if(!world.port && oldport) - // server closed - //else if(newport != "none") - // server opened - - Connect() - if(NetMan.Status == CONNECTED) - winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") - winset(Host, "main_menu.cim", "is-disabled=false;") - winset(Host, "main_menu.public_chans", "is-disabled=false;") - winset(Host, "main_menu.cmail", "is-disabled=false;") - winset(Host, "main_menu.child", "left=main_menu_output") - winset(Host, "main_menu_output.network_label", "text='[NetMan.name]'") - call(Host,"ServerLink")() - else if(NetMan.Status != FAILED) - world.OpenPort(NetMan.Port) - spawn() - winset(Host, "main_menu.info_top", "text='Contacting network...'") - NetMan.Status = CONTACTING - var/retries = NetMan.retry - sleep(10) - do - world.Export("[NetMan.addr]:[NetMan.port]?dest=netman&action=newserver") - sleep(NetMan.timeout) - if(NetMan.Status == CONTACTING) - winset(Host, "main_menu.info_top", "text='Connection timed out.'") - Host << output("timeout.", "main_menu_connect.output") - sleep(20) - if(!--retries) break - if(NetMan.Status == CONTACTING) - winset(Host, "main_menu.info_top", "text='Contacting network...'") - Host << output("Retrying...\...", "main_menu_connect.output") - while(NetMan.Status == CONTACTING) - if(NetMan.Status == CONTACTING) - NetMan.Status = FAILED - winset(Host, "main_menu.info_top", "text='Problem contacting network!'") - var/msg = "The network server failed to respond. \ - Please make sure the network address is correct, \ - and no firewalls are blocking incoming traffic on \ - port [NetMan.Port]." - Host << output(, "main_menu_connect.output") - Host << output(msg, "main_menu_connect.output") - winset(Host, "main_menu_connect.network_label", "is-disabled=false;text-color=#000000") - winset(Host, "main_menu_connect.network_addr", "is-disabled=false;background-color=#FFFFFF") - winset(Host, "main_menu_connect.public", "is-disabled=false") - winset(Host, "main_menu_connect.private", "is-disabled=false") - winset(Host, "main_menu_connect.invisible", "is-disabled=false") - winset(Host, "main_menu_connect.connect", "is-disabled=false") - - - Disconnect() - if(port) world.OpenPort(0) - Status = null - world.Export("[addr]:[port]?dest=chanman&action=delserver") - if(Host) - winset(Host, "main_menu.cim", "is-disabled=true;") - winset(Host, "main_menu.public_chans", "is-disabled=true;") - winset(Host, "main_menu.cmail", "is-disabled=true;") - winset(Host, "main_menu.info_top", "text='Disconnected from the Chatters Network'") - spawn(30) - if(winget(Host, "main_menu.info_top", "text")=="Disconnected from the Chatters Network") - winset(Host, "main_menu.info_top", "text=") - winset(Host, "main_menu.info_bottom", "text=") - - - Report(topic, params) - if(Status != CONNECTED) return - switch(topic) - if("join") - world.Export("[addr]:[port]?dest=chatman&action=login&name=[params]") - return 1 - if("quit") - world.Export("[addr]:[port]?dest=chatman&action=logout&name=[params]") - return 1 - - Query(topic, params) - if(Status != CONNECTED) return - switch(topic) - if("getchans") - world.Export("[addr]:[port]?dest=chanman&action=getchans") - return 1 - if("getchatters") - world.Export("[addr]:[port]?dest=chatman&action=getchatters") - return 1 - - MOTD(mob/chatter/C) - if(!C || !C.client || !C.Chan || !C.show_motd || !MotD) return - if(C.show_colors) - C << output("[TextMan.fadetext("Network Message of the Day", list("255000000","204153153","255204000"))]:", "[ckey(C.Chan.name)].chat.default_output") - else - C << output("Network Message of the Day:", "[ckey(C.Chan.name)].chat.default_output") - C << output(" [MotD]\n", "[ckey(C.Chan.name)].chat.default_output") - - UpdatePubChans(mob/chatter/C) - if(!C || C.telnet) return - var/i=2 - var/bgcolor - var/obj/L = new(); L.icon = './resources/images/interface/locks/locked_white.png'; L.name = "" - var/obj/U = new(); U.icon = './resources/images/interface/locks/unlocked_white.png' ; U.name="" - if(!Chans || !Chans.len) - winset(C, "pub_chans.info_top", "text='0 channels online'") - winset(C, "pub_chans.grid", "current-cell=1,2;") - Host << output(, "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=2,2;") - Host << output(, "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=3,2;") - Host << output(, "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=4,2;") - Host << output(, "pub_chans.grid") - winset(C, "pub_chans.grid", "cells=4x1") - else - winset(C, "pub_chans.info_top", "text='[Chans.len] channel\s online'") - for(var/Addr in Chans) - var/Channel/Chan = Chans[Addr] - if(i&1) - bgcolor="#ccc" - L.icon = './resources/images/interface/locks/locked_grey.png' - U.icon = './resources/images/interface/locks/unlocked_grey.png' - else - bgcolor="#fff" - L.icon = './resources/images/interface/locks/locked_white.png' - U.icon = './resources/images/interface/locks/unlocked_white.png' - winset(C, "pub_chans.grid", "current-cell=1,[i];") - C << output(" [Chan.name]", "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=2,[i];") - C << output("[Chan.founder]", "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=3,[i];") - C << output("[Chan.desc]", "pub_chans.grid") - winset(C, "pub_chans.grid", "current-cell=4,[i++];") + +NetworkManager + var + name + desc + addr + port + Port + host + + ServerIP + + + Rebooting + Hosting + + timeout = 50 + retry = 3 + + Status + + MotD = "Thank you for helping test Chatters! Please post detailed bug reports so we can track down the problems and fix them." + + tmp/list + Chans + Chatters + + + New() + ..() + spawn() + LoadNetworkCfg() + + Topic(href, href_list) + ..() + switch(href_list["action"]) + if("validate") + if(Host && Host.client) winset(Host, "main_menu.info_top", + "text='Validating channel server...'") + var/Code = href_list["code"] + if(!ServerIP) ServerIP = copytext(href_list["ip"],1,findtext(href_list["ip"],":")) + var/Valid = md5("rbl9FQ0h[Code]zWtOEKtg") + Status = VALIDATING + var/retries = retry + sleep(20) + do + var/Name + if(Host && Host.client) Name = Host.name + else Name = ChanMan.host + world.Export("[addr]:[port]?dest=netman&action=validate&code=[Valid]&name=[ckey(Name)]") + sleep(timeout) + if(Status == VALIDATING) + if(Host && Host.client) + winset(Host, "main_menu.info_top", "text='Connection timed out.'") + sleep(20) + if(!--retries) break + if(Host && Host.client) + if(Status == VALIDATING) + winset(Host, "main_menu.info_top", "text='Validating channel server...'") + while(Status == VALIDATING) + if(Status == VALIDATING) + Status = FAILED + if(Host && Host.client) winset(Host, "main_menu.info_top", "text='Problem contacting network!'") + if("connected") + if(Host && Host.client) + winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") + winset(Host, "main_menu.cim", "is-disabled=false;") + winset(Host, "main_menu.public_chans", "is-disabled=false;") + winset(Host, "main_menu.cmail", "is-disabled=false;") + winset(Host, "main_menu.child", "left=main_menu_output") + winset(Host, "main_menu_output.network_label", "text='[NetMan.name]'") + Host << output(, "main_menu_output.output") + Host << output("Connected to the Chatters Network Server. \ +You may now open a public channel, or access the network features such as Cmail, CIMs, Groups and more. \ +Click Help for more information.", "main_menu_output.output") + call(Host,"ServerLink")() + Status = CONNECTED + Query("getchans") + Query("getchatters") + if("chanlist") + var/savefile/S = new(world.Import()) + S["chans"] >> Chans + if("chatlist") + var/savefile/S = new(world.Import()) + S["chatters"] >> Chatters + if("ping") + world.Export("[addr]:[port]?dest=netman&action=pong") + if("netmap") + Query("getchans") + Query("getchatters") + + proc + LoadNetworkCfg() + var/list/config = Console.LoadCFG("./data/saves/network.cfg") + if(!config || !config.len) ErrMan.Topic("100") + + var/list/Main = params2list(config["main"]) + + name = Main["name"] + if(!name) ErrMan.Topic("101") + + desc = Main["desc"] + if(!desc) ErrMan.Topic("102") + + addr = Main["addr"] + if(!addr) ErrMan.Topic("103") + + port = Main["port"] + if(!port) ErrMan.Topic("104") + + host = Main["host"] + if(!host) ErrMan.Topic("105") + + HostCheck(client/C) + if(ChanMan && ChanMan.devs && (C.ckey in ChanMan.devs)) + for(var/Command in (typesof(/Bot/verb)-/Bot/verb)) + C.verbs += Command + if(!Host && ((!ChanMan.host && (!C.address || C.address == "127.0.0.1")) || (ChanMan.host == C.ckey))) + Host = C.mob + winset(Host, "main_menu.close", "is-visible=false") + winset(Host, "default", "size=484x244") + winset(Host, "default.child", "left=main_menu") + for(var/Command in (typesof(/Host/proc)-/Host/proc)) + Host.verbs += Command + for(var/Command in (typesof(/Operator/proc)-/Operator/proc)) + Host.verbs += Command + call(Host, "ShowMainMenu")() + if(debugs) + for(var/d in debugs) + Host << output("[d]", "console.output") + winshow(Host, "console", 1) + debugs = null + return 1 + return 0 + + + PreConnect(newport) + //if(newport != "none") + // opening server + //else + // closing server + return newport + + + PostConnect(newport, oldport) + if(!world.port && !oldport && (newport != "none")) + Status = FAILED + // ErrMan.Topic("200", newport) + if(Host) winset(Host, "main_menu.info_top", "text='Unable to open port [newport]!'") + // problem opening the server + //else if(!world.port && oldport) + // server closed + //else if(newport != "none") + // server opened + + Connect() + if(NetMan.Status == CONNECTED) + winset(Host, "main_menu.info_top", "text='Connected to the Chatters Network on port [world.port]'") + winset(Host, "main_menu.cim", "is-disabled=false;") + winset(Host, "main_menu.public_chans", "is-disabled=false;") + winset(Host, "main_menu.cmail", "is-disabled=false;") + winset(Host, "main_menu.child", "left=main_menu_output") + winset(Host, "main_menu_output.network_label", "text='[NetMan.name]'") + call(Host,"ServerLink")() + else if(NetMan.Status != FAILED) + world.OpenPort(NetMan.Port) + spawn() + winset(Host, "main_menu.info_top", "text='Contacting network...'") + NetMan.Status = CONTACTING + var/retries = NetMan.retry + sleep(10) + do + world.Export("[NetMan.addr]:[NetMan.port]?dest=netman&action=newserver") + sleep(NetMan.timeout) + if(NetMan.Status == CONTACTING) + winset(Host, "main_menu.info_top", "text='Connection timed out.'") + Host << output("timeout.", "main_menu_connect.output") + sleep(20) + if(!--retries) break + if(NetMan.Status == CONTACTING) + winset(Host, "main_menu.info_top", "text='Contacting network...'") + Host << output("Retrying...\...", "main_menu_connect.output") + while(NetMan.Status == CONTACTING) + if(NetMan.Status == CONTACTING) + NetMan.Status = FAILED + winset(Host, "main_menu.info_top", "text='Problem contacting network!'") + var/msg = "The network server failed to respond. \ + Please make sure the network address is correct, \ + and no firewalls are blocking incoming traffic on \ + port [NetMan.Port]." + Host << output(, "main_menu_connect.output") + Host << output(msg, "main_menu_connect.output") + winset(Host, "main_menu_connect.network_label", "is-disabled=false;text-color=#000000") + winset(Host, "main_menu_connect.network_addr", "is-disabled=false;background-color=#FFFFFF") + winset(Host, "main_menu_connect.public", "is-disabled=false") + winset(Host, "main_menu_connect.private", "is-disabled=false") + winset(Host, "main_menu_connect.invisible", "is-disabled=false") + winset(Host, "main_menu_connect.connect", "is-disabled=false") + + + Disconnect() + if(port) world.OpenPort(0) + Status = null + world.Export("[addr]:[port]?dest=chanman&action=delserver") + if(Host) + winset(Host, "main_menu.cim", "is-disabled=true;") + winset(Host, "main_menu.public_chans", "is-disabled=true;") + winset(Host, "main_menu.cmail", "is-disabled=true;") + winset(Host, "main_menu.info_top", "text='Disconnected from the Chatters Network'") + spawn(30) + if(winget(Host, "main_menu.info_top", "text")=="Disconnected from the Chatters Network") + winset(Host, "main_menu.info_top", "text=") + winset(Host, "main_menu.info_bottom", "text=") + + + Report(topic, params) + if(Status != CONNECTED) return + switch(topic) + if("join") + world.Export("[addr]:[port]?dest=chatman&action=login&name=[params]") + return 1 + if("quit") + world.Export("[addr]:[port]?dest=chatman&action=logout&name=[params]") + return 1 + + Query(topic, params) + if(Status != CONNECTED) return + switch(topic) + if("getchans") + world.Export("[addr]:[port]?dest=chanman&action=getchans") + return 1 + if("getchatters") + world.Export("[addr]:[port]?dest=chatman&action=getchatters") + return 1 + + MOTD(mob/chatter/C) + if(!C || !C.client || !C.Chan || !C.show_motd || !MotD) return + if(C.show_colors) + C << output("[TextMan.fadetext("Network Message of the Day", list("255000000","204153153","255204000"))]:", "[ckey(C.Chan.name)].chat.default_output") + else + C << output("Network Message of the Day:", "[ckey(C.Chan.name)].chat.default_output") + C << output(" [MotD]\n", "[ckey(C.Chan.name)].chat.default_output") + + UpdatePubChans(mob/chatter/C) + if(!C || C.telnet) return + var/i=2 + var/bgcolor + var/obj/L = new(); L.icon = './resources/images/interface/locks/locked_white.png'; L.name = "" + var/obj/U = new(); U.icon = './resources/images/interface/locks/unlocked_white.png' ; U.name="" + if(!Chans || !Chans.len) + winset(C, "pub_chans.info_top", "text='0 channels online'") + winset(C, "pub_chans.grid", "current-cell=1,2;") + Host << output(, "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=2,2;") + Host << output(, "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=3,2;") + Host << output(, "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=4,2;") + Host << output(, "pub_chans.grid") + winset(C, "pub_chans.grid", "cells=4x1") + else + winset(C, "pub_chans.info_top", "text='[Chans.len] channel\s online'") + for(var/Addr in Chans) + var/Channel/Chan = Chans[Addr] + if(i&1) + bgcolor="#ccc" + L.icon = './resources/images/interface/locks/locked_grey.png' + U.icon = './resources/images/interface/locks/unlocked_grey.png' + else + bgcolor="#fff" + L.icon = './resources/images/interface/locks/locked_white.png' + U.icon = './resources/images/interface/locks/unlocked_white.png' + winset(C, "pub_chans.grid", "current-cell=1,[i];") + C << output(" [Chan.name]", "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=2,[i];") + C << output("[Chan.founder]", "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=3,[i];") + C << output("[Chan.desc]", "pub_chans.grid") + winset(C, "pub_chans.grid", "current-cell=4,[i++];") C << output("[Chan.chatters]", "pub_chans.grid") \ No newline at end of file diff --git a/code/controllers/managers/opman.dm b/code/controllers/managers/opman.dm index b07c621..4a5ac55 100644 --- a/code/controllers/managers/opman.dm +++ b/code/controllers/managers/opman.dm @@ -1,129 +1,130 @@ - -OperatorManager - - var - list - op_ranks - op_privileges - - New() - ..() - LoadXML() - - proc - LoadXML() - var/list/ranks = flist("./data/xml/ops/ranks/") - op_ranks = listOpen(op_ranks) - op_ranks.len = ranks.len - for(var/rank in ranks) - if(!findtext(rank, "xml", length(rank)-2)) continue - var/XML/Element/rank_root = xmlRootFromFile("./data/xml/ops/ranks/[rank]") - rank_root = rank_root.Descendant("oprank") - if(!rank_root) return - var/OpRank/Rank = new() - Rank.name = rank_root.Attribute("name") - Rank.select.name = Rank.name - Rank.pos = text2num(rank_root.Attribute("pos")) - Rank.color = rank_root.Attribute("color") - Rank.monitor = text2num(rank_root.Attribute("monitor")) - Rank.auto_approve = text2num(rank_root.Attribute("approve")) - var/XML/Element/descXML = rank_root.Descendant("desc") - if(descXML) Rank.desc = descXML.Text() - var/XML/Element/promoteXML = rank_root.Descendant("promote") - if(promoteXML) Rank.promote = promoteXML.Text() - var/XML/Element/demoteXML = rank_root.Descendant("demote") - if(demoteXML) Rank.demote = demoteXML.Text() - var/XML/Element/tempXML = rank_root.Descendant("temp") - if(tempXML) - Rank.temp = 1 - Rank.expires = text2num(tempXML.Attribute("expires")) - else Rank.temp = 0 - var/XML/Element/electXML = rank_root.Descendant("elect") - if(electXML) - Rank.elect = 1 - Rank.elect_by = electXML.Attribute("by") - Rank.or_lower = text2num(electXML.Attribute("orlower")) - if(!Rank.or_lower) Rank.or_higher = 1 - else Rank.or_higher = text2num(electXML.Attribute("orhigher")) - Rank.max_elect = text2num(electXML.Attribute("max")) - else Rank.elect = 0 - Rank.privs = new() - var/XML/Element/privsXML = rank_root.Descendant("privileges") - if(privsXML) - for(var/XML/Element/Priv in privsXML.Descendants("privilege")) - Rank.privs += Priv.Attribute("name") - op_ranks[Rank.pos] = Rank - for(var/r in op_ranks) - if(isnull(r)) op_ranks -= r - var/list/privs = flist("./data/xml/ops/privileges/") - op_privileges = listOpen(op_privileges) - op_privileges.len = privs.len - for(var/priv in privs) - if(!findtext(priv, "xml", length(priv)-2)) continue - var/XML/Element/priv_root = xmlRootFromFile("./data/xml/ops/privileges/[priv]") - priv_root = priv_root.Descendant("oppriv") - if(!priv_root) return - var/OpPrivilege/Priv = new() - Priv.name = priv_root.Attribute("name") - Priv.select.name = Priv.name - Priv.monitor = text2num(priv_root.Attribute("monitor")) - Priv.auto_approve = text2num(priv_root.Attribute("approve")) - var/XML/Element/descXML = priv_root.Descendant("desc") - if(descXML) Priv.desc = descXML.Text() - var/XML/Element/executeXML = priv_root.Descendant("execute") - if(executeXML) Priv.execute = executeXML.Text() - var/XML/Element/commandXML = priv_root.Descendant("command") - if(commandXML) Priv.command = commandXML.Text() - var/XML/Element/electXML = priv_root.Descendant("elect") - if(electXML) - Priv.elect = 1 - Priv.elect_by = electXML.Attribute("by") - Priv.or_lower = text2num(electXML.Attribute("orlower")) - if(!Priv.or_lower) Priv.or_higher = 1 - else Priv.or_higher = text2num(electXML.Attribute("orhigher")) - Priv.min_votes = abs(text2num(electXML.Attribute("min_votes"))) - Priv.min_delay = abs(text2num(electXML.Attribute("min_delay"))) - Priv.margin = abs(text2num(electXML.Attribute("margin"))) - else Priv.elect = 0 - op_privileges[Priv.name] = Priv - for(var/p in op_privileges) - if(isnull(p)) op_privileges -= p - - SaveRankXML(OpRank/Rank) - if(!Rank) return - var/XML/Element/mainXML = new("xml") - var/XML/Element/rankXML = new("oprank") - mainXML.AddChild(rankXML) - var/list/rank_attributes = list("name"=Rank.name,"pos"="[Rank.pos]","color"=Rank.color) - if(Rank.monitor) rank_attributes["monitor"] = "1" - if(Rank.auto_approve) rank_attributes["approve"] = "1" - rankXML.setAttributes(rank_attributes) - var/XML/Element/descXML = new("desc") - rankXML.AddChild(descXML) - descXML.setText(Rank.desc) - var/XML/Element/promoteXML = new("promote") - rankXML.AddChild(promoteXML) - promoteXML.setText(Rank.promote) - var/XML/Element/demoteXML = new("demote") - rankXML.AddChild(demoteXML) - demoteXML.setText(Rank.demote) - if(Rank.temp) - var/XML/Element/tempXML = new("temp") - rankXML.AddChild(tempXML) - tempXML.setAttribute("expires",Rank.expires) - if(Rank.elect) - var/XML/Element/electXML = new("elect") - rankXML.AddChild(electXML) - electXML.setAttribute("by", Rank.elect_by) - if(Rank.or_higher) - electXML.setAttribute("orhigher", "1") - electXML.setAttribute("max", Rank.max_elect) - var/XML/Element/privsXML = new("privileges") - rankXML.AddChild(privsXML) - for(var/priv in Rank.privs) - var/XML/Element/privXML = new("privilege") - privsXML.AddChild(privXML) - privXML.setAttribute("name", priv) - mainXML.WriteToFile("./data/xml/ops/ranks/[Rank.name].xml") - - + +OperatorManager + + var + list + op_ranks + op_privileges + + New() + ..() + spawn() + LoadXML() + + proc + LoadXML() + var/list/ranks = flist("./data/xml/ops/ranks/") + op_ranks = listOpen(op_ranks) + op_ranks.len = ranks.len + for(var/rank in ranks) + if(!findtext(rank, "xml", length(rank)-2)) continue + var/XML/Element/rank_root = xmlRootFromFile("./data/xml/ops/ranks/[rank]") + rank_root = rank_root.Descendant("oprank") + if(!rank_root) return + var/OpRank/Rank = new() + Rank.name = rank_root.Attribute("name") + Rank.select.name = Rank.name + Rank.pos = text2num(rank_root.Attribute("pos")) + Rank.color = rank_root.Attribute("color") + Rank.monitor = text2num(rank_root.Attribute("monitor")) + Rank.auto_approve = text2num(rank_root.Attribute("approve")) + var/XML/Element/descXML = rank_root.Descendant("desc") + if(descXML) Rank.desc = descXML.Text() + var/XML/Element/promoteXML = rank_root.Descendant("promote") + if(promoteXML) Rank.promote = promoteXML.Text() + var/XML/Element/demoteXML = rank_root.Descendant("demote") + if(demoteXML) Rank.demote = demoteXML.Text() + var/XML/Element/tempXML = rank_root.Descendant("temp") + if(tempXML) + Rank.temp = 1 + Rank.expires = text2num(tempXML.Attribute("expires")) + else Rank.temp = 0 + var/XML/Element/electXML = rank_root.Descendant("elect") + if(electXML) + Rank.elect = 1 + Rank.elect_by = electXML.Attribute("by") + Rank.or_lower = text2num(electXML.Attribute("orlower")) + if(!Rank.or_lower) Rank.or_higher = 1 + else Rank.or_higher = text2num(electXML.Attribute("orhigher")) + Rank.max_elect = text2num(electXML.Attribute("max")) + else Rank.elect = 0 + Rank.privs = new() + var/XML/Element/privsXML = rank_root.Descendant("privileges") + if(privsXML) + for(var/XML/Element/Priv in privsXML.Descendants("privilege")) + Rank.privs += Priv.Attribute("name") + op_ranks[Rank.pos] = Rank + for(var/r in op_ranks) + if(isnull(r)) op_ranks -= r + var/list/privs = flist("./data/xml/ops/privileges/") + op_privileges = listOpen(op_privileges) + op_privileges.len = privs.len + for(var/priv in privs) + if(!findtext(priv, "xml", length(priv)-2)) continue + var/XML/Element/priv_root = xmlRootFromFile("./data/xml/ops/privileges/[priv]") + priv_root = priv_root.Descendant("oppriv") + if(!priv_root) return + var/OpPrivilege/Priv = new() + Priv.name = priv_root.Attribute("name") + Priv.select.name = Priv.name + Priv.monitor = text2num(priv_root.Attribute("monitor")) + Priv.auto_approve = text2num(priv_root.Attribute("approve")) + var/XML/Element/descXML = priv_root.Descendant("desc") + if(descXML) Priv.desc = descXML.Text() + var/XML/Element/executeXML = priv_root.Descendant("execute") + if(executeXML) Priv.execute = executeXML.Text() + var/XML/Element/commandXML = priv_root.Descendant("command") + if(commandXML) Priv.command = commandXML.Text() + var/XML/Element/electXML = priv_root.Descendant("elect") + if(electXML) + Priv.elect = 1 + Priv.elect_by = electXML.Attribute("by") + Priv.or_lower = text2num(electXML.Attribute("orlower")) + if(!Priv.or_lower) Priv.or_higher = 1 + else Priv.or_higher = text2num(electXML.Attribute("orhigher")) + Priv.min_votes = abs(text2num(electXML.Attribute("min_votes"))) + Priv.min_delay = abs(text2num(electXML.Attribute("min_delay"))) + Priv.margin = abs(text2num(electXML.Attribute("margin"))) + else Priv.elect = 0 + op_privileges[Priv.name] = Priv + for(var/p in op_privileges) + if(isnull(p)) op_privileges -= p + + SaveRankXML(OpRank/Rank) + if(!Rank) return + var/XML/Element/mainXML = new("xml") + var/XML/Element/rankXML = new("oprank") + mainXML.AddChild(rankXML) + var/list/rank_attributes = list("name"=Rank.name,"pos"="[Rank.pos]","color"=Rank.color) + if(Rank.monitor) rank_attributes["monitor"] = "1" + if(Rank.auto_approve) rank_attributes["approve"] = "1" + rankXML.setAttributes(rank_attributes) + var/XML/Element/descXML = new("desc") + rankXML.AddChild(descXML) + descXML.setText(Rank.desc) + var/XML/Element/promoteXML = new("promote") + rankXML.AddChild(promoteXML) + promoteXML.setText(Rank.promote) + var/XML/Element/demoteXML = new("demote") + rankXML.AddChild(demoteXML) + demoteXML.setText(Rank.demote) + if(Rank.temp) + var/XML/Element/tempXML = new("temp") + rankXML.AddChild(tempXML) + tempXML.setAttribute("expires",Rank.expires) + if(Rank.elect) + var/XML/Element/electXML = new("elect") + rankXML.AddChild(electXML) + electXML.setAttribute("by", Rank.elect_by) + if(Rank.or_higher) + electXML.setAttribute("orhigher", "1") + electXML.setAttribute("max", Rank.max_elect) + var/XML/Element/privsXML = new("privileges") + rankXML.AddChild(privsXML) + for(var/priv in Rank.privs) + var/XML/Element/privXML = new("privilege") + privsXML.AddChild(privXML) + privXML.setAttribute("name", priv) + mainXML.WriteToFile("./data/xml/ops/ranks/[Rank.name].xml") + + diff --git a/code/models/channel.dm b/code/models/channel.dm index 19bb94e..bff59e4 100644 --- a/code/models/channel.dm +++ b/code/models/channel.dm @@ -1,764 +1,768 @@ -Channel - var - founder - name - publicity - desc - topic - pass - locked - telnet_pass - telnet_attempts - QOTD - SuperNode - MaxNodes - - // spam controls - spam_control =1 - spam_limit = 3 - flood_limit = 3 - smileys_limit = 10 - max_msgs = 3 - min_delay = 20 - - room_desc = "An average looking room." - room_desc_size - - Bot - chanbot - list - chatters - players - painters - operators - op_ranks - op_privileges - op_actions - mute - banned - nodes - ballots - showcodes = list() - - filtered_words = list( "fuck" = "fudge", - "shit" = "dung", - " ass" = "donkey", - " asshole"= "donkeyhole", - "penis" = "pencil", - "vagina" = "kitty", - "pussy" = "kitty", - " cunt" = "kitty", - "bitch" = "female dog", - "faggot" = "bundle of sticks", - " fag" = "cigarette", - "nigger" = "ignorant person", - "nigga" = "homeslice", - " dick" = "private eye", - " cock" = "rooster", - "cocksuck"= "milkdrink") - - New(params[]) - if(params) - founder = params["Founder"] - if(!founder) founder = Host.name - name = params["Name"] - publicity = params["Publicity"] - desc = params["Desc"] - topic = params["Topic"] - pass = params["Pass"] - locked = text2num(params["Locked"]) ? 1 : 0 - telnet_pass = params["TelPass"] - telnet_attempts = (text2num(params["TelAtmpts"]) || -1) - SuperNode = text2num(params["SuperNode"]) ? 1 : 0 - MaxNodes = text2num(params["MaxNodes"]) - ..() - chanbot = new /Bot(src) - if(SuperNode) nodes = new() - - proc - LoadOps() - op_ranks = OpMan.op_ranks - var/savefile/S = new("./data/saves/channels/[ckey(name)].sav") - var/list/ops = null - S["operators"] >> ops - if(ops) - operators = listOpen(operators) - for(var/Name in ops) - var/rankIndex = ops[Name] - var/OpRank/Rank = op_ranks[rankIndex] - operators[ckey(Name)] = new/Op(Name, Rank) - - Join(mob/chatter/C) - if(!C || !C.client) - del C - return - - if(C.Chan == src) return - C.Chan = src - winclone(C, "channel", ckey(name)) - winclone(C, "who", "[ckey(name)].who") - winclone(C, "chat", "[ckey(name)].chat") - var/window = ckey(name) - winset(C, null, "[window].default_input.is-default=true;\ - [window].chat.default_output.is-default=true;\ - [window].chat.default_output.is-disabled=false;\ - [window].topic_label.text='[TextMan.escapeQuotes(topic)]';\ - [window].child.left=[window].chat;\ - [window].child.right=[window].who;\ - default.size=[C.winsize];\ - default.can-resize=true;\ - default.title='[name] - Chatters';\ - default.menu=menu;\ - default.child.pos=0,0;\ - default.child.size=[C.winsize];\ - default.child.left=[ckey(name)];") -/* winset(C, "[ckey(name)].default_input", "is-default=true;") - winset(C, "[ckey(name)].chat.default_output", "is-default=true;is-disabled=false.") - winset(C, "[ckey(name)].topic_label", "text='[TextMan.escapeQuotes(topic)]';") - winset(C, "[ckey(name)].child", "left=[ckey(name)].chat; right=[ckey(name)].who") - winset(C, "default", "size=[C.winsize];can-resize=true;title='[name] - Chatters';menu=menu;") - winset(C, "default.child", "pos=0,0;size=[C.winsize];left=[ckey(name)];") -*/ - - if(C.ckey in banned) - C << output("Sorry, you are banned from this channel.", "[ckey(name)].chat.default_output") - C << output("Connection closed.", "[ckey(name)].chat.default_output") - del C - return - - - if(Host == C) winset(C, "default", "menu=host") - - for(var/p in typesof(/Player/proc)-/Player/proc) - C.verbs += p - - if(C.ckey in operators) - if(C.telnet) - operators -= C.ckey - else - var/Op/O = operators[C.ckey] - for(var/priv in O.privileges) - var/OpPrivilege/P = OpMan.op_privileges[priv] - C.verbs += text2path("/Operator/proc/[P.command]") - - if(!C.telnet && winget(C, "[ckey(name)].default_input", "is-disabled") == "true") - // Returning from a kick/ban - var/size = winget(C, "[ckey(name)].child", "size") - var/X = copytext(size, 1, findtext(size,"x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1)) - 44 - winset(C, null, "[window].toggle_quickbar.is-visible=true;\ - [window].set.is-visible=true;\ - [window].help.is-visible=true;\ - [window].default_input.is-disabled=false;\ - [window].child.size=[X]x[Y];\ - [window].child.pos=0,0;") - C.ToggleQuickBar(1) - - if(!C.quickbar) - C.quickbar = TRUE - C.ToggleQuickBar(1) -// if(Host == C) winset(C, "host.quickbar_toggle", "is-checked=false;") -// else winset(C, "menu.quickbar_toggle", "is-checked=false;") - - if(!C.showwho) - C.showwho = TRUE - C.ToggleWho(1) - if(Host == C) - winset(C, "host.who_toggle", "is-checked=false;") - else - winset(C, "menu.who_toggle", "is-checked=false;") - - if(!C.showtopic) - C.showtopic = TRUE - C.ToggleTopic(1) - if(Host == C) - winset(C, "host.topic_toggle", "is-checked=false;") - else - winset(C, "menu.topic_toggle", "is-checked=false;") - - if(C.swaped_panes) - C.swaped_panes = FALSE - C.SwapPanes(1) - - winshow(C, ckey(name), 1) - - winset(C, "[ckey(C.Chan.name)].chat.default_output", "style='[TextMan.escapeQuotes(C.default_output_style)]';max-lines='[C.max_output]';") - if(C.show_title) - if(C.show_colors) - C << output({"[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] -[world.name] - Created by Xooxerand the BYOND Community -[TextMan.fadetext("Still the greatest chat program on BYOND!", list("102000000","255000000","102000000","000000000","000000255"))] -Source available on the Chatters Repository. -Copyright � 2008 Andrew "Xooxer" Arnold -[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] -- All Rights Reserved - -"}, "[ckey(name)].chat.default_output") - - else - C << output({"########################################## -[world.name] - Created by Xooxerand the BYOND Community -Still the greatest chat program on BYOND! -Source available on the Chatters Repository. -Copyright � 2008 Andrew "Xooxer" Arnold -########################################## -- All Rights Reserved - -"}, "[ckey(name)].chat.default_output") - - if(C.show_welcome) - C << output("[time2text(world.realtime+C.time_offset, list2text(C.long_date_format))]\nWelcome, [C.name]!\n", "[ckey(name)].chat.default_output") - - if(C.show_qotd) TextMan.QOTD(C) - - if(!chatters) chatters = new() - chatters += C - chatters = SortWho(chatters) - - UpdateWho() - - world.status = "[Home.name] founded by [Home.founder] - [Home.chatters.len] chatter\s" - - MapMan.Join(C) - - winset(C, "[ckey(Home.name)].default_input", "text='> ';focus=true;") - - chanbot.Say("[C.name] has joined [name]") - chanbot.Say("You have joined [name] founded by [founder]",C) - chanbot.Say("[topic]",C) - if(!Home.ismute(C)) EventMan.Parse(C, C.onJoin) - - Quit(mob/chatter/C) - if(!C) - for(var/i=1 to chatters.len) - if(!chatters[i]) chatters -= chatters[i] - return - UpdateWho() - - if(C.ckey in operators) - var/Op/O = operators[C.ckey] - if(O.Rank.temp) operators -= C.ckey - - if(!Home.ismute(C)) EventMan.Parse(C, C.onQuit) - C.Chan = null - - if(chatters) chatters -= C - if(!chatters.len) chatters = null - - UpdateWho() - - chanbot.Say("[C.name] has quit [name]") - - if(C && ChatMan.istelnet(C.key)) - C.Logout() - - UpdateWho() - - //telnet update who - var chatter_array[] = list() - for(var/mob/chatter/C in chatters) - chatter_array += "[dd_replacetext(C.name, " ", "+")][C.afk ? "~" : ""]" - var display = dd_list2text(chatter_array, ",") - - - for(var/mob/chatter/C in chatters) - - var/active = chatters.len - - if(ChatMan.istelnet(C.key)) - C << ".who [display]" - - else - for(var/i=1, i<=chatters.len, i++) - var/mob/chatter/c = chatters[i] - if(isnull(c)) - chatters -= chatters[i] - continue - if(C.client) winset(C, "[ckey(name)].who.grid", "current-cell=1,[i]") - var/n = c.name - if(c==C) - if(c.afk) - active-- - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:gray;font-weight:bold}'") - c.name += " \[AFK]" - else if(C.ckey in C.Chan.operators) - var/Op/O = C.Chan.operators[C.ckey] - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:[O.Rank.color];font-weight:bold}'") - else - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{font-weight:bold}'") - else - if(!ChatMan.istelnet(c.key) && c.afk) - active-- - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:gray}'") - c.name += " \[AFK]" - else if(c.ckey in C.Chan.operators) - var/Op/O = C.Chan.operators[c.ckey] - if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:[O.Rank.color];font-weight:bold}'") - else - if(C.client) winset(C, "[ckey(name)].who.grid", "style=''") - C << output(c, "[ckey(name)].who.grid") - c.name = n - if(C.client) - winset(C, "[ckey(name)].online", "text='[chatters.len] Chatter\s - [active] Active:';") - winset(C, "[ckey(name)].online_left", "text='[chatters.len] Chatter\s - [active] Active:';") - winset(C, "[ckey(name)].who.grid", "cells=1x[chatters.len]") - - SortWho(list/L) - var/list/AFK - for(var/mob/chatter/C in L) - if(C.afk) - if(!AFK) AFK = new - L -= C - AFK += C - if(!L.len) L = null - L = ListMan.atomSort(L) - AFK = ListMan.atomSort(AFK) - if(L && AFK) - return L + AFK - else if(AFK) - return AFK - else - return L - - Say(mob/chatter/C, msg, clean, window) - if(ismute(C)) - chanbot.Say("I'm sorry, but you appear to be muted.",C) - return - - if(length(msg)>512) - var/part2 = copytext(msg, 513) - msg = copytext(msg, 1, 513) - spawn(20) C.Say(part2) - - if(!clean) - msg = TextMan.Sanitize(msg) - chanbot.SpamTimer(C, msg) - - var/raw_msg = msg - msg = TextMan.FilterChat(msg) - - var/smsg = TextMan.ParseSmileys(msg) - smsg = TextMan.ParseLinks(smsg) - - msg = TextMan.ParseLinks(msg) - - if(!window) window = "[ckey(name)].chat.default_output" - - for(var/mob/chatter/c in chatters) - if(c.ignoring(C) & CHAT_IGNORE) continue - var/message - if(!c.filter) - message = raw_msg - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.say_format) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else if(c.filter==1) - message = TextMan.FilterChat(raw_msg,c) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.say_format) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else - message = msg - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) - message = smsg - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.say_format) - if(Parsedmsg) - c << output(Parsedmsg, "[window]") - - - Me(mob/chatter/C, msg, clean, window) - if(ismute(C)) - chanbot.Say("I'm sorry, but you appear to be muted.",C) - return - - if(!clean) msg = TextMan.Sanitize(msg) - - var/raw_msg = msg - msg = TextMan.FilterChat(msg) - - var/smsg = TextMan.ParseSmileys(msg) - smsg = TextMan.ParseLinks(smsg) - - msg = TextMan.ParseLinks(msg) - chanbot.SpamTimer(C, msg) - - if(!window) window = "[ckey(name)].chat.default_output" - - for(var/mob/chatter/c in chatters) - if(!c.ignoring(C)) - var/message - if(!c.filter) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 1) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else if(c.filter==1) - message = TextMan.FilterChat(raw_msg,c) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 1) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else - message = msg - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) - message = smsg - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message, c.me_format, 1) - if(Parsedmsg) - c << output(Parsedmsg, "[window]") - - My(mob/chatter/C, msg, clean, window) - if(ismute(C)) - chanbot.Say("I'm sorry, but you appear to be muted.",C) - return - - if(!clean) msg = TextMan.Sanitize(msg) - - var/raw_msg = msg - msg = TextMan.FilterChat(msg) - - var/smsg = TextMan.ParseSmileys(msg) - smsg = TextMan.ParseLinks(smsg) - - msg = TextMan.ParseLinks(msg) - chanbot.SpamTimer(C, msg) - - if(!window) window = "[ckey(name)].chat.default_output" - - for(var/mob/chatter/c in chatters) - if(!c.ignoring(C)) - var/message - if(!c.filter) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 2) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else if(c.filter==1) - message = TextMan.FilterChat(raw_msg,c) - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) - message = TextMan.ParseLinks(message) - message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 2) - if(Parsedmsg) c << output(Parsedmsg, "[window]") - else - message = msg - if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) - msg = smsg - msg = TextMan.ParseTags(msg, c.show_colors, c.show_highlight,0) - var/Parsedmsg = c.ParseMsg(C,msg, c.me_format, 2) - if(Parsedmsg) - c << output(Parsedmsg, "[window]") - - GoAFK(mob/chatter/C, msg) - if(ChatMan.istelnet(C.key)) return - C.afk = TRUE - C.away_at = world.realtime - msg = TextMan.Sanitize(msg) - C.away_reason = msg - - var/raw_msg = msg - msg = TextMan.FilterChat(msg) - - chatters = SortWho(chatters) - UpdateWho() - if(players && players.len) - players = SortWho(players) - GameMan.UpdateWho(src) - if(!ismute(C)) - for(var/mob/chatter/c in chatters) - if(!(c.ignoring(C) & CHAT_IGNORE)) - if(!c.filter) - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [raw_msg])", "[ckey(name)].chat.default_output") - else if(c.filter == 1) - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [TextMan.FilterChat(raw_msg,c)])", "[ckey(name)].chat.default_output") - else - c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [msg])", "[ckey(name)].chat.default_output") - C << output("Your activity status is now set to Away From Keyboard.", "[ckey(name)].chat.default_output") - - - ReturnAFK(mob/chatter/C) - if(!C) return - C.afk = FALSE - C.away_reason = null - chatters = SortWho(chatters) - UpdateWho() - if(players && players.len) - players = SortWho(players) - GameMan.UpdateWho(src) - if(!ismute(C)) - for(var/mob/chatter/c in chatters) - if(!(c.ignoring(C) & CHAT_IGNORE)) - c << output("[c.ParseTime()] [C.name] is back from AFK after [round(((world.realtime - C.away_at)/600),1)] minute\s of inactivity.", "[ckey(name)].chat.default_output") - C.away_at = null - C << output("Your activity status is now set to Active Chatter.", "[ckey(name)].chat.default_output") - - - ismute(mob/M) - if(mute && mute.len) - if(istext(M)) - if(ckey(M) in mute) return 1 - else if(ismob(M)) - if(M.ckey in mute) return 1 - else return 1 - - - TallyVotes(OpPrivilege/Priv, OpRank/Rank) - if(!Priv) return - var/list/votes = new() - for(var/Ballot/B in ballots) - if(B.privilege == Priv.name) votes += B - if(votes.len < Priv.min_votes) return - switch(Priv.name) - if("Promote") - if(!Rank) return - var/list/nominations = new() - for(var/Ballot/B in votes) - var/OpRank/R = ChatMan.Rank(B.target) - var/OpRank/TargetRank - if(R == "All") TargetRank = op_ranks[op_ranks.len] - else if(R.pos == 1) return - else TargetRank = op_ranks[R.pos-1] - if(TargetRank == Rank) nominations[B] = TargetRank - if(nominations.len < Priv.min_votes) return - if(Rank.max_elect) - var/i=0 - for(var/op in operators) - var/Op/O = operators[op] - if(O.Rank == Rank) i++ - if(i >= Rank.max_elect) - return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - - var/mob/chatter/T = ChatMan.Get(R) - if(!ismob(T)) T = null - else if(T.telnet) return - var/Op/Operator - var/cKey = ckey(R) - if(ckey(founder) == cKey) return - if(cKey in operators) - Operator = operators[cKey] - var/r = op_ranks.Find(Operator.Rank) - if(r == 1) return - Operator.Rank = op_ranks[r-1] - Operator.privileges = Operator.Rank.privs - Operator.RankSelect.name = Operator.Rank.name - else - if(!op_ranks) return - var/i = op_ranks.len - var/OpRank/newRank = op_ranks[i] - Operator = new(R, newRank) - if(T) - if(T.telnet) return - for(var/priv in Operator.privileges) - var/OpPrivilege/P = OpMan.op_privileges[priv] - T.verbs += text2path("/Operator/proc/[P.command]") - if(Operator.Rank.promote) - chanbot.Say("[T.name] was elected to [Operator.Rank.name].") - UpdateWho() - ChanMan.SaveChan(src) - break - if("Demote") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Demote") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - - var/mob/chatter/T = ChatMan.Get(R) - if(!ismob(T)) T = null - var/cKey = ckey(R) - if(ckey(founder) == cKey) return - if(!(cKey in operators)) return - var/Op/Operator = operators[cKey] - var/r = op_ranks.Find(Operator.Rank) - if(r == op_ranks.len) - operators -= cKey - if(T) chanbot.Say("[T.name] was demoted by election.") - else - Operator.Rank = op_ranks[r+1] - Operator.privileges = Operator.Rank.privs - Operator.RankSelect.name = Operator.Rank.name - if(T) - if(Operator.Rank.demote) - chanbot.Say("[T.name] was demoted to [Operator.Rank.name] by election.") - if(T) - for(var/priv in Operator.privileges) - var/OpPrivilege/P = OpMan.op_privileges[priv] - T.verbs -= text2path("/Operator/proc/[P.command]") - UpdateWho() - ChanMan.SaveChan(src) - break - if("Mute") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Mute") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - if(!mute) mute = new - if(!(ckey(R) in mute)) - chanbot.Say("[R] has been muted by election.") - mute += ckey(R) - ChanMan.SaveChan(src) - break - if("Voice") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Voice") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - if(mute && (ckey(R) in mute)) - mute -= ckey(R) - chanbot.Say("[R] has been voiced by election.") - ChanMan.SaveChan(src) - break - if("Kick") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Kick") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - var/mob/chatter/C = ChatMan.Get(R) - if(!C) return - var/reason = "You were removed by a vote of your peers." - chanbot.Say("[C.name] has been kicked by election.") - - if(!ChatMan.istelnet(C.key)) - // clear the chat window of everything but the output - // to reinforce that they are really out of the program - winset(C, "default", "menu=") - if(C.quickbar) C.ToggleQuickBar(1) - C << output(null, "[ckey(name)].chat.default_output") - winset(C, "[ckey(name)].child", "right=") - winset(C, "[ckey(name)].toggle_quickbar", "is-visible=false") - winset(C, "[ckey(name)].set", "is-visible=false") - winset(C, "[ckey(name)].help", "is-visible=false") - winset(C, "[ckey(name)].default_input", "is-disabled=true") - - var/size = winget(C, "[ckey(name)].child", "size") - var/X = copytext(size, 1, findtext(size,"x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))+36 - winset(C, "[ckey(name)].child", "size=[X]x[Y];pos=0,0") - - C << output("You have been kicked from [name].", "[ckey(name)].chat.default_output") - C << output("Reason: [reason]", "[ckey(name)].chat.default_output") - C << output("Connection closed.", "[ckey(name)].chat.default_output") - - chatters -= C - UpdateWho() - - C.Logout() // omgwtfpwnt - if("Ban") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Ban") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - var/reason = "You were removed by a vote of your peers." - chanbot.Say("[R] has been banned by election.") - - if(!banned) banned = new - - banned += ckey(R) - - var/mob/chatter/C = ChatMan.Get(R) - if(C) - if(!ChatMan.istelnet(C.key)) - // clear the chat window of everything but the output - // to reinforce that they are really out of the program - winset(C, "default", "menu=") - if(C.quickbar) C.ToggleQuickBar(1) - C << output(null, "[ckey(name)].chat.default_output") - winset(C, "[ckey(name)].child", "right=") - winset(C, "[ckey(name)].toggle_quickbar", "is-visible=false") - winset(C, "[ckey(name)].set", "is-visible=false") - winset(C, "[ckey(name)].help", "is-visible=false") - winset(C, "[ckey(name)].default_input", "is-disabled=true") - - var/size = winget(C, "[ckey(name)].child", "size") - var/X = copytext(size, 1, findtext(size,"x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))+44 - winset(C, "[ckey(name)].child", "size=[X]x[Y];pos=0,0") - - C << output("You have been banned from [name]", "[ckey(name)].chat.default_output") - C << output("Reason: [reason]", "[ckey(name)].chat.default_output") - C << output("Connection closed.", "[ckey(name)].chat.default_output") - - chatters -= C - UpdateWho() - - C.Logout() // omgwtfpwnt - ChanMan.SaveChan(src) - if("Unban") - var/list/nominations = new() - for(var/Ballot/B in votes) - if(B.privilege == "Unban") nominations += B - if(nominations.len < Priv.min_votes) return - var/list/results = new() - for(var/Ballot/B in nominations) - if(!(B.target in results)) - results[B.target] = 1 - else - results[B.target] += 1 - del(B) - for(var/R in results) - if((results[R]*100/nominations.len) >= Priv.margin) - if((ckey(R) in banned)) - chanbot.Say("[R] has been unbanned by election.") - - banned -= ckey(R) - ChanMan.SaveChan(src) - +Channel + var + founder + name + publicity + desc + topic + pass + locked + telnet_pass + telnet_attempts + QOTD + SuperNode + MaxNodes + + // spam controls + spam_control =1 + spam_limit = 3 + flood_limit = 3 + smileys_limit = 10 + max_msgs = 3 + min_delay = 20 + + room_desc = "An average looking room." + room_desc_size + + Bot + chanbot + list + chatters + players + painters + operators + op_ranks + op_privileges + op_actions + mute + banned + nodes + ballots + showcodes = list() + + filtered_words = list( "fuck" = "fudge", + "shit" = "dung", + " ass" = "donkey", + " asshole"= "donkeyhole", + "penis" = "pencil", + "vagina" = "kitty", + "pussy" = "kitty", + " cunt" = "kitty", + "bitch" = "female dog", + "faggot" = "bundle of sticks", + " fag" = "cigarette", + "nigger" = "ignorant person", + "nigga" = "homeslice", + " dick" = "private eye", + " cock" = "rooster", + "cocksuck"= "milkdrink") + + New(params[]) + if(params) + founder = params["Founder"] + if(!founder) founder = Host.name + name = params["Name"] + publicity = params["Publicity"] + desc = params["Desc"] + topic = params["Topic"] + pass = params["Pass"] + locked = text2num(params["Locked"]) ? 1 : 0 + telnet_pass = params["TelPass"] + telnet_attempts = (text2num(params["TelAtmpts"]) || -1) + SuperNode = text2num(params["SuperNode"]) ? 1 : 0 + MaxNodes = text2num(params["MaxNodes"]) + ..() + chanbot = new /Bot(src) + if(SuperNode) nodes = new() + + proc + LoadOps() + op_ranks = OpMan.op_ranks + var/savefile/S = new("./data/saves/channels/[ckey(name)].sav") + var/list/ops = null + S["operators"] >> ops + if(ops) + operators = listOpen(operators) + for(var/Name in ops) + var/rankIndex = ops[Name] + var/OpRank/Rank = op_ranks[rankIndex] + operators[ckey(Name)] = new/Op(Name, Rank) + + Join(mob/chatter/C) + if(!C || !C.client) + del C + return + + if(C.Chan == src) return + C.Chan = src + winclone(C, "channel", ckey(name)) + winclone(C, "who", "[ckey(name)].who") + winclone(C, "chat", "[ckey(name)].chat") + var/window = ckey(name) + winset(C, null, "[window].default_input.is-default=true;\ + [window].chat.default_output.is-default=true;\ + [window].chat.default_output.is-disabled=false;\ + [window].topic_label.text='[TextMan.escapeQuotes(topic)]';\ + [window].child.left=[window].chat;\ + [window].child.right=[window].who;\ + default.size=[C.winsize];\ + default.can-resize=true;\ + default.title='[name] - Chatters';\ + default.menu=menu;\ + default.child.pos=0,0;\ + default.child.size=[C.winsize];\ + default.child.left=[ckey(name)];") +/* winset(C, "[ckey(name)].default_input", "is-default=true;") + winset(C, "[ckey(name)].chat.default_output", "is-default=true;is-disabled=false.") + winset(C, "[ckey(name)].topic_label", "text='[TextMan.escapeQuotes(topic)]';") + winset(C, "[ckey(name)].child", "left=[ckey(name)].chat; right=[ckey(name)].who") + winset(C, "default", "size=[C.winsize];can-resize=true;title='[name] - Chatters';menu=menu;") + winset(C, "default.child", "pos=0,0;size=[C.winsize];left=[ckey(name)];") +*/ + + if(C.ckey in banned) + C << output("Sorry, you are banned from this channel.", "[ckey(name)].chat.default_output") + C << output("Connection closed.", "[ckey(name)].chat.default_output") + del C + return + + + if(Host == C) winset(C, "default", "menu=host") + + for(var/p in typesof(/Player/proc)-/Player/proc) + C.verbs += p + + if(C.ckey in operators) + if(C.telnet) + operators -= C.ckey + else + var/Op/O = operators[C.ckey] + for(var/priv in O.privileges) + var/OpPrivilege/P = OpMan.op_privileges[priv] + C.verbs += text2path("/Operator/proc/[P.command]") + + if(!C.telnet && winget(C, "[ckey(name)].default_input", "is-disabled") == "true") + // Returning from a kick/ban + var/size = winget(C, "[ckey(name)].child", "size") + var/X = copytext(size, 1, findtext(size,"x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1)) - 44 + winset(C, null, "[window].toggle_quickbar.is-visible=true;\ + [window].set.is-visible=true;\ + [window].help.is-visible=true;\ + [window].default_input.is-disabled=false;\ + [window].child.size=[X]x[Y];\ + [window].child.pos=0,0;") + C.ToggleQuickBar(1) + + if(!C.quickbar) + C.quickbar = TRUE + C.ToggleQuickBar(1) +// if(Host == C) winset(C, "host.quickbar_toggle", "is-checked=false;") +// else winset(C, "menu.quickbar_toggle", "is-checked=false;") + + if(!C.showwho) + C.showwho = TRUE + C.ToggleWho(1) + if(Host == C) + winset(C, "host.who_toggle", "is-checked=false;") + else + winset(C, "menu.who_toggle", "is-checked=false;") + + if(!C.showtopic) + C.showtopic = TRUE + C.ToggleTopic(1) + if(Host == C) + winset(C, "host.topic_toggle", "is-checked=false;") + else + winset(C, "menu.topic_toggle", "is-checked=false;") + + if(C.swaped_panes) + C.swaped_panes = FALSE + C.SwapPanes(1) + + winshow(C, ckey(name), 1) + + winset(C, "[ckey(C.Chan.name)].chat.default_output", "style='[TextMan.escapeQuotes(C.default_output_style)]';max-lines='[C.max_output]';") + if(C.show_title) + if(C.show_colors) + C << output({"[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] +[world.name] - Created by Xooxerand the BYOND Community +[TextMan.fadetext("Still the greatest chat program on BYOND!", list("102000000","255000000","102000000","000000000","000000255"))] +Source available on the Chatters Repository. +Copyright � 2008 Andrew "Xooxer" Arnold +[TextMan.fadetext("##########################################",list("000000000","255000000","255255255"))] +- All Rights Reserved - +"}, "[ckey(name)].chat.default_output") + + else + C << output({"########################################## +[world.name] - Created by Xooxerand the BYOND Community +Still the greatest chat program on BYOND! +Source available on the Chatters Repository. +Copyright � 2008 Andrew "Xooxer" Arnold +########################################## +- All Rights Reserved - +"}, "[ckey(name)].chat.default_output") + + if(C.show_welcome) + C << output("[time2text(world.realtime+C.time_offset, list2text(C.long_date_format))]\nWelcome, [C.name]!\n", "[ckey(name)].chat.default_output") + + if(C.show_motd) NetMan.MOTD(C) + + if(C.show_qotd) TextMan.QOTD(C) + + if(!chatters) chatters = new() + chatters += C + chatters = SortWho(chatters) + + UpdateWho() + + world.status = "[Home.name] founded by [Home.founder] - [Home.chatters.len] chatter\s" + + MapMan.Join(C) + + winset(C, "[ckey(Home.name)].default_input", "text='> ';focus=true;") + + chanbot.Say("[C.name] has joined [name]") + chanbot.Say("You have joined [name] founded by [founder]",C) + chanbot.Say("[topic]",C) + if(!Home.ismute(C)) EventMan.Parse(C, C.onJoin) + NetMan.Report("join", C.name) + + Quit(mob/chatter/C) + if(!C) + for(var/i=1 to chatters.len) + if(!chatters[i]) chatters -= chatters[i] + return + UpdateWho() + + if(C.ckey in operators) + var/Op/O = operators[C.ckey] + if(O.Rank.temp) operators -= C.ckey + + if(!Home.ismute(C)) EventMan.Parse(C, C.onQuit) + C.Chan = null + + if(chatters) chatters -= C + if(!chatters.len) chatters = null + + UpdateWho() + + chanbot.Say("[C.name] has quit [name]") + NetMan.Report("quit", C.name) + + if(C && ChatMan.istelnet(C.key)) + C.Logout() + + UpdateWho() + + //telnet update who + var chatter_array[] = list() + for(var/mob/chatter/C in chatters) + chatter_array += "[dd_replacetext(C.name, " ", "+")][C.afk ? "~" : ""]" + var display = dd_list2text(chatter_array, ",") + + + for(var/mob/chatter/C in chatters) + + var/active = chatters.len + + if(ChatMan.istelnet(C.key)) + C << ".who [display]" + + else + for(var/i=1, i<=chatters.len, i++) + var/mob/chatter/c = chatters[i] + if(isnull(c)) + chatters -= chatters[i] + continue + if(C.client) winset(C, "[ckey(name)].who.grid", "current-cell=1,[i]") + var/n = c.name + if(c==C) + if(c.afk) + active-- + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:gray;font-weight:bold}'") + c.name += " \[AFK]" + else if(C.ckey in C.Chan.operators) + var/Op/O = C.Chan.operators[C.ckey] + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:[O.Rank.color];font-weight:bold}'") + else + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{font-weight:bold}'") + else + if(!ChatMan.istelnet(c.key) && c.afk) + active-- + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:gray}'") + c.name += " \[AFK]" + else if(c.ckey in C.Chan.operators) + var/Op/O = C.Chan.operators[c.ckey] + if(C.client) winset(C, "[ckey(name)].who.grid", "style='body{color:[O.Rank.color];font-weight:bold}'") + else + if(C.client) winset(C, "[ckey(name)].who.grid", "style=''") + C << output(c, "[ckey(name)].who.grid") + c.name = n + if(C.client) + winset(C, "[ckey(name)].online", "text='[chatters.len] Chatter\s - [active] Active:';") + winset(C, "[ckey(name)].online_left", "text='[chatters.len] Chatter\s - [active] Active:';") + winset(C, "[ckey(name)].who.grid", "cells=1x[chatters.len]") + + SortWho(list/L) + var/list/AFK + for(var/mob/chatter/C in L) + if(C.afk) + if(!AFK) AFK = new + L -= C + AFK += C + if(!L.len) L = null + L = ListMan.atomSort(L) + AFK = ListMan.atomSort(AFK) + if(L && AFK) + return L + AFK + else if(AFK) + return AFK + else + return L + + Say(mob/chatter/C, msg, clean, window) + if(ismute(C)) + chanbot.Say("I'm sorry, but you appear to be muted.",C) + return + + if(length(msg)>512) + var/part2 = copytext(msg, 513) + msg = copytext(msg, 1, 513) + spawn(20) C.Say(part2) + + if(!clean) + msg = TextMan.Sanitize(msg) + chanbot.SpamTimer(C, msg) + + var/raw_msg = msg + msg = TextMan.FilterChat(msg) + + var/smsg = TextMan.ParseSmileys(msg) + smsg = TextMan.ParseLinks(smsg) + + msg = TextMan.ParseLinks(msg) + + if(!window) window = "[ckey(name)].chat.default_output" + + for(var/mob/chatter/c in chatters) + if(c.ignoring(C) & CHAT_IGNORE) continue + var/message + if(!c.filter) + message = raw_msg + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.say_format) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else if(c.filter==1) + message = TextMan.FilterChat(raw_msg,c) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.say_format) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else + message = msg + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) + message = smsg + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.say_format) + if(Parsedmsg) + c << output(Parsedmsg, "[window]") + + + Me(mob/chatter/C, msg, clean, window) + if(ismute(C)) + chanbot.Say("I'm sorry, but you appear to be muted.",C) + return + + if(!clean) msg = TextMan.Sanitize(msg) + + var/raw_msg = msg + msg = TextMan.FilterChat(msg) + + var/smsg = TextMan.ParseSmileys(msg) + smsg = TextMan.ParseLinks(smsg) + + msg = TextMan.ParseLinks(msg) + chanbot.SpamTimer(C, msg) + + if(!window) window = "[ckey(name)].chat.default_output" + + for(var/mob/chatter/c in chatters) + if(!c.ignoring(C)) + var/message + if(!c.filter) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 1) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else if(c.filter==1) + message = TextMan.FilterChat(raw_msg,c) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 1) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else + message = msg + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) + message = smsg + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message, c.me_format, 1) + if(Parsedmsg) + c << output(Parsedmsg, "[window]") + + My(mob/chatter/C, msg, clean, window) + if(ismute(C)) + chanbot.Say("I'm sorry, but you appear to be muted.",C) + return + + if(!clean) msg = TextMan.Sanitize(msg) + + var/raw_msg = msg + msg = TextMan.FilterChat(msg) + + var/smsg = TextMan.ParseSmileys(msg) + smsg = TextMan.ParseLinks(smsg) + + msg = TextMan.ParseLinks(msg) + chanbot.SpamTimer(C, msg) + + if(!window) window = "[ckey(name)].chat.default_output" + + for(var/mob/chatter/c in chatters) + if(!c.ignoring(C)) + var/message + if(!c.filter) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(raw_msg) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 2) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else if(c.filter==1) + message = TextMan.FilterChat(raw_msg,c) + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) message = TextMan.ParseSmileys(message) + message = TextMan.ParseLinks(message) + message = TextMan.ParseTags(message, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,message,c.me_format, 2) + if(Parsedmsg) c << output(Parsedmsg, "[window]") + else + message = msg + if(c.show_smileys && !(c.ignoring(C) & SMILEY_IGNORE)) + msg = smsg + msg = TextMan.ParseTags(msg, c.show_colors, c.show_highlight,0) + var/Parsedmsg = c.ParseMsg(C,msg, c.me_format, 2) + if(Parsedmsg) + c << output(Parsedmsg, "[window]") + + GoAFK(mob/chatter/C, msg) + if(ChatMan.istelnet(C.key)) return + C.afk = TRUE + C.away_at = world.realtime + msg = TextMan.Sanitize(msg) + C.away_reason = msg + + var/raw_msg = msg + msg = TextMan.FilterChat(msg) + + chatters = SortWho(chatters) + UpdateWho() + if(players && players.len) + players = SortWho(players) + GameMan.UpdateWho(src) + if(!ismute(C)) + for(var/mob/chatter/c in chatters) + if(!(c.ignoring(C) & CHAT_IGNORE)) + if(!c.filter) + c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [raw_msg])", "[ckey(name)].chat.default_output") + else if(c.filter == 1) + c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [TextMan.FilterChat(raw_msg,c)])", "[ckey(name)].chat.default_output") + else + c << output("[c.ParseTime()] [C.name] is now AFK. (Reason: [msg])", "[ckey(name)].chat.default_output") + C << output("Your activity status is now set to Away From Keyboard.", "[ckey(name)].chat.default_output") + + + ReturnAFK(mob/chatter/C) + if(!C) return + C.afk = FALSE + C.away_reason = null + chatters = SortWho(chatters) + UpdateWho() + if(players && players.len) + players = SortWho(players) + GameMan.UpdateWho(src) + if(!ismute(C)) + for(var/mob/chatter/c in chatters) + if(!(c.ignoring(C) & CHAT_IGNORE)) + c << output("[c.ParseTime()] [C.name] is back from AFK after [round(((world.realtime - C.away_at)/600),1)] minute\s of inactivity.", "[ckey(name)].chat.default_output") + C.away_at = null + C << output("Your activity status is now set to Active Chatter.", "[ckey(name)].chat.default_output") + + + ismute(mob/M) + if(mute && mute.len) + if(istext(M)) + if(ckey(M) in mute) return 1 + else if(ismob(M)) + if(M.ckey in mute) return 1 + else return 1 + + + TallyVotes(OpPrivilege/Priv, OpRank/Rank) + if(!Priv) return + var/list/votes = new() + for(var/Ballot/B in ballots) + if(B.privilege == Priv.name) votes += B + if(votes.len < Priv.min_votes) return + switch(Priv.name) + if("Promote") + if(!Rank) return + var/list/nominations = new() + for(var/Ballot/B in votes) + var/OpRank/R = ChatMan.Rank(B.target) + var/OpRank/TargetRank + if(R == "All") TargetRank = op_ranks[op_ranks.len] + else if(R.pos == 1) return + else TargetRank = op_ranks[R.pos-1] + if(TargetRank == Rank) nominations[B] = TargetRank + if(nominations.len < Priv.min_votes) return + if(Rank.max_elect) + var/i=0 + for(var/op in operators) + var/Op/O = operators[op] + if(O.Rank == Rank) i++ + if(i >= Rank.max_elect) + return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + + var/mob/chatter/T = ChatMan.Get(R) + if(!ismob(T)) T = null + else if(T.telnet) return + var/Op/Operator + var/cKey = ckey(R) + if(ckey(founder) == cKey) return + if(cKey in operators) + Operator = operators[cKey] + var/r = op_ranks.Find(Operator.Rank) + if(r == 1) return + Operator.Rank = op_ranks[r-1] + Operator.privileges = Operator.Rank.privs + Operator.RankSelect.name = Operator.Rank.name + else + if(!op_ranks) return + var/i = op_ranks.len + var/OpRank/newRank = op_ranks[i] + Operator = new(R, newRank) + if(T) + if(T.telnet) return + for(var/priv in Operator.privileges) + var/OpPrivilege/P = OpMan.op_privileges[priv] + T.verbs += text2path("/Operator/proc/[P.command]") + if(Operator.Rank.promote) + chanbot.Say("[T.name] was elected to [Operator.Rank.name].") + UpdateWho() + ChanMan.SaveChan(src) + break + if("Demote") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Demote") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + + var/mob/chatter/T = ChatMan.Get(R) + if(!ismob(T)) T = null + var/cKey = ckey(R) + if(ckey(founder) == cKey) return + if(!(cKey in operators)) return + var/Op/Operator = operators[cKey] + var/r = op_ranks.Find(Operator.Rank) + if(r == op_ranks.len) + operators -= cKey + if(T) chanbot.Say("[T.name] was demoted by election.") + else + Operator.Rank = op_ranks[r+1] + Operator.privileges = Operator.Rank.privs + Operator.RankSelect.name = Operator.Rank.name + if(T) + if(Operator.Rank.demote) + chanbot.Say("[T.name] was demoted to [Operator.Rank.name] by election.") + if(T) + for(var/priv in Operator.privileges) + var/OpPrivilege/P = OpMan.op_privileges[priv] + T.verbs -= text2path("/Operator/proc/[P.command]") + UpdateWho() + ChanMan.SaveChan(src) + break + if("Mute") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Mute") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + if(!mute) mute = new + if(!(ckey(R) in mute)) + chanbot.Say("[R] has been muted by election.") + mute += ckey(R) + ChanMan.SaveChan(src) + break + if("Voice") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Voice") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + if(mute && (ckey(R) in mute)) + mute -= ckey(R) + chanbot.Say("[R] has been voiced by election.") + ChanMan.SaveChan(src) + break + if("Kick") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Kick") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + var/mob/chatter/C = ChatMan.Get(R) + if(!C) return + var/reason = "You were removed by a vote of your peers." + chanbot.Say("[C.name] has been kicked by election.") + + if(!ChatMan.istelnet(C.key)) + // clear the chat window of everything but the output + // to reinforce that they are really out of the program + winset(C, "default", "menu=") + if(C.quickbar) C.ToggleQuickBar(1) + C << output(null, "[ckey(name)].chat.default_output") + winset(C, "[ckey(name)].child", "right=") + winset(C, "[ckey(name)].toggle_quickbar", "is-visible=false") + winset(C, "[ckey(name)].set", "is-visible=false") + winset(C, "[ckey(name)].help", "is-visible=false") + winset(C, "[ckey(name)].default_input", "is-disabled=true") + + var/size = winget(C, "[ckey(name)].child", "size") + var/X = copytext(size, 1, findtext(size,"x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))+36 + winset(C, "[ckey(name)].child", "size=[X]x[Y];pos=0,0") + + C << output("You have been kicked from [name].", "[ckey(name)].chat.default_output") + C << output("Reason: [reason]", "[ckey(name)].chat.default_output") + C << output("Connection closed.", "[ckey(name)].chat.default_output") + + chatters -= C + UpdateWho() + + C.Logout() // omgwtfpwnt + if("Ban") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Ban") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + var/reason = "You were removed by a vote of your peers." + chanbot.Say("[R] has been banned by election.") + + if(!banned) banned = new + + banned += ckey(R) + + var/mob/chatter/C = ChatMan.Get(R) + if(C) + if(!ChatMan.istelnet(C.key)) + // clear the chat window of everything but the output + // to reinforce that they are really out of the program + winset(C, "default", "menu=") + if(C.quickbar) C.ToggleQuickBar(1) + C << output(null, "[ckey(name)].chat.default_output") + winset(C, "[ckey(name)].child", "right=") + winset(C, "[ckey(name)].toggle_quickbar", "is-visible=false") + winset(C, "[ckey(name)].set", "is-visible=false") + winset(C, "[ckey(name)].help", "is-visible=false") + winset(C, "[ckey(name)].default_input", "is-disabled=true") + + var/size = winget(C, "[ckey(name)].child", "size") + var/X = copytext(size, 1, findtext(size,"x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))+44 + winset(C, "[ckey(name)].child", "size=[X]x[Y];pos=0,0") + + C << output("You have been banned from [name]", "[ckey(name)].chat.default_output") + C << output("Reason: [reason]", "[ckey(name)].chat.default_output") + C << output("Connection closed.", "[ckey(name)].chat.default_output") + + chatters -= C + UpdateWho() + + C.Logout() // omgwtfpwnt + ChanMan.SaveChan(src) + if("Unban") + var/list/nominations = new() + for(var/Ballot/B in votes) + if(B.privilege == "Unban") nominations += B + if(nominations.len < Priv.min_votes) return + var/list/results = new() + for(var/Ballot/B in nominations) + if(!(B.target in results)) + results[B.target] = 1 + else + results[B.target] += 1 + del(B) + for(var/R in results) + if((results[R]*100/nominations.len) >= Priv.margin) + if((ckey(R) in banned)) + chanbot.Say("[R] has been unbanned by election.") + + banned -= ckey(R) + ChanMan.SaveChan(src) + diff --git a/code/models/chatter/_main.dm b/code/models/chatter/_main.dm index 5ed3370..522b065 100644 --- a/code/models/chatter/_main.dm +++ b/code/models/chatter/_main.dm @@ -1,194 +1,198 @@ - -mob - chatter - var - name_color - text_color - background - fade_name - show_colors = TRUE - - _24hr_time = TRUE - time_offset = 0 - auto_away = 15 - auto_reason = "I have gone auto-AFK." - - default_output_style = ".code{color:#000000}.ident {color:#606}.comment {color:#666}.preproc {color:#008000}.keyword {color:#00f}.string {color:#0096b4}.number {color:#800000}body {text-indent: -8px;}" - ticker = 0 - - show_smileys = TRUE - show_images = TRUE - forced_punctuation = FALSE - - picture - age = "No age given." - location = "No location provided." - description = "No description available." - interests = "No interests supplied." - - onJoin = "me(\"enters the channel.\")" - onQuit = "me(\"exits the channel.\")" - - filter = 2 - replacement_word = "" - - quickbar = TRUE - showwho = TRUE - showtopic = TRUE - swaped_panes = FALSE - show_title = TRUE - show_welcome = TRUE - show_motd = TRUE - show_qotd = TRUE - show_highlight = TRUE - - clear_on_reboot = FALSE - max_output = 1000 - - telnet_pass - - winsize = "640x480" - - im_sounds = TRUE - im_volume = 100 - got_msg_snd = "./data/sndfx/mallert 010.wav" - snt_msg_snd = "./data/sndfx/mallert 009.wav" - - // Added to notify a user if his name has been said in conversation. - // - name_notify = FALSE - - tmp/Painter/Painter - - tmp/OpRank/RankSelect - tmp/OpPrivilege/PrivSelectLeft - tmp/OpPrivilege/PrivSelectRight - - tmp/obj/OpNameSelect/NameSelect - tmp/game_color - tmp/afk = FALSE - tmp/telnet = FALSE - tmp/away_at = 0 - tmp/away_reason - tmp/spam_num - tmp/flood_flag - tmp/flood_num - tmp/list/msgs - tmp/Channel/Chan - tmp/ColorView/CV - tmp/MessageHandler/MsgHand - - list - ignoring - fade_colors = list("#000000") - - time_format = list("\[","hh",":","mm",":","ss","]") - date_format = list("MMM"," ","MM",", `","YY") - long_date_format = list("Day",", ","Month"," ","DD",", ","YYYY") - say_format = list("$ts", " ","$name",": ","$msg") - rpsay_format = list("$ts", " ","$name"," ","$rp",": ","$msg") - me_format = list("$ts", " ", "$name", " ", "$msg") - - filtered_words - - tmp/msgHandlers - tmp/Tags = list("\[b]" = "\[/b]", - "\[i]" = "\[/i]", - "\[u]" = "\[/u]", - "\[s]" = "\[/s]", - "\[code]" = "\[/code]") - tmp/Smileys = list(":)",":(",":D","<:(",">:(",">:D") - tmp/Colors = list("#C00","#0C0","#00C","#CC0","#C0C","#0CC","#000") - - - New() - ..() - MsgHand = new(src) - CV = new(src) - - Login() - ..() - - if(!ChatMan.istelnet(key)) - src << output("Name:", "pub_chans.grid:1,1") - src << output("Founder:", "pub_chans.grid:2,1") - src << output("Description:", "pub_chans.grid:3,1") - src << output("Chatters:", "pub_chans.grid:4,1") - if(winget(src, "default", "is-maximized")=="true") - winset(src, "default", "is-maximized=false;size='484x244'") - else - winset(src, "default", "size='484x244';") - if(!fade_name) - if(name_color) - fade_name = "[name]" - else - fade_name = name - if(!gender) gender = client.gender - if(Home) - ChanMan.Join(src, Home) - else - winset(src, "default.output", "is-visible=true") - winset(src, "default.child", "is-visible=false") - src << output("Please wait while your host configures the channel...", "default.output") - while(!Home) sleep(10) - winset(src, "default.output", "is-visible=false") - winset(src, "default.child", "is-visible=true") - ChanMan.Join(src, Home) - for(var/obj/help/topic/T in world) - src << output("[T.name]", "topics_grid.output") - spawn() Ticker() - - // Telnet users login differently - else - //Set options suited for telnet. - telnet = TRUE - show_colors = FALSE - show_smileys = FALSE - show_highlight = FALSE - onJoin = "" - onQuit = "" - - if(!fade_name) fade_name = name - if(!gender) gender = client.gender - if(Home) ChanMan.Join(src, Home) - - Stat() - ..() - if(src.telnet) return - if(auto_away && (auto_away < client.inactivity/600) && !afk) afk(auto_reason) - if(Chan && Chan.players && Chan.players.len) - if(src in Chan.players) - if(winget(src,"games", "is-visible")=="false") - Chan.players -= src - Chan.players = Chan.SortWho(Chan.players) - GameMan.UpdateWho(Chan) - if(afk) ReturnAFK() - if(src.msgHandlers && src.msgHandlers.len) - for(var/msgHandler in msgHandlers) - var/open = winget(src, "cim_[msgHandler]", "is-visible") - if(open == "false") - src << output(null, "cim_[msgHandler].output") - winset(src, "cim_[msgHandler].input", "text=") - for(var/i=1,i<=3,i++) - winset(src, "cim_[msgHandler].tag[i]", "is-checked=false") - for(var/i=1,i<=7,i++) - winset(src, "cim_[msgHandler].color[i]", "is-checked=false;text=") - var/C = src.Colors[i] - src.Colors[C] = null - var/Messenger/M = msgHandlers[msgHandler] - msgHandlers -= msgHandler - del(M) - if(src.Painter) - var/open = winget(src, "map", "is-visible") - if(open == "false") - del(src.Painter) - - Click() - call(usr, "LookAt")(key) - - - Logout() - if(Console && Chan) ChanMan.Quit(src, Chan) - ..() - sleep(50) + +mob + chatter + var + name_color + text_color + background + fade_name + show_colors = TRUE + + _24hr_time = TRUE + time_offset = 0 + auto_away = 15 + auto_reason = "I have gone auto-AFK." + + default_output_style = ".code{color:#000000}.ident {color:#606}.comment {color:#666}.preproc {color:#008000}.keyword {color:#00f}.string {color:#0096b4}.number {color:#800000}body {text-indent: -8px;}" + ticker = 0 + + show_smileys = TRUE + show_images = TRUE + forced_punctuation = FALSE + + picture + age = "No age given." + location = "No location provided." + description = "No description available." + interests = "No interests supplied." + + onJoin = "me(\"enters the channel.\")" + onQuit = "me(\"exits the channel.\")" + + filter = 2 + replacement_word = "" + + quickbar = TRUE + showwho = TRUE + showtopic = TRUE + swaped_panes = FALSE + show_title = TRUE + show_welcome = TRUE + show_motd = TRUE + show_qotd = TRUE + show_highlight = TRUE + + clear_on_reboot = FALSE + max_output = 1000 + + telnet_pass + + winsize = "640x480" + + im_sounds = TRUE + im_volume = 100 + got_msg_snd = "./data/sndfx/mallert 010.wav" + snt_msg_snd = "./data/sndfx/mallert 009.wav" + + // Added to notify a user if his name has been said in conversation. + // + name_notify = FALSE + + tmp/Painter/Painter + + tmp/OpRank/RankSelect + tmp/OpPrivilege/PrivSelectLeft + tmp/OpPrivilege/PrivSelectRight + + tmp/obj/OpNameSelect/NameSelect + tmp/game_color + tmp/afk = FALSE + tmp/telnet = FALSE + tmp/away_at = 0 + tmp/away_reason + tmp/spam_num + tmp/flood_flag + tmp/flood_num + tmp/list/msgs + tmp/Channel/Chan + tmp/ColorView/CV + tmp/MessageHandler/MsgHand + + list + ignoring + fade_colors = list("#000000") + + time_format = list("\[","hh",":","mm",":","ss","]") + date_format = list("MMM"," ","MM",", `","YY") + long_date_format = list("Day",", ","Month"," ","DD",", ","YYYY") + say_format = list("$ts", " ","$name",": ","$msg") + rpsay_format = list("$ts", " ","$name"," ","$rp",": ","$msg") + me_format = list("$ts", " ", "$name", " ", "$msg") + + filtered_words + + tmp/msgHandlers + tmp/Tags = list("\[b]" = "\[/b]", + "\[i]" = "\[/i]", + "\[u]" = "\[/u]", + "\[s]" = "\[/s]", + "\[code]" = "\[/code]") + tmp/Smileys = list(":)",":(",":D","<:(",">:(",">:D") + tmp/Colors = list("#C00","#0C0","#00C","#CC0","#C0C","#0CC","#000") + + + New() + ..() + MsgHand = new(src) + CV = new(src) + + Login() + ..() + + if(!ChatMan.istelnet(key)) + src << output("Name:", "pub_chans.grid:1,1") + src << output("Founder:", "pub_chans.grid:2,1") + src << output("Description:", "pub_chans.grid:3,1") + src << output("Chatters:", "pub_chans.grid:4,1") + if(winget(src, "default", "is-maximized")=="true") + winset(src, "default", "is-maximized=false;size='484x244'") + else + winset(src, "default", "size='484x244';") + if(!fade_name) + if(name_color) + fade_name = "[name]" + else + fade_name = name + if(!gender) gender = client.gender + if(!NetMan.HostCheck(client)) + if(Home) + ChanMan.Join(src, Home) + else + winset(src, "default.output", "is-visible=true") + winset(src, "default.child", "is-visible=false") + src << output("Please wait while your host configures the channel...", "default.output") + while(!Home) sleep(10) + winset(src, "default.output", "is-visible=false") + winset(src, "default.child", "is-visible=true") + ChanMan.Join(src, Home) + else if(Home) + ChanMan.Join(src, Home) + for(var/obj/help/topic/T in world) + src << output("[T.name]", "topics_grid.output") + spawn() Ticker() + + // Telnet users login differently + else + //Set options suited for telnet. + telnet = TRUE + show_colors = FALSE + show_smileys = FALSE + show_highlight = FALSE + onJoin = "" + onQuit = "" + + if(!fade_name) fade_name = name + if(!gender) gender = client.gender + if(!NetMan.HostCheck(client)) + if(Home) ChanMan.Join(src, Home) + + Stat() + ..() + if(src.telnet) return + if(auto_away && (auto_away < client.inactivity/600) && !afk) afk(auto_reason) + if(Chan && Chan.players && Chan.players.len) + if(src in Chan.players) + if(winget(src,"games", "is-visible")=="false") + Chan.players -= src + Chan.players = Chan.SortWho(Chan.players) + GameMan.UpdateWho(Chan) + if(afk) ReturnAFK() + if(src.msgHandlers && src.msgHandlers.len) + for(var/msgHandler in msgHandlers) + var/open = winget(src, "cim_[msgHandler]", "is-visible") + if(open == "false") + src << output(null, "cim_[msgHandler].output") + winset(src, "cim_[msgHandler].input", "text=") + for(var/i=1,i<=3,i++) + winset(src, "cim_[msgHandler].tag[i]", "is-checked=false") + for(var/i=1,i<=7,i++) + winset(src, "cim_[msgHandler].color[i]", "is-checked=false;text=") + var/C = src.Colors[i] + src.Colors[C] = null + var/Messenger/M = msgHandlers[msgHandler] + msgHandlers -= msgHandler + del(M) + if(src.Painter) + var/open = winget(src, "map", "is-visible") + if(open == "false") + del(src.Painter) + + Click() + call(usr, "LookAt")(key) + + + Logout() + if(Console && Chan) ChanMan.Quit(src, Chan) + ..() + sleep(50) if(!client) del(src) \ No newline at end of file diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 083e9c9..0113ae2 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -1,598 +1,599 @@ -mob - chatter - verb - // Temporary, toggle name notify. - Notify() - name_notify = !name_notify - - src << "You will no[name_notify ? "w" : "t"] be notified if your name is said." - - - Vote(ballot as text|null) - var/OpRank/Rank = ChatMan.Rank(name) - if(!ballot) - usr << output("Voting Failed. usage: /Vote Privilege Name", "[ckey(Chan.name)].chat.default_output") - usr << output("Available privileges: Promote Demote Mute Voice Kick Ban Unban", "[ckey(Chan.name)].chat.default_output") - return - var/space = findtext(ballot, " ") - var/privilege = lowertext(copytext(ballot, 1, space)) - var/target - if(space && (length(ballot) > space)) - target = copytext(ballot, space+1) - switch(privilege) - if("promote") votePromote(privilege, Rank, target) - if("demote") voteDemote (privilege, Rank, target) - if("mute") voteMute (privilege, Rank, target) - if("voice") voteVoice (privilege, Rank, target) - if("kick") voteKick (privilege, Rank, target) - if("ban") voteBan (privilege, Rank, target) - if("unban") voteUnban (privilege, Rank, target) - - Send(target as text|null|mob in Home.chatters, file as file|null) - if(!target) - target = input("Who would you like to send a file to?", "Send File") as text|null - if(!target) return - var/mob/chatter/C - if(ismob(target)) C = target - else C = ChatMan.Get(target) - if(!C) - if(src.Chan) - src << output("[target] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert("[target] is not currently online.", "Unable to locate chatter") - else - if(ismob(C)) - var/ign = C.ignoring(ckey) - if(ign & FILES_IGNORE) - alert("[C.name] is currently ignoring files from you.", "Unable to Transfer File") - return - if(!file) - file = input("Select the file you wish to send to [C.name]", "Upload File") as file|null - if(!file) return - if(length(file) > MAX_FILE_SIZE) - alert("This file ([fsize(file)]) exceeds the limit of [fsize(MAX_FILE_SIZE)].","File Size Limit Exceeded.") - fdel(file) - return - switch(alert(C, "[name] is trying to send you a file: [file] ([fsize(file)])","[name] File Transfer","Accept","Reject","Ignore")) - if("Accept") - C << ftp(file) - alert("File ([file]) accepted by [C.name].","File Transfer Complete") - if("Reject") - alert("File ([file]) rejected by [C.name].","File Transfer Failed") - if("Ignore") - C.Ignore(name,"files") - alert("File ([file]) rejected by [C.name].","File Transfer Failed") - - login(telnet_key as text|null) - set hidden = 1 - if(!telnet_key) return - if(!telnet) return - var/savefile/S = new("./data/saves/tel.net") - if(!S || !length(S)) return - var/list/L = new - S["telnet"] >> L - if(!L || !L.len) return - var/key_hash = md5(telnet_key) - if(key_hash in L) - var/telnet_pass = input("Please enter your telnet password:", "Telnet Key Login") as password|null - if(!telnet_pass) - del(L) - return - if(L[key_hash] != md5(telnet_pass)) - del(L) - return - del(L) - name = telnet_key - fade_name = name - Home.UpdateWho() - - Set() - call(usr, "ShowSet")() - - Help() - ShowHelp() - - Cmail() - //ShowChattersMail() - - Say(msg as text|null) - if(!msg) return - if(afk) ReturnAFK() - for(var/i=1,i<=5,i++) - if(!client) continue - winset(src, "[ckey(Home.name)].tag[i]", "is-checked=false") - for(var/i=1,i<=7,i++) - if(!client) continue - winset(src, "[ckey(Home.name)].color[i]", "is-checked=false;text=") - var/C = src.Colors[i] - src.Colors[C] = null - Chan.Say(src, msg) - - Me(msg as text|null) - if(!msg) return - if(afk) ReturnAFK() - Chan.Me(src, msg) - - My(msg as text|null) - if(!msg) return - if(afk) ReturnAFK() - Chan.My(src, msg) - - IM(target as text|null|mob in Home.chatters, msg as text|null) - if(!target) - var/Messenger/im = new(src) - im.Display(src) - return - var/mob/C - if(ismob(target)) C = target - else C = ChatMan.Get(target) - for(var/i=1,i<=3,i++) - if(!client) continue - winset(src, "cim_[C.ckey].tag[i]", "is-checked=false") - for(var/i=1,i<=7,i++) - if(!client) continue - winset(src, "cim_[C.ckey].color[i]", "is-checked=false;text=") - var/N = src.Colors[i] - src.Colors[N] = null - if(!C) - if(src.Chan) - src << output("[target] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert(src, "[target] is not currently online.", "Unable to locate chatter") - else - if(ismob(C)) - if(!msg) - var/Messenger/im = new(src, C.name) - im.Display(src) - return - if(length(msg)>512) - var/part2 = copytext(msg, 513) - msg = copytext(msg, 1, 513) - spawn(20) IM(C.name, part2) - - var/Messenger/im = new(src, C.name) - im.Display(src) - MsgMan.RouteMsg(src, C, msg) - else - if(!msg) - var/Messenger/im = new(src, C) - im.Display(src) - return - if(length(msg)>512) - var/part2 = copytext(msg, 513) - msg = copytext(msg, 1, 513) - spawn(20) IM(C, part2) - - var/Messenger/im = new(src, C) - im.Display(src) - var/savefile/S = new() - var/mob/chatter/M = new() - - M.name = name - M.name_color = name_color - M.text_color = text_color - M.fade_name = fade_name - M.picture = picture - M.age = age - M.location = location - M.description = description - M.interests = interests - - S["from"] << M - S["msg"] << msg - S["to"] << C - - src << output(src.ParseMsg(src, msg, src.say_format), "cim_[C.ckey].output") - - Ignore(mob/target as text|null|mob in Home.chatters, scope as text|null|anything in list("im", "chat", "fade", "colors", "smileys", "images", "files", "full")) - if(!target) - if(src.Chan) - src << output("Please provide a name. Proper usage: /Ignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("Please provide a name. Proper usage: /Ignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "Ignore") - return - if(!ignoring) ignoring = new - if(ismob(target)) target = target.name - var/is_ignored = ignoring(target) - if(is_ignored == FULL_IGNORE) - if(src.Chan) - src << output("You are already ignoring [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are already ignoring [target].", "Unable to ignore chatter") - return - if(!scope) scope = "[FULL_IGNORE]" - var/ignore_type = "this scope" - switch(scope) - if("im") - scope = "[IM_IGNORE]" - ignore_type = "instant messages" - if("chat") - scope = "[CHAT_IGNORE]" - ignore_type = "chat messages" - if("fade") - scope = "[FADE_IGNORE]" - ignore_type = "fades" - if("colors") - scope = "[COLOR_IGNORE]" - ignore_type = "colors" - if("smileys") - scope = "[SMILEY_IGNORE]" - ignore_type = "smileys" - if("images") - scope = "[IMAGES_IGNORE]" - ignore_type = "images" - if("files") - scope = "[FILES_IGNORE]" - ignore_type = "files" - if("full") scope = "[FULL_IGNORE]" - var/num = text2num(scope) - if(num && isnum(num)) - if(num & is_ignored) - if(src.Chan) - src << output("You are already ignoring [ignore_type] from [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are already ignoring [ignore_type] from [target].","Unable to ignore chatter") - return - num += is_ignored - ignore_type = "" - if(num == 31) num = FULL_IGNORE - if(num & FULL_IGNORE) scope = FULL_IGNORE - else - scope = 0 - if(num & IM_IGNORE) - scope |= IM_IGNORE - ignore_type += "\n - instant messages" - if(ckey(target) in msgHandlers) - winset(src, "cim_[ckey(target)]", "is-visible=false") - if(num & CHAT_IGNORE) - scope |= CHAT_IGNORE - ignore_type += "\n - chat messages" - if(num & FADE_IGNORE) - scope |= FADE_IGNORE - ignore_type += "\n - fade name" - if(num & COLOR_IGNORE) - scope |= COLOR_IGNORE - ignore_type += "\n - colors" - if(num & SMILEY_IGNORE) - scope |= SMILEY_IGNORE - ignore_type += "\n - smileys" - if(num & IMAGES_IGNORE) - scope |= IMAGES_IGNORE - ignore_type += "\n - images" - if(num & FILES_IGNORE) - scope |= FILES_IGNORE - ignore_type += "\n - files" - if(!scope) - if(src.Chan) - src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full","Unable to ignore chatter") - return - else - if(src.Chan) - src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full", "[ckey(Home.name)].chat.default_output") - else - alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full","Unable to ignore chatter") - return - if(!is_ignored) ignoring += ckey(target) - ignoring[ckey(target)] = scope - if(length(ignore_type)) - if(src.Chan) - src << output("You are now ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") - else - alert("You are now ignoring the following from [target]: [ignore_type]", "Ignoring chatter") - else - if(src.Chan) - src << output("You are now fully ignoring [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are now fully ignoring [target].", "Ignoring chatter") - ChatMan.Save(src) - - - Unignore(mob/target as text|null|anything in ignoring, scope as text|null|anything in list("im", "chat", "fade", "colors", "smileys", "images", "files", "full")) - if(!target) - if(src.Chan) - src << output("Please provide a name. Proper usage: /Unignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("Please provide a name. Proper usage: /Unignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "Unignore") - return - if(!ignoring || !ignoring.len) - if(src.Chan) - src << output("You are not currently ignoring any chatters.", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring any chatters.", "Unable to unignore chatter") - return - if(ismob(target)) target = target.name - var/ign = ignoring(target) - if(!ign) - if(src.Chan) - src << output("You are not currently ignoring [target]", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring [target]", "Unable to unignore chatter") - return - if(!scope) scope = "[FULL_IGNORE]" - var/ignore_type = "this scope" - switch(scope) - if("im") - scope = "[IM_IGNORE]" - ignore_type = "instant messages" - if("chat") - scope = "[CHAT_IGNORE]" - ignore_type = "chat messages" - if("fade") - scope = "[FADE_IGNORE]" - ignore_type = "fades" - if("colors") - scope = "[COLOR_IGNORE]" - ignore_type = "colors" - if("smileys") - scope = "[SMILEY_IGNORE]" - ignore_type = "smileys" - if("images") - scope = "[IMAGES_IGNORE]" - ignore_type = "images" - if("files") - scope = "[FILES_IGNORE]" - ignore_type = "files" - if("full") scope = "[FULL_IGNORE]" - var/num = text2num(scope) - if(num && isnum(num)) - if((num != FULL_IGNORE) && !(num & ign)) - if(src.Chan) - src << output("You are not currently ignoring [ignore_type] from [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring [ignore_type] from [target].","Unable to unignore chatter") - return - ignore_type = "" - if(num == 31) num = FULL_IGNORE - if(num & FULL_IGNORE) scope = FULL_IGNORE - else - scope = 0 - if(num & IM_IGNORE) - scope |= IM_IGNORE - if(ign - IM_IGNORE) - ignore_type += "\n - instant messages" - if(num & CHAT_IGNORE) - scope |= CHAT_IGNORE - if(ign - CHAT_IGNORE) - ignore_type += "\n - chat messages" - if(num & FADE_IGNORE) - scope |= FADE_IGNORE - if(ign - FADE_IGNORE) - ignore_type += "\n - fade name" - if(num & COLOR_IGNORE) - scope |= COLOR_IGNORE - if(ign - COLOR_IGNORE) - ignore_type += "\n - colors" - if(num & SMILEY_IGNORE) - scope |= SMILEY_IGNORE - if(ign - SMILEY_IGNORE) - ignore_type += "\n - smileys" - if(num & IMAGES_IGNORE) - scope |= IMAGES_IGNORE - if(ign - IMAGES_IGNORE) - ignore_type += "\n - images" - if(num & FILES_IGNORE) - scope |= FILES_IGNORE - if(ign - FILES_IGNORE) - ignore_type += "\n - files" - if(!scope) - if(src.Chan) - src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full","Unable to unignore chatter") - return - else - if(src.Chan) - src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") - else - alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full","Unable to unignore chatter") - return - if(scope == FULL_IGNORE) ignoring -= ckey(target) - else ignoring[ckey(target)] &= ~scope - if(!ignoring[ckey(target)]) - ignoring -= ckey(target) - ignore_type = "" - if(length(ignore_type)) - if(src.Chan) - src << output("You are no longer ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") - else - alert("You are no longer ignoring the following from [target]: [ignore_type]", "Unignoring chatter") - else - if(src.Chan) - src << output("You are no longer ignoring [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are no longer ignoring [target].", "Unignoring chatter") - ChatMan.Save(src) - - Ignoring(mob/target as text|null|anything in ignoring) - if(!ignoring || !ignoring.len) - if(src.Chan) - src << output("You are not currently ignoring any chatters.", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring any chatters.", "No chatters ignored") - return - if(!target) - var/ignored - for(var/i in ignoring) - var/scoped - if((ignoring[i] & FULL_IGNORE)) scoped = "Full ignore" - else - if((ignoring[i] & IM_IGNORE)) - if(!scoped) scoped = "IMs" - else scoped += ", IMs" - if((ignoring[i] & CHAT_IGNORE)) - if(!scoped) scoped = "chat" - else scoped += ", chat" - if((ignoring[i] & FADE_IGNORE)) - if(!scoped) scoped = "fade name" - else scoped += ", fade name" - if((ignoring[i] & COLOR_IGNORE)) - if(!scoped) scoped = "colors" - else scoped += ", colors" - if((ignoring[i] & SMILEY_IGNORE)) - if(!scoped) scoped = "smileys" - else scoped += ", smileys" - if((ignoring[i] & IMAGES_IGNORE)) - if(!scoped) scoped = "images" - else scoped += ", images" - if((ignoring[i] & FILES_IGNORE)) - if(!scoped) scoped = "files" - else scoped += ", files" - ignored += "\n[i] - [scoped]" - if(src.Chan) - src << output("You are currently ignoring the following chatters.[ignored]", "[ckey(Home.name)].chat.default_output") - else - alert("You are currently ignoring the following chatters.[ignored]", "Not Ignoring chatter") - return - if(ismob(target)) target = target.name - var/ign = ignoring(target) - if(!ign) - if(src.Chan) - src << output("You are not currently ignoring [target]", "[ckey(Home.name)].chat.default_output") - else - alert("You are not currently ignoring [target]", "Not Ignoring chatter") - return - var/ignore_type = "" - if(!(ign & FULL_IGNORE)) - if(ign & IM_IGNORE) - if(ign - IM_IGNORE) - ignore_type += "\n - instant messages" - if(ign & CHAT_IGNORE) - if(ign - CHAT_IGNORE) - ignore_type += "\n - chat messages" - if(ign & FADE_IGNORE) - if(ign - FADE_IGNORE) - ignore_type += "\n - fade name" - if(ign & COLOR_IGNORE) - if(ign - COLOR_IGNORE) - ignore_type += "\n - colors" - if(ign & SMILEY_IGNORE) - if(ign - SMILEY_IGNORE) - ignore_type += "\n - smileys" - if(ign & IMAGES_IGNORE) - if(ign - IMAGES_IGNORE) - ignore_type += "\n - images" - if(ign & FILES_IGNORE) - if(ign - FILES_IGNORE) - ignore_type += "\n - files" - if(length(ignore_type)) - if(src.Chan) - src << output("You are ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") - else - alert("You are ignoring the following from [target]: [ignore_type]", "Ignoring chatter") - else - if(src.Chan) - src << output("You are fully ignoring [target].", "[ckey(Home.name)].chat.default_output") - else - alert("You are fully ignoring [target].", "Ignoring chatter") - - Look() - if(!Chan) return - if(!Chan.room_desc) - src << output("Looking around, you see....\n\tAn average looking room.", "[ckey(Chan.name)].chat.default_output") - return - if(Chan.room_desc_size >= 500) - switch(alert("This room description exceeds the recomended room description size. (500 characters) Would you like to view it anyways?","Room Description Size Alert! [Chan.room_desc_size] characters!","Yes","No")) - if("No") return - src << output("Looking around, you see....\n\t[Chan.room_desc]", "[ckey(Chan.name)].chat.default_output") - - - LookAt(t as text|null|mob in Home.chatters) - if(!t) return - var/mob/chatter/C - if(ismob(t)) C = t - else C = ChatMan.Get(t) - if(!C) - if(src.Chan) - src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert(src, "[t] is not currently online.", "Unable to locate chatter") - else - src << output(null, "profile.output") - if(C.picture) - src << output("\...", "profile.output") - else - src << browse_rsc('./resources/images/noimage.png', "noimage.png") - src << output("\...", "profile.output") - winset(src, "profile.key", "text=' [TextMan.escapeQuotes(C.name)]") - winset(src, "profile.age", "text=' [TextMan.escapeQuotes(C.age)]") - winset(src, "profile.gender", "text=' [C.gender]") - winset(src, "profile.location", "text=' [TextMan.escapeQuotes(C.location)]") - winset(src, "profile.description", "text=' [TextMan.escapeQuotes(C.description)]") - winset(src, "profile.interests", "text=' [TextMan.escapeQuotes(C.interests)]") - winset(src, "profile", "is-visible=true") - winset(src, "profile.show_button", "command='ShowCode \"[C.name]\"';") - winset(src, "profile.im_button", "command='IM \"[C.name]\"';") - - ShowCode(t as text|null|mob in Home.chatters) - if(afk) ReturnAFK() - var/showcode_snippet/S = new - if(t) - var/mob/chatter/C - if(ismob(t)) C = t - else C = ChatMan.Get(t) - if(!C) - if(src.Chan) - src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert(src, "[t] is not currently online.", "Unable to locate chatter") - else - var/ign = C.ignoring(src) - if(ign && CHAT_IGNORE) - src << "Unable to show code!" - src << "[C.name] is ignoring you." - return - S.target = C.ckey - else - if(!src.Chan || Chan.ismute(src)) - if(src.Chan) src.Chan.chanbot.Say("I'm sorry, but you appear to be muted.", src) - return - - var/iCode = input("Paste your code below") as message - S.owner = "[src.name]" - S.code = iCode - S.Send(1) - - ShowText(t as text|null|mob in Home.chatters) - if(afk) ReturnAFK() - - var/showcode_snippet/S = new - if(t) - var/mob/chatter/C - if(ismob(t)) C = t - else C = ChatMan.Get(t) - if(!C) - if(src.Chan) - src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") - else - alert(src, "[t] is not currently online.", "Unable to locate chatter") - else - var/ign = C.ignoring(src) - if(ign && CHAT_IGNORE) - src << "Unable to show code!" - src << "[C.name] is ignoring you." - return - S.target = C.ckey - else - if(!src.Chan || Chan.ismute(src)) - if(src.Chan) src.Chan.chanbot.Say("I'm sorry, but you appear to be muted.", src) - return - - var/iCode = input("Paste your text below") as message - S.owner = "[src.name]" - S.code = iCode - S.Send() - - afk(msg as text|null) - if(!Chan) return - if(!afk) - if(!msg) msg = auto_reason - Home.GoAFK(src, msg) - else - ReturnAFK() - Filter(msg as text|null) - switch(ckey(msg)) - if("on","1") filter=2 - if("off","0") filter=0 +mob + chatter + verb + // Temporary, toggle name notify. + Notify() + name_notify = !name_notify + + src << "You will no[name_notify ? "w" : "t"] be notified if your name is said." + + + Vote(ballot as text|null) + var/OpRank/Rank = ChatMan.Rank(name) + if(!ballot) + usr << output("Voting Failed. usage: /Vote Privilege Name", "[ckey(Chan.name)].chat.default_output") + usr << output("Available privileges: Promote Demote Mute Voice Kick Ban Unban", "[ckey(Chan.name)].chat.default_output") + return + var/space = findtext(ballot, " ") + var/privilege = lowertext(copytext(ballot, 1, space)) + var/target + if(space && (length(ballot) > space)) + target = copytext(ballot, space+1) + switch(privilege) + if("promote") votePromote(privilege, Rank, target) + if("demote") voteDemote (privilege, Rank, target) + if("mute") voteMute (privilege, Rank, target) + if("voice") voteVoice (privilege, Rank, target) + if("kick") voteKick (privilege, Rank, target) + if("ban") voteBan (privilege, Rank, target) + if("unban") voteUnban (privilege, Rank, target) + + Send(target as text|null|mob in Home.chatters, file as file|null) + if(!target) + target = input("Who would you like to send a file to?", "Send File") as text|null + if(!target) return + var/mob/chatter/C + if(ismob(target)) C = target + else C = ChatMan.Get(target) + if(!C) + if(src.Chan) + src << output("[target] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert("[target] is not currently online.", "Unable to locate chatter") + else + if(ismob(C)) + var/ign = C.ignoring(ckey) + if(ign & FILES_IGNORE) + alert("[C.name] is currently ignoring files from you.", "Unable to Transfer File") + return + if(!file) + file = input("Select the file you wish to send to [C.name]", "Upload File") as file|null + if(!file) return + if(length(file) > MAX_FILE_SIZE) + alert("This file ([fsize(file)]) exceeds the limit of [fsize(MAX_FILE_SIZE)].","File Size Limit Exceeded.") + fdel(file) + return + switch(alert(C, "[name] is trying to send you a file: [file] ([fsize(file)])","[name] File Transfer","Accept","Reject","Ignore")) + if("Accept") + C << ftp(file) + alert("File ([file]) accepted by [C.name].","File Transfer Complete") + if("Reject") + alert("File ([file]) rejected by [C.name].","File Transfer Failed") + if("Ignore") + C.Ignore(name,"files") + alert("File ([file]) rejected by [C.name].","File Transfer Failed") + + login(telnet_key as text|null) + set hidden = 1 + if(!telnet_key) return + if(!telnet) return + var/savefile/S = new("./data/saves/tel.net") + if(!S || !length(S)) return + var/list/L = new + S["telnet"] >> L + if(!L || !L.len) return + var/key_hash = md5(telnet_key) + if(key_hash in L) + var/telnet_pass = input("Please enter your telnet password:", "Telnet Key Login") as password|null + if(!telnet_pass) + del(L) + return + if(L[key_hash] != md5(telnet_pass)) + del(L) + return + del(L) + name = telnet_key + fade_name = name + Home.UpdateWho() + + Set() + call(usr, "ShowSet")() + + Help() + ShowHelp() + + Cmail() + //ShowChattersMail() + + Say(msg as text|null) + if(!msg) return + if(afk) ReturnAFK() + for(var/i=1,i<=5,i++) + if(!client) continue + winset(src, "[ckey(Home.name)].tag[i]", "is-checked=false") + for(var/i=1,i<=7,i++) + if(!client) continue + winset(src, "[ckey(Home.name)].color[i]", "is-checked=false;text=") + var/C = src.Colors[i] + src.Colors[C] = null + Chan.Say(src, msg) + + Me(msg as text|null) + if(!msg) return + if(afk) ReturnAFK() + Chan.Me(src, msg) + + My(msg as text|null) + if(!msg) return + if(afk) ReturnAFK() + Chan.My(src, msg) + + IM(target as text|null|mob in Home.chatters, msg as text|null) + if(!target) + var/Messenger/im = new(src) + im.Display(src) + return + var/mob/C + if(ismob(target)) C = target + else C = ChatMan.Get(target) + for(var/i=1,i<=3,i++) + if(!client) continue + winset(src, "cim_[C.ckey].tag[i]", "is-checked=false") + for(var/i=1,i<=7,i++) + if(!client) continue + winset(src, "cim_[C.ckey].color[i]", "is-checked=false;text=") + var/N = src.Colors[i] + src.Colors[N] = null + if(!C) + if(src.Chan) + src << output("[target] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert(src, "[target] is not currently online.", "Unable to locate chatter") + else + if(ismob(C)) + if(!msg) + var/Messenger/im = new(src, C.name) + im.Display(src) + return + if(length(msg)>512) + var/part2 = copytext(msg, 513) + msg = copytext(msg, 1, 513) + spawn(20) IM(C.name, part2) + + var/Messenger/im = new(src, C.name) + im.Display(src) + MsgMan.RouteMsg(src, C, msg) + else + if(!msg) + var/Messenger/im = new(src, C) + im.Display(src) + return + if(length(msg)>512) + var/part2 = copytext(msg, 513) + msg = copytext(msg, 1, 513) + spawn(20) IM(C, part2) + + var/Messenger/im = new(src, C) + im.Display(src) + var/savefile/S = new() + var/mob/chatter/M = new() + + M.name = name + M.name_color = name_color + M.text_color = text_color + M.fade_name = fade_name + M.picture = picture + M.age = age + M.location = location + M.description = description + M.interests = interests + + S["from"] << M + S["msg"] << msg + S["to"] << C + + src << output(src.ParseMsg(src, msg, src.say_format), "cim_[C.ckey].output") + world.Export("[NetMan.Chatters[C]]?dest=msgman&action=msg",S) + + Ignore(mob/target as text|null|mob in Home.chatters, scope as text|null|anything in list("im", "chat", "fade", "colors", "smileys", "images", "files", "full")) + if(!target) + if(src.Chan) + src << output("Please provide a name. Proper usage: /Ignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("Please provide a name. Proper usage: /Ignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "Ignore") + return + if(!ignoring) ignoring = new + if(ismob(target)) target = target.name + var/is_ignored = ignoring(target) + if(is_ignored == FULL_IGNORE) + if(src.Chan) + src << output("You are already ignoring [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are already ignoring [target].", "Unable to ignore chatter") + return + if(!scope) scope = "[FULL_IGNORE]" + var/ignore_type = "this scope" + switch(scope) + if("im") + scope = "[IM_IGNORE]" + ignore_type = "instant messages" + if("chat") + scope = "[CHAT_IGNORE]" + ignore_type = "chat messages" + if("fade") + scope = "[FADE_IGNORE]" + ignore_type = "fades" + if("colors") + scope = "[COLOR_IGNORE]" + ignore_type = "colors" + if("smileys") + scope = "[SMILEY_IGNORE]" + ignore_type = "smileys" + if("images") + scope = "[IMAGES_IGNORE]" + ignore_type = "images" + if("files") + scope = "[FILES_IGNORE]" + ignore_type = "files" + if("full") scope = "[FULL_IGNORE]" + var/num = text2num(scope) + if(num && isnum(num)) + if(num & is_ignored) + if(src.Chan) + src << output("You are already ignoring [ignore_type] from [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are already ignoring [ignore_type] from [target].","Unable to ignore chatter") + return + num += is_ignored + ignore_type = "" + if(num == 31) num = FULL_IGNORE + if(num & FULL_IGNORE) scope = FULL_IGNORE + else + scope = 0 + if(num & IM_IGNORE) + scope |= IM_IGNORE + ignore_type += "\n - instant messages" + if(ckey(target) in msgHandlers) + winset(src, "cim_[ckey(target)]", "is-visible=false") + if(num & CHAT_IGNORE) + scope |= CHAT_IGNORE + ignore_type += "\n - chat messages" + if(num & FADE_IGNORE) + scope |= FADE_IGNORE + ignore_type += "\n - fade name" + if(num & COLOR_IGNORE) + scope |= COLOR_IGNORE + ignore_type += "\n - colors" + if(num & SMILEY_IGNORE) + scope |= SMILEY_IGNORE + ignore_type += "\n - smileys" + if(num & IMAGES_IGNORE) + scope |= IMAGES_IGNORE + ignore_type += "\n - images" + if(num & FILES_IGNORE) + scope |= FILES_IGNORE + ignore_type += "\n - files" + if(!scope) + if(src.Chan) + src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full","Unable to ignore chatter") + return + else + if(src.Chan) + src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full", "[ckey(Home.name)].chat.default_output") + else + alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files full","Unable to ignore chatter") + return + if(!is_ignored) ignoring += ckey(target) + ignoring[ckey(target)] = scope + if(length(ignore_type)) + if(src.Chan) + src << output("You are now ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") + else + alert("You are now ignoring the following from [target]: [ignore_type]", "Ignoring chatter") + else + if(src.Chan) + src << output("You are now fully ignoring [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are now fully ignoring [target].", "Ignoring chatter") + ChatMan.Save(src) + + + Unignore(mob/target as text|null|anything in ignoring, scope as text|null|anything in list("im", "chat", "fade", "colors", "smileys", "images", "files", "full")) + if(!target) + if(src.Chan) + src << output("Please provide a name. Proper usage: /Unignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("Please provide a name. Proper usage: /Unignore \"Chatter\" \"scope\" Available Scopes: im, chat, fade, colors, smileys, images, files, full", "Unignore") + return + if(!ignoring || !ignoring.len) + if(src.Chan) + src << output("You are not currently ignoring any chatters.", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring any chatters.", "Unable to unignore chatter") + return + if(ismob(target)) target = target.name + var/ign = ignoring(target) + if(!ign) + if(src.Chan) + src << output("You are not currently ignoring [target]", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring [target]", "Unable to unignore chatter") + return + if(!scope) scope = "[FULL_IGNORE]" + var/ignore_type = "this scope" + switch(scope) + if("im") + scope = "[IM_IGNORE]" + ignore_type = "instant messages" + if("chat") + scope = "[CHAT_IGNORE]" + ignore_type = "chat messages" + if("fade") + scope = "[FADE_IGNORE]" + ignore_type = "fades" + if("colors") + scope = "[COLOR_IGNORE]" + ignore_type = "colors" + if("smileys") + scope = "[SMILEY_IGNORE]" + ignore_type = "smileys" + if("images") + scope = "[IMAGES_IGNORE]" + ignore_type = "images" + if("files") + scope = "[FILES_IGNORE]" + ignore_type = "files" + if("full") scope = "[FULL_IGNORE]" + var/num = text2num(scope) + if(num && isnum(num)) + if((num != FULL_IGNORE) && !(num & ign)) + if(src.Chan) + src << output("You are not currently ignoring [ignore_type] from [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring [ignore_type] from [target].","Unable to unignore chatter") + return + ignore_type = "" + if(num == 31) num = FULL_IGNORE + if(num & FULL_IGNORE) scope = FULL_IGNORE + else + scope = 0 + if(num & IM_IGNORE) + scope |= IM_IGNORE + if(ign - IM_IGNORE) + ignore_type += "\n - instant messages" + if(num & CHAT_IGNORE) + scope |= CHAT_IGNORE + if(ign - CHAT_IGNORE) + ignore_type += "\n - chat messages" + if(num & FADE_IGNORE) + scope |= FADE_IGNORE + if(ign - FADE_IGNORE) + ignore_type += "\n - fade name" + if(num & COLOR_IGNORE) + scope |= COLOR_IGNORE + if(ign - COLOR_IGNORE) + ignore_type += "\n - colors" + if(num & SMILEY_IGNORE) + scope |= SMILEY_IGNORE + if(ign - SMILEY_IGNORE) + ignore_type += "\n - smileys" + if(num & IMAGES_IGNORE) + scope |= IMAGES_IGNORE + if(ign - IMAGES_IGNORE) + ignore_type += "\n - images" + if(num & FILES_IGNORE) + scope |= FILES_IGNORE + if(ign - FILES_IGNORE) + ignore_type += "\n - files" + if(!scope) + if(src.Chan) + src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full","Unable to unignore chatter") + return + else + if(src.Chan) + src << output("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full", "[ckey(Home.name)].chat.default_output") + else + alert("The scope you provided did not match a known ignore scope. Available Scopes: im, chat, fade, colors, smileys, images, files, full","Unable to unignore chatter") + return + if(scope == FULL_IGNORE) ignoring -= ckey(target) + else ignoring[ckey(target)] &= ~scope + if(!ignoring[ckey(target)]) + ignoring -= ckey(target) + ignore_type = "" + if(length(ignore_type)) + if(src.Chan) + src << output("You are no longer ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") + else + alert("You are no longer ignoring the following from [target]: [ignore_type]", "Unignoring chatter") + else + if(src.Chan) + src << output("You are no longer ignoring [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are no longer ignoring [target].", "Unignoring chatter") + ChatMan.Save(src) + + Ignoring(mob/target as text|null|anything in ignoring) + if(!ignoring || !ignoring.len) + if(src.Chan) + src << output("You are not currently ignoring any chatters.", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring any chatters.", "No chatters ignored") + return + if(!target) + var/ignored + for(var/i in ignoring) + var/scoped + if((ignoring[i] & FULL_IGNORE)) scoped = "Full ignore" + else + if((ignoring[i] & IM_IGNORE)) + if(!scoped) scoped = "IMs" + else scoped += ", IMs" + if((ignoring[i] & CHAT_IGNORE)) + if(!scoped) scoped = "chat" + else scoped += ", chat" + if((ignoring[i] & FADE_IGNORE)) + if(!scoped) scoped = "fade name" + else scoped += ", fade name" + if((ignoring[i] & COLOR_IGNORE)) + if(!scoped) scoped = "colors" + else scoped += ", colors" + if((ignoring[i] & SMILEY_IGNORE)) + if(!scoped) scoped = "smileys" + else scoped += ", smileys" + if((ignoring[i] & IMAGES_IGNORE)) + if(!scoped) scoped = "images" + else scoped += ", images" + if((ignoring[i] & FILES_IGNORE)) + if(!scoped) scoped = "files" + else scoped += ", files" + ignored += "\n[i] - [scoped]" + if(src.Chan) + src << output("You are currently ignoring the following chatters.[ignored]", "[ckey(Home.name)].chat.default_output") + else + alert("You are currently ignoring the following chatters.[ignored]", "Not Ignoring chatter") + return + if(ismob(target)) target = target.name + var/ign = ignoring(target) + if(!ign) + if(src.Chan) + src << output("You are not currently ignoring [target]", "[ckey(Home.name)].chat.default_output") + else + alert("You are not currently ignoring [target]", "Not Ignoring chatter") + return + var/ignore_type = "" + if(!(ign & FULL_IGNORE)) + if(ign & IM_IGNORE) + if(ign - IM_IGNORE) + ignore_type += "\n - instant messages" + if(ign & CHAT_IGNORE) + if(ign - CHAT_IGNORE) + ignore_type += "\n - chat messages" + if(ign & FADE_IGNORE) + if(ign - FADE_IGNORE) + ignore_type += "\n - fade name" + if(ign & COLOR_IGNORE) + if(ign - COLOR_IGNORE) + ignore_type += "\n - colors" + if(ign & SMILEY_IGNORE) + if(ign - SMILEY_IGNORE) + ignore_type += "\n - smileys" + if(ign & IMAGES_IGNORE) + if(ign - IMAGES_IGNORE) + ignore_type += "\n - images" + if(ign & FILES_IGNORE) + if(ign - FILES_IGNORE) + ignore_type += "\n - files" + if(length(ignore_type)) + if(src.Chan) + src << output("You are ignoring the following from [target]: [ignore_type]", "[ckey(Home.name)].chat.default_output") + else + alert("You are ignoring the following from [target]: [ignore_type]", "Ignoring chatter") + else + if(src.Chan) + src << output("You are fully ignoring [target].", "[ckey(Home.name)].chat.default_output") + else + alert("You are fully ignoring [target].", "Ignoring chatter") + + Look() + if(!Chan) return + if(!Chan.room_desc) + src << output("Looking around, you see....\n\tAn average looking room.", "[ckey(Chan.name)].chat.default_output") + return + if(Chan.room_desc_size >= 500) + switch(alert("This room description exceeds the recomended room description size. (500 characters) Would you like to view it anyways?","Room Description Size Alert! [Chan.room_desc_size] characters!","Yes","No")) + if("No") return + src << output("Looking around, you see....\n\t[Chan.room_desc]", "[ckey(Chan.name)].chat.default_output") + + + LookAt(t as text|null|mob in Home.chatters) + if(!t) return + var/mob/chatter/C + if(ismob(t)) C = t + else C = ChatMan.Get(t) + if(!C) + if(src.Chan) + src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert(src, "[t] is not currently online.", "Unable to locate chatter") + else + src << output(null, "profile.output") + if(C.picture) + src << output("\...", "profile.output") + else + src << browse_rsc('./resources/images/noimage.png', "noimage.png") + src << output("\...", "profile.output") + winset(src, "profile.key", "text=' [TextMan.escapeQuotes(C.name)]") + winset(src, "profile.age", "text=' [TextMan.escapeQuotes(C.age)]") + winset(src, "profile.gender", "text=' [C.gender]") + winset(src, "profile.location", "text=' [TextMan.escapeQuotes(C.location)]") + winset(src, "profile.description", "text=' [TextMan.escapeQuotes(C.description)]") + winset(src, "profile.interests", "text=' [TextMan.escapeQuotes(C.interests)]") + winset(src, "profile", "is-visible=true") + winset(src, "profile.show_button", "command='ShowCode \"[C.name]\"';") + winset(src, "profile.im_button", "command='IM \"[C.name]\"';") + + ShowCode(t as text|null|mob in Home.chatters) + if(afk) ReturnAFK() + var/showcode_snippet/S = new + if(t) + var/mob/chatter/C + if(ismob(t)) C = t + else C = ChatMan.Get(t) + if(!C) + if(src.Chan) + src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert(src, "[t] is not currently online.", "Unable to locate chatter") + else + var/ign = C.ignoring(src) + if(ign && CHAT_IGNORE) + src << "Unable to show code!" + src << "[C.name] is ignoring you." + return + S.target = C.ckey + else + if(!src.Chan || Chan.ismute(src)) + if(src.Chan) src.Chan.chanbot.Say("I'm sorry, but you appear to be muted.", src) + return + + var/iCode = input("Paste your code below") as message + S.owner = "[src.name]" + S.code = iCode + S.Send(1) + + ShowText(t as text|null|mob in Home.chatters) + if(afk) ReturnAFK() + + var/showcode_snippet/S = new + if(t) + var/mob/chatter/C + if(ismob(t)) C = t + else C = ChatMan.Get(t) + if(!C) + if(src.Chan) + src << output("[t] is not currently online.", "[ckey(src.Chan.name)].chat.default_output") + else + alert(src, "[t] is not currently online.", "Unable to locate chatter") + else + var/ign = C.ignoring(src) + if(ign && CHAT_IGNORE) + src << "Unable to show code!" + src << "[C.name] is ignoring you." + return + S.target = C.ckey + else + if(!src.Chan || Chan.ismute(src)) + if(src.Chan) src.Chan.chanbot.Say("I'm sorry, but you appear to be muted.", src) + return + + var/iCode = input("Paste your text below") as message + S.owner = "[src.name]" + S.code = iCode + S.Send() + + afk(msg as text|null) + if(!Chan) return + if(!afk) + if(!msg) msg = auto_reason + Home.GoAFK(src, msg) + else + ReturnAFK() + Filter(msg as text|null) + switch(ckey(msg)) + if("on","1") filter=2 + if("off","0") filter=0 src << "Filter set [msg]" \ No newline at end of file diff --git a/code/models/chatter/controls.dm b/code/models/chatter/controls.dm index c093974..53dd5c0 100644 --- a/code/models/chatter/controls.dm +++ b/code/models/chatter/controls.dm @@ -1,422 +1,423 @@ - -mob - chatter - verb - - SwapPanes(nosave as num|null) - set hidden = 1 - if(!src.Chan) return - if(!src.showwho) return - src.swaped_panes ^= 1 - var/splitter = text2num(winget(src, "[ckey(Home.name)].child", "splitter")) - winset(src, "[ckey(Home.name)].child", "splitter=[100-splitter]") - if(src.swaped_panes) - winset(src, "[ckey(Home.name)].child", "left='[ckey(Home.name)].who'") - winset(src, "[ckey(Home.name)].child", "right='[ckey(Home.name)].chat'") - winset(src, "[ckey(Home.name)].topic_label", "pos='132,0'") - winset(src, "[ckey(Home.name)].online", "is-visible=false") - winset(src, "[ckey(Home.name)].online_left", "is-visible=true") - else - winset(src, "[ckey(Home.name)].child", "left='[ckey(Home.name)].chat'") - winset(src, "[ckey(Home.name)].child", "right='[ckey(Home.name)].who'") - winset(src, "[ckey(Home.name)].topic_label", "pos='0,0'") - winset(src, "[ckey(Home.name)].online", "is-visible=true") - winset(src, "[ckey(Home.name)].online_left", "is-visible=false") - if(!nosave) - winsize = winget(src, "default", "size") - ChatMan.Save(src) - - ToggleTopic(nosave as num|null) - set hidden = 1 - if(!src.Chan) return - if(src.showtopic) - winset(src, "[ckey(Home.name)].topic_label", "is-visible=false") - src.showtopic = FALSE - if(Host == src) winset(src, "host.topic_toggle", "is-checked=false;") - else winset(src, "menu.topic_toggle", "is-checked=false;") - if(!showwho && !nosave) - var/size = winget(src, "default.child", "size") - var/X = copytext(size, 1, findtext(size, "x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))+20 - winset(src, "default.child", "pos='0,-20';size='[X]x[Y]'") - else - winset(src, "[ckey(Home.name)].topic_label", "is-visible=true") - src.showtopic = TRUE - if(Host == src) winset(src, "host.topic_toggle", "is-checked=true;") - else winset(src, "menu.topic_toggle", "is-checked=true;") - if(!showwho && !nosave) - var/size = winget(src, "default.child", "size") - var/X = copytext(size, 1, findtext(size, "x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))-20 - winset(src, "default.child", "pos='0,0';size='[X]x[Y]'") - if(!nosave) - winsize = winget(src, "default", "size") - ChatMan.Save(src) - - ToggleWho(nosave as num|null) - set hidden = 1 - if(!src.Chan) return - var/pos = "right" - if(src.swaped_panes) pos = "left" - if(src.showwho) - winset(src, "[ckey(Home.name)].child", "[pos]=") - winset(src, "[ckey(Home.name)].online", "is-visible=false") - src.showwho = FALSE - if(Host == src) winset(src, "host.who_toggle", "is-checked=false;") - else winset(src, "menu.who_toggle", "is-checked=false;") - if(!showtopic) - var/size = winget(src, "default.child", "size") - var/X = copytext(size, 1, findtext(size, "x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))+20 - winset(src, "default.child", "pos='0,-20';size='[X]x[Y]'") - - else - winset(src, "[ckey(Home.name)].child", "[pos]='[ckey(Home.name)].who'") - winset(src, "[ckey(Home.name)].online", "is-visible=true") - src.showwho = TRUE - if(Host == src) winset(src, "host.who_toggle", "is-checked=true;") - else winset(src, "menu.who_toggle", "is-checked=true;") - if(!showtopic) - var/size = winget(src, "default.child", "size") - var/X = copytext(size, 1, findtext(size, "x")) - var/Y = text2num(copytext(size, findtext(size, "x")+1))-20 - winset(src, "default.child", "pos='0,0';size='[X]x[Y]'") - if(!nosave) - winsize = winget(src, "default", "size") - ChatMan.Save(src) - - ToggleQuickBar(nosave as num|null) - set hidden = 1 - if(!Chan) return - var/i - var/size = winget(src, "[ckey(Home.name)].child", "size") - var/seperator = findtext(size, "x") - var/X = copytext(size,1,seperator) - var/Y = text2num(copytext(size,seperator+1)) - var/window = ckey(Home.name) - if(src.quickbar) - Y += 16 - for(i=1, i<=5, i++) - winset(src, "[window].tag[i]","is-visible=false") - for(i=1, i<=6, i++) - winset(src, "[window].smiley[i]","is-visible=false") - for(i=1, i<=7, i++) - winset(src, "[window].color[i]","is-visible=false") - winset(src, "[window].toggle_quickbar", "text='+'") - quickbar = FALSE - if(Host == src) winset(src, "host.quickbar_toggle", "is-checked=false;") - else winset(src, "menu.quickbar_toggle", "is-checked=false;") - else - Y -= 16 - for(i=1, i<=5, i++) - winset(src, "[window].tag[i]","is-visible=true") - for(i=1, i<=6, i++) - winset(src, "[window].smiley[i]","is-visible=true") - for(i=1, i<=7, i++) - winset(src, "[window].color[i]","is-visible=true") - winset(src, "[window].toggle_quickbar", "text='-'") - quickbar = TRUE - if(Host == src) winset(src, "host.quickbar_toggle", "is-checked=true;") - else winset(src, "menu.quickbar_toggle", "is-checked=true;") - winset(src, null, "[window].child.size=[X]x[Y];\ - [window].default_input.focus=true;") - if(!nosave) - winsize = winget(src, "default", "size") - ChatMan.Save(src) - - - ToggleCIMBar(window as text|null) - set hidden = 1 - if(!window) return - window = "cim_[ckey(window)]" - var/i - - var/outsize = winget(src, "[window].output", "size") - var/outseperator = findtext(outsize, "x") - var/outX = copytext(outsize,1,outseperator) - var/outY = text2num(copytext(outsize,outseperator+1)) - - var/profpos = winget(src, "[window].profile", "pos") - var/profseperator = findtext(profpos, ",") - var/profX = copytext(profpos,1,profseperator) - var/profY = text2num(copytext(profpos,profseperator+1)) - - var/showpos = winget(src, "[window].show", "pos") - var/showseperator = findtext(showpos, ",") - var/showX = copytext(showpos,1,showseperator) - var/showY = text2num(copytext(showpos,showseperator+1)) - - var/sharepos = winget(src, "[window].share", "pos") - var/shareseperator = findtext(sharepos, ",") - var/shareX = copytext(sharepos,1,shareseperator) - var/shareY = text2num(copytext(sharepos,shareseperator+1)) - - var/invpos = winget(src, "[window].invite", "pos") - var/invseperator = findtext(invpos, ",") - var/invX = copytext(invpos,1,invseperator) - var/invY = text2num(copytext(invpos,invseperator+1)) - - var/joinpos = winget(src, "[window].join", "pos") - var/joinseperator = findtext(joinpos, ",") - var/joinX = copytext(joinpos,1,joinseperator) - var/joinY = text2num(copytext(joinpos,joinseperator+1)) - - if(winget(src, "[window].tag1", "is-visible") == "true") - outY += 20 - profY += 20 - showY += 20 - shareY += 20 - invY += 20 - joinY += 20 - for(i=1, i<=3, i++) - winset(src, "[window].tag[i]","is-visible=false") - for(i=1, i<=6, i++) - winset(src, "[window].smiley[i]","is-visible=false") - for(i=1, i<=7, i++) - winset(src, "[window].color[i]","is-visible=false") - winset(src, "[window].toggle_quickbar", "text='+'") - else - outY -= 20 - profY -= 20 - showY -= 20 - shareY -= 20 - invY -= 20 - joinY -= 20 - for(i=1, i<=3, i++) - winset(src, "[window].tag[i]","is-visible=true") - for(i=1, i<=6, i++) - winset(src, "[window].smiley[i]","is-visible=true") - for(i=1, i<=7, i++) - winset(src, "[window].color[i]","is-visible=true") - winset(src, "[window].toggle_quickbar", "text='-'") - winset(src, "[window].profile", "pos=[profX],[profY]") - winset(src, "[window].show", "pos=[showX],[showY]") - winset(src, "[window].share", "pos=[shareX],[shareY]") - winset(src, "[window].invite", "pos=[invX],[invY]") - winset(src, "[window].join", "pos=[joinX],[joinY]") - winset(src, "[window].output", "size=[outX]x[outY]") - winset(src, "[window].input", "focus=true") - - NewInstantMessage() - set hidden = 1 - var/Messenger/im = new(src) - im.Display(src) - - ShowGameWindow() - set hidden = 1 - winshow(src, "game", 1) - - HideGameWindow() - set hidden = 1 - winshow(src, "game", 0) - - ShowChattersMail() - set hidden = 1 - winshow(src, "cmail", 1) - - HideChattersMail() - set hidden = 1 - winshow(src, "cmail", 0) - - ShowAbout() - set hidden = 1 - winshow(src, "about", 1) - - HideAbout() - set hidden = 1 - winshow(src, "about", 0) - - ShowCredits() - set hidden = 1 - winshow(src, "credits", 1) - - HideCredits() - set hidden = 1 - winshow(src, "credits", 0) - - ShowPublicChannels() - set hidden = 1 - winshow(src, "pub_chans", 1) - - HidePublicChannels() - set hidden = 1 - winshow(src, "pub_chans", 0) - - ShowHelp(t as text|null) - set hidden = 1 - if(!t) t = "index" - var/HelpView/HV = new() - HV.Display(src, t) - del(HV) - winshow(src, "help", 1) - - HideHelp() - set hidden = 1 - winshow(src, "help", 0) - - SearchHelp(t as text|null) - set hidden = 1 - if(!t) t = winget(src, "help.search", "text") - else winset(src, "help.search", "text='[t]'") - var/HelpView/HV = new() - HV.Display(src, "search", t) - del(HV) - - ShowProfile() - set hidden = 1 - src << output(null, "profile.output") - if(src.picture) src << output("\...", "profile.output") - else - src << output("\...", "profile.output") - winset(src, "profile.key", "text=' [src.name]") - winset(src, "profile.age", "text=' [src.age]") - winset(src, "profile.gender", "text=' [src.gender]") - winset(src, "profile.location", "text=' [src.location]") - winset(src, "profile.description", "text=' [src.description]") - winset(src, "profile.interests", "text=' [src.interests]") - winset(src, "profile", "is-visible=true") - winset(src, "profile.im_button", "command='IM \"[src.name]\"';") - - HideProfile() - set hidden = 1 - winshow(src, "profile", 0) - - SelectColor(scope as text|null) - set hidden = 1 - if(!scope) return - CV.Display(scope) - - InsertColor(color as text|null, window as text|null) - set hidden = 1 - if(!color) return - if(!Chan) return - var/input - if(!window) - window = "[ckey(Home.name)]" - input = "default_input" - else - window = "cim_[ckey(window)]" - input = "input" - var/msg_value = winget(src, "[window].[input]", "text") - var/down = winget(src, "[window].[color]", "is-checked") - if(down == "false") - msg_value += "\[/#]" - var/index = text2num(copytext(color, 6)) - src.Colors[src.Colors[index]] = null - winset(src, "[window].[color]", "text=''") - else - for(var/i=1,i<=7,i++) - var/C = src.Colors[i] - if(src.Colors[C] == "selected") - msg_value += "\[/#]" - src.Colors[C] = null - winset(src, "[window].color[i]", "text=''") - winset(src, "[window].color[i]", "is-checked=false") - switch(color) - if("color1") - msg_value += "\[[src.Colors[1]]]" - src.Colors[src.Colors[1]] = "selected" - if("color2") - msg_value += "\[[src.Colors[2]]]" - src.Colors[src.Colors[2]] = "selected" - if("color3") - msg_value += "\[[src.Colors[3]]]" - src.Colors[src.Colors[3]] = "selected" - if("color4") - msg_value += "\[[src.Colors[4]]]" - src.Colors[src.Colors[4]] = "selected" - if("color5") - msg_value += "\[[src.Colors[5]]]" - src.Colors[src.Colors[5]] = "selected" - if("color6") - msg_value += "\[[src.Colors[6]]]" - src.Colors[src.Colors[6]] = "selected" - if("color7") - msg_value += "\[[src.Colors[7]]]" - src.Colors[src.Colors[7]] = "selected" - winset(src, "[window].[color]", "text='*'") - winset(src, "[window].[input]", "text='[TextMan.escapeQuotes(msg_value)]'") - winset(src, "[window].[input]", "focus=true") - - InsertTag(tag as text|null, window as text|null) - set hidden = 1 - if(!tag) return - if(!Chan) return - var/input - if(!window) - window = "[ckey(Home.name)]" - input = "default_input" - else - window = "cim_[ckey(window)]" - input = "input" - var/msg_value = winget(src, "[window].[input]", "text") - var/down = winget(src, "[window].[tag]", "is-checked") - switch(tag) - if("tag1") - var/open = src.Tags[1] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - if("tag2") - var/open = src.Tags[2] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - if("tag3") - var/open = src.Tags[3] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - if("tag4") - var/open = src.Tags[4] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - if("tag5") - var/open = src.Tags[5] - if(down == "false") - msg_value += src.Tags[open] - else - msg_value += open - winset(src, "[window].[input]", "text='[TextMan.escapeQuotes(msg_value)]'") - winset(src, "[window].[input]", "focus=true") - - InsertSmiley(smiley as text|null, window as text|null) - set hidden = 1 - if(!smiley) return - if(!Chan) return - if(!window) window = "[ckey(Home.name)].default_input" - else window = "cim_[ckey(window)].input" - var/msg_value = winget(src, "[window]", "text") - switch(smiley) - if("smiley1") - msg_value += src.Smileys[1] - if("smiley2") - msg_value += src.Smileys[2] - if("smiley3") - msg_value += src.Smileys[3] - if("smiley4") - msg_value += src.Smileys[4] - if("smiley5") - msg_value += src.Smileys[5] - if("smiley6") - msg_value += src.Smileys[6] - winset(src, "[window]", "text='[TextMan.escapeQuotes(msg_value)]'") - winset(src, "[window]", "focus=true") - - Join() - set hidden = 1 - if(afk) ReturnAFK() - ChanMan.Join(src, Home) - - Quit() - set hidden = 1 - ChanMan.Quit(src, Home) - - SayAlias(msg as text|null) - set name = ">" - Say(msg) + +mob + chatter + verb + + SwapPanes(nosave as num|null) + set hidden = 1 + if(!src.Chan) return + if(!src.showwho) return + src.swaped_panes ^= 1 + var/splitter = text2num(winget(src, "[ckey(Home.name)].child", "splitter")) + winset(src, "[ckey(Home.name)].child", "splitter=[100-splitter]") + if(src.swaped_panes) + winset(src, "[ckey(Home.name)].child", "left='[ckey(Home.name)].who'") + winset(src, "[ckey(Home.name)].child", "right='[ckey(Home.name)].chat'") + winset(src, "[ckey(Home.name)].topic_label", "pos='132,0'") + winset(src, "[ckey(Home.name)].online", "is-visible=false") + winset(src, "[ckey(Home.name)].online_left", "is-visible=true") + else + winset(src, "[ckey(Home.name)].child", "left='[ckey(Home.name)].chat'") + winset(src, "[ckey(Home.name)].child", "right='[ckey(Home.name)].who'") + winset(src, "[ckey(Home.name)].topic_label", "pos='0,0'") + winset(src, "[ckey(Home.name)].online", "is-visible=true") + winset(src, "[ckey(Home.name)].online_left", "is-visible=false") + if(!nosave) + winsize = winget(src, "default", "size") + ChatMan.Save(src) + + ToggleTopic(nosave as num|null) + set hidden = 1 + if(!src.Chan) return + if(src.showtopic) + winset(src, "[ckey(Home.name)].topic_label", "is-visible=false") + src.showtopic = FALSE + if(Host == src) winset(src, "host.topic_toggle", "is-checked=false;") + else winset(src, "menu.topic_toggle", "is-checked=false;") + if(!showwho && !nosave) + var/size = winget(src, "default.child", "size") + var/X = copytext(size, 1, findtext(size, "x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))+20 + winset(src, "default.child", "pos='0,-20';size='[X]x[Y]'") + else + winset(src, "[ckey(Home.name)].topic_label", "is-visible=true") + src.showtopic = TRUE + if(Host == src) winset(src, "host.topic_toggle", "is-checked=true;") + else winset(src, "menu.topic_toggle", "is-checked=true;") + if(!showwho && !nosave) + var/size = winget(src, "default.child", "size") + var/X = copytext(size, 1, findtext(size, "x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))-20 + winset(src, "default.child", "pos='0,0';size='[X]x[Y]'") + if(!nosave) + winsize = winget(src, "default", "size") + ChatMan.Save(src) + + ToggleWho(nosave as num|null) + set hidden = 1 + if(!src.Chan) return + var/pos = "right" + if(src.swaped_panes) pos = "left" + if(src.showwho) + winset(src, "[ckey(Home.name)].child", "[pos]=") + winset(src, "[ckey(Home.name)].online", "is-visible=false") + src.showwho = FALSE + if(Host == src) winset(src, "host.who_toggle", "is-checked=false;") + else winset(src, "menu.who_toggle", "is-checked=false;") + if(!showtopic) + var/size = winget(src, "default.child", "size") + var/X = copytext(size, 1, findtext(size, "x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))+20 + winset(src, "default.child", "pos='0,-20';size='[X]x[Y]'") + + else + winset(src, "[ckey(Home.name)].child", "[pos]='[ckey(Home.name)].who'") + winset(src, "[ckey(Home.name)].online", "is-visible=true") + src.showwho = TRUE + if(Host == src) winset(src, "host.who_toggle", "is-checked=true;") + else winset(src, "menu.who_toggle", "is-checked=true;") + if(!showtopic) + var/size = winget(src, "default.child", "size") + var/X = copytext(size, 1, findtext(size, "x")) + var/Y = text2num(copytext(size, findtext(size, "x")+1))-20 + winset(src, "default.child", "pos='0,0';size='[X]x[Y]'") + if(!nosave) + winsize = winget(src, "default", "size") + ChatMan.Save(src) + + ToggleQuickBar(nosave as num|null) + set hidden = 1 + if(!Chan) return + var/i + var/size = winget(src, "[ckey(Home.name)].child", "size") + var/seperator = findtext(size, "x") + var/X = copytext(size,1,seperator) + var/Y = text2num(copytext(size,seperator+1)) + var/window = ckey(Home.name) + if(src.quickbar) + Y += 16 + for(i=1, i<=5, i++) + winset(src, "[window].tag[i]","is-visible=false") + for(i=1, i<=6, i++) + winset(src, "[window].smiley[i]","is-visible=false") + for(i=1, i<=7, i++) + winset(src, "[window].color[i]","is-visible=false") + winset(src, "[window].toggle_quickbar", "text='+'") + quickbar = FALSE + if(Host == src) winset(src, "host.quickbar_toggle", "is-checked=false;") + else winset(src, "menu.quickbar_toggle", "is-checked=false;") + else + Y -= 16 + for(i=1, i<=5, i++) + winset(src, "[window].tag[i]","is-visible=true") + for(i=1, i<=6, i++) + winset(src, "[window].smiley[i]","is-visible=true") + for(i=1, i<=7, i++) + winset(src, "[window].color[i]","is-visible=true") + winset(src, "[window].toggle_quickbar", "text='-'") + quickbar = TRUE + if(Host == src) winset(src, "host.quickbar_toggle", "is-checked=true;") + else winset(src, "menu.quickbar_toggle", "is-checked=true;") + winset(src, null, "[window].child.size=[X]x[Y];\ + [window].default_input.focus=true;") + if(!nosave) + winsize = winget(src, "default", "size") + ChatMan.Save(src) + + + ToggleCIMBar(window as text|null) + set hidden = 1 + if(!window) return + window = "cim_[ckey(window)]" + var/i + + var/outsize = winget(src, "[window].output", "size") + var/outseperator = findtext(outsize, "x") + var/outX = copytext(outsize,1,outseperator) + var/outY = text2num(copytext(outsize,outseperator+1)) + + var/profpos = winget(src, "[window].profile", "pos") + var/profseperator = findtext(profpos, ",") + var/profX = copytext(profpos,1,profseperator) + var/profY = text2num(copytext(profpos,profseperator+1)) + + var/showpos = winget(src, "[window].show", "pos") + var/showseperator = findtext(showpos, ",") + var/showX = copytext(showpos,1,showseperator) + var/showY = text2num(copytext(showpos,showseperator+1)) + + var/sharepos = winget(src, "[window].share", "pos") + var/shareseperator = findtext(sharepos, ",") + var/shareX = copytext(sharepos,1,shareseperator) + var/shareY = text2num(copytext(sharepos,shareseperator+1)) + + var/invpos = winget(src, "[window].invite", "pos") + var/invseperator = findtext(invpos, ",") + var/invX = copytext(invpos,1,invseperator) + var/invY = text2num(copytext(invpos,invseperator+1)) + + var/joinpos = winget(src, "[window].join", "pos") + var/joinseperator = findtext(joinpos, ",") + var/joinX = copytext(joinpos,1,joinseperator) + var/joinY = text2num(copytext(joinpos,joinseperator+1)) + + if(winget(src, "[window].tag1", "is-visible") == "true") + outY += 20 + profY += 20 + showY += 20 + shareY += 20 + invY += 20 + joinY += 20 + for(i=1, i<=3, i++) + winset(src, "[window].tag[i]","is-visible=false") + for(i=1, i<=6, i++) + winset(src, "[window].smiley[i]","is-visible=false") + for(i=1, i<=7, i++) + winset(src, "[window].color[i]","is-visible=false") + winset(src, "[window].toggle_quickbar", "text='+'") + else + outY -= 20 + profY -= 20 + showY -= 20 + shareY -= 20 + invY -= 20 + joinY -= 20 + for(i=1, i<=3, i++) + winset(src, "[window].tag[i]","is-visible=true") + for(i=1, i<=6, i++) + winset(src, "[window].smiley[i]","is-visible=true") + for(i=1, i<=7, i++) + winset(src, "[window].color[i]","is-visible=true") + winset(src, "[window].toggle_quickbar", "text='-'") + winset(src, "[window].profile", "pos=[profX],[profY]") + winset(src, "[window].show", "pos=[showX],[showY]") + winset(src, "[window].share", "pos=[shareX],[shareY]") + winset(src, "[window].invite", "pos=[invX],[invY]") + winset(src, "[window].join", "pos=[joinX],[joinY]") + winset(src, "[window].output", "size=[outX]x[outY]") + winset(src, "[window].input", "focus=true") + + NewInstantMessage() + set hidden = 1 + var/Messenger/im = new(src) + im.Display(src) + + ShowGameWindow() + set hidden = 1 + winshow(src, "game", 1) + + HideGameWindow() + set hidden = 1 + winshow(src, "game", 0) + + ShowChattersMail() + set hidden = 1 + winshow(src, "cmail", 1) + + HideChattersMail() + set hidden = 1 + winshow(src, "cmail", 0) + + ShowAbout() + set hidden = 1 + winshow(src, "about", 1) + + HideAbout() + set hidden = 1 + winshow(src, "about", 0) + + ShowCredits() + set hidden = 1 + winshow(src, "credits", 1) + + HideCredits() + set hidden = 1 + winshow(src, "credits", 0) + + ShowPublicChannels() + set hidden = 1 + NetMan.UpdatePubChans(src) + winshow(src, "pub_chans", 1) + + HidePublicChannels() + set hidden = 1 + winshow(src, "pub_chans", 0) + + ShowHelp(t as text|null) + set hidden = 1 + if(!t) t = "index" + var/HelpView/HV = new() + HV.Display(src, t) + del(HV) + winshow(src, "help", 1) + + HideHelp() + set hidden = 1 + winshow(src, "help", 0) + + SearchHelp(t as text|null) + set hidden = 1 + if(!t) t = winget(src, "help.search", "text") + else winset(src, "help.search", "text='[t]'") + var/HelpView/HV = new() + HV.Display(src, "search", t) + del(HV) + + ShowProfile() + set hidden = 1 + src << output(null, "profile.output") + if(src.picture) src << output("\...", "profile.output") + else + src << output("\...", "profile.output") + winset(src, "profile.key", "text=' [src.name]") + winset(src, "profile.age", "text=' [src.age]") + winset(src, "profile.gender", "text=' [src.gender]") + winset(src, "profile.location", "text=' [src.location]") + winset(src, "profile.description", "text=' [src.description]") + winset(src, "profile.interests", "text=' [src.interests]") + winset(src, "profile", "is-visible=true") + winset(src, "profile.im_button", "command='IM \"[src.name]\"';") + + HideProfile() + set hidden = 1 + winshow(src, "profile", 0) + + SelectColor(scope as text|null) + set hidden = 1 + if(!scope) return + CV.Display(scope) + + InsertColor(color as text|null, window as text|null) + set hidden = 1 + if(!color) return + if(!Chan) return + var/input + if(!window) + window = "[ckey(Home.name)]" + input = "default_input" + else + window = "cim_[ckey(window)]" + input = "input" + var/msg_value = winget(src, "[window].[input]", "text") + var/down = winget(src, "[window].[color]", "is-checked") + if(down == "false") + msg_value += "\[/#]" + var/index = text2num(copytext(color, 6)) + src.Colors[src.Colors[index]] = null + winset(src, "[window].[color]", "text=''") + else + for(var/i=1,i<=7,i++) + var/C = src.Colors[i] + if(src.Colors[C] == "selected") + msg_value += "\[/#]" + src.Colors[C] = null + winset(src, "[window].color[i]", "text=''") + winset(src, "[window].color[i]", "is-checked=false") + switch(color) + if("color1") + msg_value += "\[[src.Colors[1]]]" + src.Colors[src.Colors[1]] = "selected" + if("color2") + msg_value += "\[[src.Colors[2]]]" + src.Colors[src.Colors[2]] = "selected" + if("color3") + msg_value += "\[[src.Colors[3]]]" + src.Colors[src.Colors[3]] = "selected" + if("color4") + msg_value += "\[[src.Colors[4]]]" + src.Colors[src.Colors[4]] = "selected" + if("color5") + msg_value += "\[[src.Colors[5]]]" + src.Colors[src.Colors[5]] = "selected" + if("color6") + msg_value += "\[[src.Colors[6]]]" + src.Colors[src.Colors[6]] = "selected" + if("color7") + msg_value += "\[[src.Colors[7]]]" + src.Colors[src.Colors[7]] = "selected" + winset(src, "[window].[color]", "text='*'") + winset(src, "[window].[input]", "text='[TextMan.escapeQuotes(msg_value)]'") + winset(src, "[window].[input]", "focus=true") + + InsertTag(tag as text|null, window as text|null) + set hidden = 1 + if(!tag) return + if(!Chan) return + var/input + if(!window) + window = "[ckey(Home.name)]" + input = "default_input" + else + window = "cim_[ckey(window)]" + input = "input" + var/msg_value = winget(src, "[window].[input]", "text") + var/down = winget(src, "[window].[tag]", "is-checked") + switch(tag) + if("tag1") + var/open = src.Tags[1] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + if("tag2") + var/open = src.Tags[2] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + if("tag3") + var/open = src.Tags[3] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + if("tag4") + var/open = src.Tags[4] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + if("tag5") + var/open = src.Tags[5] + if(down == "false") + msg_value += src.Tags[open] + else + msg_value += open + winset(src, "[window].[input]", "text='[TextMan.escapeQuotes(msg_value)]'") + winset(src, "[window].[input]", "focus=true") + + InsertSmiley(smiley as text|null, window as text|null) + set hidden = 1 + if(!smiley) return + if(!Chan) return + if(!window) window = "[ckey(Home.name)].default_input" + else window = "cim_[ckey(window)].input" + var/msg_value = winget(src, "[window]", "text") + switch(smiley) + if("smiley1") + msg_value += src.Smileys[1] + if("smiley2") + msg_value += src.Smileys[2] + if("smiley3") + msg_value += src.Smileys[3] + if("smiley4") + msg_value += src.Smileys[4] + if("smiley5") + msg_value += src.Smileys[5] + if("smiley6") + msg_value += src.Smileys[6] + winset(src, "[window]", "text='[TextMan.escapeQuotes(msg_value)]'") + winset(src, "[window]", "focus=true") + + Join() + set hidden = 1 + if(afk) ReturnAFK() + ChanMan.Join(src, Home) + + Quit() + set hidden = 1 + ChanMan.Quit(src, Home) + + SayAlias(msg as text|null) + set name = ">" + Say(msg) diff --git a/code/world.dm b/code/world.dm index 1058823..9d31963 100644 --- a/code/world.dm +++ b/code/world.dm @@ -1,46 +1,51 @@ - -world - version = 0 - name = "Chatters" - hub = "Xooxer.Chatters" - hub_password = "rbl9FQ0hzWtOEKtg" // my eyes only 0_0 - - view = "13x11" - - cache_lifespan = 1 - - mob = /mob/Temp // default temporary mob - turf = /turf/void // default temporary turf - visibility = 1 // Set to 0 in LoadServerCfg if we're not public, leave otherwise. - - New() - var/rsc_check = VerifyResources() - if(!rsc_check) - spawn(10) - if(Host && Host.client) - Host << output("Chatters.rsc is missing, corrupt or out of date!\nPlease check your Options & Messages and correct the error.\nShutting down...", "main_menu_output.output") - del(src) - else if(rsc_check == "unpakit") // Unpack the hosting package - var/zipfile/Z = new("./Chatters.zip") // Dantom.zipfile ftw! - for(var/z in Z.Flist()) Z.Export("./", z) // export host files here - Reboot() // Restart server to ensure proper boot environment - ..() - Console = new() // spawn the Console <-- This starts everything else - swapmaps_mode = SWAPMAPS_SAV // set SwapMaps to use savfiles - - Del() - del(Console) // last ditch effort to save before the world dies - ..() - - - Topic(Text,Addr) - ..() - Text+="&addr=[Addr]" - Console.Topic(Text) - - - OpenPort(Port) - if(isnull(Port)) - return - ..() - + +world + version = 0 + name = "Chatters" + hub = "Xooxer.Chatters" + hub_password = "rbl9FQ0hzWtOEKtg" // my eyes only 0_0 + + view = "13x11" + + cache_lifespan = 1 + + mob = /mob/Temp // default temporary mob + turf = /turf/void // default temporary turf + visibility = 1 // Set to 0 in LoadServerCfg if we're not public, leave otherwise. + + New() + var/rsc_check = VerifyResources() + if(!rsc_check) + spawn(10) + if(Host && Host.client) + Host << output("Chatters.rsc is missing, corrupt or out of date!\nPlease check your Options & Messages and correct the error.\nShutting down...", "main_menu_output.output") + del(src) + else if(rsc_check == "unpakit") // Unpack the hosting package + var/zipfile/Z = new("./Chatters.zip") // Dantom.zipfile ftw! + for(var/z in Z.Flist()) Z.Export("./", z) // export host files here + Reboot() // Restart server to ensure proper boot environment + ..() + Console = new() // spawn the Console <-- This starts everything else + swapmaps_mode = SWAPMAPS_SAV // set SwapMaps to use savfiles + + Del() + Export("[NetMan.addr]:[NetMan.port]?dest=chanman&action=delserver") + del(Console) // last ditch effort to save before the world dies + ..() + + + Topic(Text,Addr) + ..() + Text+="&addr=[Addr]" + Console.Topic(Text) + + + OpenPort(Port) + if(isnull(Port)) + NetMan.Disconnect() + return + Port = NetMan.PreConnect(Port) + var/oldport = port + ..() + NetMan.PostConnect(Port, oldport) + From 888421271326b5f4efe7c5b9a76a099b3e7041e2 Mon Sep 17 00:00:00 2001 From: HiroTDK Date: Sat, 14 Jul 2012 09:46:11 -0300 Subject: [PATCH 14/15] Update master --- code/models/chatter/commands.dm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index a7ffeaf..68022d9 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -606,12 +606,19 @@ Valid Commands: login(telnet_key as text|null) set hidden = 1 if(!telnet_key || !telnet) return - for(var/mob/chatter/C in Home.chatters) if((C.key && C.key==telnet_key) || C.name==telnet_key) return + for(var/mob/chatter/C in Home.chatters) + if((C.key && C.key==telnet_key) || C.name==telnet_key) + src << "Error: That key is already logged in!" + return var/savefile/S = new("./data/saves/tel.net") - if(!S || !length(S)) return + if(!S || !length(S)) + src << "Error: There is no password saved for that key!" + return var/list/L = new S["telnet"] >> L - if(!L || !L.len) return + if(!L || !L.len) + src << "Error: There is no password saved for that key!" + return var/key_hash = md5(telnet_key) if(key_hash in L) var/telnet_pass = input("Please enter your telnet password:", "Telnet Key Login") as password|null @@ -619,9 +626,11 @@ Valid Commands: del(L) return if(L[key_hash] != md5(telnet_pass)) + src << "Error: Incorrect password!" del(L) return del(L) name = telnet_key fade_name = name Home.UpdateWho() + else src << "Error: There is no password saved for that key!" From a843e95df3c721e41f8580a39a44a51704cc3530 Mon Sep 17 00:00:00 2001 From: HiroTDK Date: Sat, 14 Jul 2012 09:54:51 -0300 Subject: [PATCH 15/15] Minor edit. --- code/models/chatter/commands.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/models/chatter/commands.dm b/code/models/chatter/commands.dm index 68022d9..adb0bb5 100644 --- a/code/models/chatter/commands.dm +++ b/code/models/chatter/commands.dm @@ -630,6 +630,7 @@ Valid Commands: del(L) return del(L) + src << "You have successfully logged in as telnet_key!" name = telnet_key fade_name = name Home.UpdateWho()