📄 main.cpp
字号:
/************************************************************************************
Copyright (c) 2000 Aaron O'Neil
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1) Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2) 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.
3) Redistributions in binary form must reproduce the above copyright notice on
program startup. Additional credits for program modification are acceptable
but original copyright and credits must be visible at startup.
4) You may charge a reasonable copying fee for any distribution of Mud Master.
You may charge any fee you choose for support of Mud Master. You may not
charge a fee for Mud Master itself.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
**************************************************************************************/
#include "StdAfx.h"
#include "Extern.h"
#include "Notifications.h"
#include "Keyboard.h"
#include "MudWindow.h"
#include "TextInput.h"
#include "InputHistory.h"
#include "ScrollBack.h"
#include "Commands.h"
#include "AliasMap.h"
#include "Actions.h"
#include "TabList.h"
#include "Macros.h"
#include "UserLists.h"
#include "Procedures.h"
#include "Modem.h"
#include "LogFile.h"
#include "Events.h"
#include "StatusBar.h"
#include "MudArray.h"
#include "Gags.h"
#include "Highlights.h"
#include "Chat.h"
#include "Undo.h"
#include "Dll.h"
#include "Sound.h"
#include "Msp.h"
#include "Substitute.h"
#include "DebugStack.h"
#include "VersionThread.h"
#include "LogLine.h"
#include "ChangesThread.h"
CAliasMap _aliases;
CActions _actions;
CTabList _tabList;
CMacros _macros;
CUserLists _lists;
CEvents _events;
CMudArray _arrays;
CGags _gags;
CHighlights _highlights;
CSubstitutes _subs;
CChat _chat;
CDll _dlls;
CStatusBar _statusBar;
CKeyboard _keyboard;
CUndo _undo;
CSound _sound;
CMsp _msp;
CDebugStack _debugStack;
CTextLine *_ptlLastText = NULL;
BOOL _bBootLog = FALSE;
CHANGESTHREADINFO _cti;
//////////////////////////////////
// System Variables
//
CString _strListItem;
int _nLoopCount;
//
//////////////////////////////////
// Number of bytes to read each time the in buffers are polled
// for data waiting.
#define INBUF_SIZE 5000
// Profile shows that a huge amount of time is spent in CheckForChatConnections().
// That function eats all the time up calling select and I don't see a way
// the code there can be changed or improved. The value below is how often
// chat connections are checked in the main loop. It's the number of times
// through the loop before connections are checked.
#define CHATCONNECT_INTERVAL 200
// Same deal as above. This one is how often it checks for text on the chat
// sockets.
#define CHATCHECK_INTERVAL 50
// Same as above. This is how often it checks the windows message queue.
#define WINMESSAGE_INTERVAL 50
// How often the clock is checked for an elapsed second.
#define TIMER_INTERVAL 50
// These are the variables %0-%9 that get used in actions
// and aliases.
CString _strGlobalVars[10];
CStringMap _mapVars;
CScreen _screen;
CMudWindow _terminal;
CTextInput _tiUserInput;
CInputHistory _history;
CScrollBack _scrollBack;
CONFIGURATION _config;
TERMCOLORS _colors;
// TRUE if using a modem instead of winsock.
BOOL _bUsingModem = FALSE;
CModem _modem;
SOCKET _hActiveSocket = INVALID_SOCKET;
CString _strActiveSession;
BOOL _bConnected = FALSE;
// For incoming chat requests.
SOCKET _hListenSocket = INVALID_SOCKET;
BOOL _bChatListenEnabled = FALSE;
CString _strLastLine;
// See Extern.H for help on this var.
BOOL _bReadingFile = FALSE;
// True when logging the text to a file.
BOOL _bLogOpen = FALSE;
CLogFile _logFile;
// Input buffer for use when speedwalking. Made it global so I
// won't fragment memory by allocating and dealocation chuncks
// of memory. Also using it in the screen editor to process
// stuff at the same time as editing.
char *_pWalkBuf;
// Input buffer for incoming chats. Global for the same reason
// as the walkbuf.
char *_pChatBuf;
// Port to use for the listen socket.
int _nListenPort = 4050;
// This is set to FALSE when the program first starts. When a
// midi file is played the flag is set to TRUE. The midi routine
// then knows that it has to close the previous file before it
// tries to play a new one.
BOOL _bMidiOpen = FALSE;
CString _strIniName = ".\\Mud Master.ini";
// Place for user defined DLL routines to return data.
char *_pszDLLResult;
///////////////////////////////////////////////////////////////
// Notification lists.
//
CNotifyConnect _notifyConnect;
CNotifyDisconnect _notifyDisconnect;
CNotifyChatConnect _notifyChatConnect;
CNotifyChatDisconnect _notifyChatDisconnect;
CNotifyInput _notifyInput;
CNotifyRaw _notifyRaw;
//
///////////////////////////////////////////////////////////////
// This list of commands is indexed with a hash table. Because of
// this it is VERY important to put the items in the list in
// alphabetical order. It only has to be sorted by the first letter.
// All the 'A's together, etc...
COMMANDLIST _commandList[] =
{
{"action",Action,FALSE,"action"},
{"alias",Alias,FALSE,"alias"},
{"altgr",AltGr,FALSE,"altgr"},
{"array",Array,FALSE,"array"},
{"assign",Assign,FALSE,"assign"},
{"autoaccept",AutoAccept,FALSE,"autoaccp"},
{"barback",BarBack,FALSE,"barback"},
{"barfore",BarFore,FALSE,"barfore"},
{"baritem",BarItem,FALSE,"baritem"},
{"baritemback",BarItemBack,FALSE,"baritemb"},
{"baritemfore",BarItemFore,FALSE,"baritemf"},
{"baritemshift",BarItemShift,FALSE,"baritems"},
{"barseparator",BarSeparator,FALSE,"barsep"},
{"bell",Bell,FALSE,"bell"},
{"cachesize",CacheSize,FALSE,"cachesz"},
{"call",Call,FALSE,"call"},
{"calldll",CallDLL,FALSE,"calldll"},
{"cg",GroupChat,FALSE,"chatgrp"},
{"char",Char,TRUE,"char"},
{"chat",Chat,FALSE,"chat"},
{"chatall",ChatAll,FALSE,"chatall"},
{"chatback",ChatBack,FALSE,"chatback"},
{"chatcommands",ChatCommands,FALSE,"chatcom"},
{"chatfore",ChatFore,FALSE,"chatfore"},
{"chatgroup",GroupChat,FALSE,"chatgrp"},
{"chatgroupremove",ChatGroupRemove,FALSE,"chatgrem"},
{"chatgroupset",ChatGroupSet,FALSE,"chatgset"},
{"chatignore",ChatIgnore,FALSE,"chatign"},
{"chatignoreall",ChatIgnoreAll,FALSE,"chatigna"},
{"chatname",ChatName,FALSE,"chatname"},
{"chatprivate",ChatPrivate,FALSE,"chatpriv"},
{"chatserve",ChatServe,FALSE,"chatsrv"},
{"chatsnoop",ChatSnoop,FALSE,"chatsnp"},
{"chattransfers",ChatTransfers,FALSE,"chattran"},
{"chatversions",ChatVersions,FALSE,"chatver"},
{"clearlist",ClearList,FALSE,"clearlst"},
{"cr",CR,FALSE,"cr"},
{"debug",DebugMessages,FALSE,"debug"},
{"debugdepth",DebugDepth,FALSE,"debugdpt"},
{"default",Default,FALSE,"default"},
{"dir",Dir,FALSE,"dir"},
{"disableaction",DisableAction,FALSE,"disact"},
{"disablealias",DisableAlias,FALSE,"disalias"},
{"disablebaritem",DisableBarItem,FALSE,"disbar"},
{"disableevent",DisableEvent,FALSE,"disabevt"},
{"disablegag",DisableGag,FALSE,"disgag"},
{"disablegroup",DisableGroup,FALSE,"disgrp"},
{"disablehighlight",DisableHighlight,FALSE,"dishighl"},
{"disablemacro",DisableMacro,FALSE,"dismacro"},
{"disablesubstitute",DisableSub,FALSE,"dissub"},
{"disconnect",Disconnect,FALSE,"discon"},
{"dll",Dll,FALSE,"dll"},
{"dnd",Dnd,FALSE,"dnd"},
{"doevents",DoEvents,FALSE,"doevents"},
{"downloadpath",DownloadPath,FALSE,"downpath"},
{"echo",Echo,FALSE,"echo"},
{"echoactions",EchoActions,FALSE,"echoact"},
{"editaction",EditAction,FALSE,"eaction"},
{"editalias",EditAlias,FALSE,"ealias"},
{"editback",EditBack,FALSE,"editback"},
{"editbaritem",EditBarItem,FALSE,"ebar"},
{"editevent",EditEvent,FALSE,"editevt"},
{"editfore",EditFore,FALSE,"editfore"},
{"editgag",EditGag,FALSE,"editgag"},
{"edithighlight",EditHighlight,FALSE,"edhighl"},
{"editmacro",EditMacro,FALSE,"emacro"},
{"editsubstitute",EditSub,FALSE,"editsub"},
{"editvariable",EditVariable,FALSE,"editvar"},
{"emote",Emote,FALSE,"emote"},
{"emoteall",EmoteAll,FALSE,"emoteall"},
{"eg",GroupEmote,FALSE,"emotegrp"},
{"emotegroup",GroupEmote,FALSE,"emotegrp"},
{"empty",Empty,FALSE,"empty"},
{"enableaction",EnableAction,FALSE,"enaction"},
{"enablealias",EnableAlias,FALSE,"enalias"},
{"enablebaritem",EnableBarItem,FALSE,"enbar"},
{"enableevent",EnableEvent,FALSE,"enabevt"},
{"enablegag",EnableGag,FALSE,"engag"},
{"enablegroup",EnableGroup,FALSE,"enablegroup"},
{"enablehighlight",EnableHighlight,FALSE,"enhighl"},
{"enablemacro",EnableMacro,FALSE,"enmacro"},
{"enablesubstitute",EnableSub,FALSE,"ensub"},
{"event",Event,FALSE,"event"},
{"feditaction",FullEditAction,FALSE,"feaction"},
{"feditalias",FullEditAlias,FALSE,"fealias"},
{"feditbaritem",FullEditBarItem,FALSE,"febar"},
{"feditevent",FullEditEvent,FALSE,"feditevt"},
{"feditgag",FullEditGag,FALSE,"feditgag"},
{"fedithighlight",FullEditHighlight,FALSE,"fedhighl"},
{"feditmacro",FullEditMacro,FALSE,"femacro"},
{"feditsubstitute,",FullEditSub,FALSE,"fesub"},
{"feditvariable",FullEditVariable,FALSE,"fevar"},
{"filecancel",FileCancel,FALSE,"filecan"},
{"filedelete",FileDelete,FALSE,"filedel"},
{"filestatus",FileStatus,FALSE,"filestat"},
{"fireevent",FireEvent,FALSE,"fireevt"},
{"freelibrary",FreeLibrary,FALSE,"freelib"},
{"gag",Gag,FALSE,"gag"},
{"groupactions",GroupActions,FALSE,"grpact"},
{"groupaliases",GroupAliases,FALSE,"grpalias"},
{"groupbaritems",GroupBarItems,FALSE,"grpbar"},
{"groupevents",GroupEvents,FALSE,"grpevent"},
{"grouplists",GroupLists,FALSE,"grplist"},
{"groupmacros",GroupMacros,FALSE,"grpmacro"},
{"groupsubstitutes",GroupSubs,FALSE,"grpsub"},
{"grouptablist",GroupTablist,FALSE,"grptab"},
{"groupvariables",GroupVariables,FALSE,"grpvar"},
{"help",Help,FALSE,NULL},
{"highlight",Highlight,FALSE,"highl"},
{"if",If,FALSE,"if"},
{"ignore",Ignore,FALSE,"ignore"},
{"ignorealiases",IgnoreAliases,FALSE,"igalias"},
{"information",Information,FALSE,"info"},
{"itemadd",ItemAdd,FALSE,"itemadd"},
{"itemdelete",ItemDelete,FALSE,"itemdel"},
{"killall",KillAll,FALSE,"killall"},
{"killgroup",KillGroup,FALSE,"killgrp"},
{"listadd",ListAdd,FALSE,"listadd"},
{"listdelete",ListDelete,FALSE,"listdel"},
{"listitems",ListItems,FALSE,"listitem"},
{"lists",Lists,FALSE,"lists"},
{"loadlibrary",MMLoadLibrary,FALSE,"loadlib"},
{"logclose",LogClose,FALSE,"logclose"},
{"logopen",LogOpen,FALSE,"logopen"},
{"logopenappend",LogOpenAppend,FALSE,"logapp"},
{"logstatus",LogStatus,FALSE,"logstat"},
{"loop",Loop,FALSE,"loop"},
{"macro",Macro,FALSE,"macro"},
{"math",Math,FALSE,"math"},
{"message",Message,FALSE,"message"},
{"mode",Mode,FALSE,"mode"},
{"msp",Msp,FALSE,"msp"},
{"multipleactions",MultipleActions,FALSE,"multiact"},
{"nodefault",NoDefault,FALSE,"nodef"},
{"notifydll",NotifyDll,FALSE,"notdll"},
{"openport",OpenPort,FALSE,"openport"},
{"pace",Pace,FALSE,"pace"},
{"pause",Pause,FALSE,"pause"},
{"peekconnections",PeekConnections,FALSE,"peekcon"},
{"ping",Ping,FALSE,"ping"},
{"playmidi",PlayMidi,FALSE,"playmidi"},
{"playwave",PlayWav,FALSE,"playwav"},
{"presubstitute",Presubstitute,FALSE,"presub"},
{"promptoverwrite",PromptOverwrite,FALSE,"prompto"},
{"read",Read,FALSE,"read"},
{"requestconnects",RequestConnects,FALSE,"reqcon"},
{"resetevent",ResetEvent,FALSE,"resetevt"},
{"savescrollback",SaveScrollback,FALSE,"savescrl"},
{"scriptpath",ScriptPath,FALSE,"scrpath"},
{"sendaction",SendAction,FALSE,"sendact"},
{"sendalias",SendAlias,FALSE,"sendal"},
{"sendarray",SendArray,FALSE,"sendarr"},
{"sendbaritem",SendBarItem,FALSE,"sendbari"},
{"sendevent",SendEvent,FALSE,"sendevt"},
{"sendfile",SendFile,FALSE,"sendfile"},
{"sendgag",SendGag,FALSE,"sendgag"},
{"sendgroup",SendGroup,FALSE,"sendgrp"},
{"sendhighlight",SendHighlight,FALSE,"sendhigh"},
{"sendlist",SendList,FALSE,"sendlist"},
{"sendmacro",SendMacro,FALSE,"sendmac"},
{"sendsubstitute",SendSub,FALSE,"sendsub"},
{"sendvariable",SendVariable,FALSE,"sendvar"},
{"session",Session,FALSE,"session"},
{"seteventtime",SetEventTime,FALSE,"sevtime"},
{"setip",SetIP,FALSE,"setip"},
{"showme",ShowMe,FALSE,"showme"},
{"showmismatcherrors",ShowMismatchErrors,FALSE,"showmis"},
{"snoop",Snoop,FALSE,"snoop"},
{"soundpath",SoundPath,FALSE,"sndpath"},
{"speedwalk",SpeedWalk,FALSE,"speedw"},
{"statusbar",StatusBar,FALSE,"statbar"},
{"substitute",Substitute,FALSE,"sub"},
{"tabadd",TabAdd,FALSE,"tabadd"},
{"tabdelete",TabDelete,FALSE,"tabdel"},
{"tablist",TabList,FALSE,"tablist"},
{"textin",TextIn,FALSE,"textin"},
{"unaction",UnAction,FALSE,"unaction"},
{"unalias",UnAlias,FALSE,"unalias"},
{"unarray",UnArray,FALSE,"unarray"},
{"unbaritem",UnBarItem,FALSE,"unbar"},
{"unchat",UnChat,FALSE,"unchat"},
{"undo",UnDo,FALSE,"undo"},
{"unevent",UnEvent,FALSE,"unevent"},
{"ungag",UnGag,FALSE,"ungag"},
{"unhighlight",UnHighlight,FALSE,"unhighl"},
{"unmacro",UnMacro,FALSE,"unmacro"},
{"unsubstitute",UnSubstitute,FALSE,"unsub"},
{"unvariable",UnVariable,FALSE,"unvar"},
{"updatebaritem",UpdateBarItem,FALSE,"upbar"},
{"updatestatusbar",UpdateStatusBar,FALSE,"upstatus"},
{"uploadpath",UploadPath,FALSE,"upldpath"},
{"variable",Variable,FALSE,"var"},
{"version",Version,FALSE,"version"},
{"volumedefault",VolumeDefault,FALSE,"voldef"},
{"volumemax",VolumeMax,FALSE,"volmax"},
{"volumebits",VolumeBits,FALSE,"volbits"},
{"while",While,FALSE,"while"},
{"winmessages",WinMessages,FALSE,"winmes"},
{"write",Write,FALSE,"write"},
{"writegroup",WriteGroup,FALSE,"writegrp"},
{"zap",Zap,FALSE,"zap"},
{"",NULL,FALSE}
};
CHashTable _htCommands;
// Creates the hash table for the command list.
void HashCommands();
//
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// Terminal Printing Functions
//
// Prints a message from the program to the terminal screen.
// Adds the # and sets focus back to the input control.
// bNoAction TRUE to make the printed text non-actionable.
void PrintMessage(const char *pszMessage, BOOL bCR, BOOL bNoAction);
// Gets the latest socket error and prints a message.
void PrintError();
// Calling this function saves the text color, changes it to
// F_LIGHTGREY and disables actions, and hides the cursor.
void CommandPrintOn();
// Puts the color back to what it was, restores the action
// state, shows the cursor and sets focus to the input control.
void CommandPrintOff();
//
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// Speed Walking Functions
//
BOOL IsWalkable(const char *pszText);
void DoSpeedWalk(const char *pszText);
//
///////////////////////////////////////////////////////////////
// Returns TRUE if pszLookFor is a partial match for pszText.
// The string is a partail matching if pszLookFor is the left
// leftmost portion of pszText.
BOOL IsPartial(const char *pszLookFor, const char *pszText);
void HandleInput(CString &strLine);
void ProcessLine(CString &strLine);
// Pass in strText to look for the first black statement in
// the string. A block statement will be enclosed by the
// blockstart and blockend chars from _config. If those are
// no present, spaces are used to determine the block. strText
// is modified to point the the next character after the block
// statement. Or an Empty string if nothing is left.
void FindStatement(CString &strText, CString &strResult);
// This function is used only for findind the @PreTrans procedure
// and replacing the vars in it. Pretranlation is used on commands
// that you want a variable to be replaced before it is actually
// executed. For example: /mac f1 $Target, when you press F1
// $Target gets translated. You may want to replace the variable
// when the macro is created, and just store the value in the macro.
// /mac f1 @PreTrans($Target), would replace the variable before
// the macro is defined.
void PretranslateString(CString &strLine);
// Pass in strLine and the function will find any variables in
// the text and replace them with their values. If bQuoteStrings
// is TRUE then all the string variables that are replaced will be
// placed within quotation marks.
void ReplaceVariables(CString &strLine, BOOL bQuoteStrings);
// Pass in a variable name in strName. If it is a system variable
// the function returns TRUE and fills strResult with the value
// of that variable.
BOOL SystemVar(CString &strName, CString &strResult);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -