/**
* This file was modified by

* Check the programming section for updates and further scripts
* Last Update: 11:25 05.11.2011
*/
//------------------------------------------------------------------------------
// Delays
//------------------------------------------------------------------------------
var GameMinLength = 120; // Time in seconds, minimum game length, 180 seconds default (1 game/3 minutes).
var UnableToConnectRetry = 5; // Time in minutes to retry connecting on connection fail (real value is +/- 1 min).
var RealmDownRetry = 15; // Time in minutes to retry connecting on a realm down (default is 300 minutes).
var DisconnectedRetry = 5; // Time in minutes to retry on a disconnection (usually ip ban related).
var CdKeyInUseRetry = 5; // Time in minutes to retry on a cdkey in use error message (set to 0 to stop).
var ConnectingToBnetTimeout = 20; // Time in seconds to wait for a login to Time out and click cancel and retry.
var CharacterScreenTimeout = 10; // Time in seconds to wait for character screen to appear.
var PleaseWaitTimeout = 10; // Time in seconds to wait for a please wait popup.
var CreateGameThreshold = 20; // Time in seconds to wait between making games.
var CreateGameThresholdRandom = 5; // Time in seconds to randomly add +/- to the game create time.
var CreateGameTimeout = 15; // Time in seconds to register a failed to create game.
var WaitInLineTimeout = 60; // Time in seconds to wait in lines for a create game (60 second default).
var CharacterSelectDelay = 1000; // Time in milliseconds to wait before selecting a character on the char screen.
var GameDoesNotExistDelayMin = 10; // How long to wait when a Game Does Not Exist occurs - minimum - default 10 minutes.
var GameDoesNotExistDelayMax = 15; // How long to wait when a Game Does Not Exist occurs - maximum - default 15 minutes.
var GameDoesNotExistTimeout = 30; // How long to wait for the dialog to disappear (default 30 seconds, don't change this).
// Control
var LoginDelay = 5000; // Time in milliseconds to wait before submitting login information.
var ClickDelay = 2000; // Wait X milliseconds before next action after a click event.
var TextDelay = 2500; // Wait X milliseconds before next action after inserting text into a textbox.
var ClickDelayRandom = 500; // Random amount of Time in milliseconds to add to a click.
var TextDelayRandom = 500; // Random amount of Time in milliseconds to add to a text set.
// Channel
var WaitBeforeEnterChatMin = 1000; // Min time in milliseconds to wait before entering chat.
var WaitBeforeEnterChatMax = 2000; // Max time in milliseconds to wait before entering chat.
var WaitInChatBeforeActionsMin = 2000; // Min time in milliseconds to wait before joining channel.
var WaitInChatBeforeActionsMax = 3000; // Max time in milliseconds to wait before joining channel.
var GameAnnouncementDelay = 5000; // Wait X milliseconds before posting the announcement message (don't set this too low!).
var GameAnnouncementDelayRandom = 500; // Random amount of time to add to a to the announcement delay.
var UseFileBackupTimeMax = 30; // Time in minutes that may pass since last file update - The backup File is updated at the beginning of every single game and is read everytime the name of your previous game is undefined (e.g. at restarts); Set to 0 to deactivate file backup.
//------------------------------------------------------------------------------
// Game settings
//------------------------------------------------------------------------------
var PlayersPerGame = 8; // Maximum number of players to be set when creating a game.
var CharacterDifference = 0; // Level difference to be set when creating games. Set to 0 not to use level restrictions.
var GameDescription = ""; // The description to be used for your game. Set to "" not to enter a game description.
var JoinRandomGamesChars = new Array("YourNameGoesHere");// Dynamic array that holds chars that are to join public games.
var JoinGameKeywords = new Array("dia", "baal"); // If your char is set to join public games, games will only be joined if the game name contains one of the given keywords.
//------------------------------------------------------------------------------
// Channel Settings
//------------------------------------------------------------------------------
var IgnoreWispers = true; // Set to true to ignore all incoming wispers from players that are not on your friendlist.
var JoinChatAfterLogin = true; // Join chat after login.
var JoinRandomChannel = true; // If this is true, will join a random channel, otherwise it will use the channel below..
var JoinChannelInChat = "OP tnsk"; // Leave blank not to join a private channel.
var PerformChannelLogin = false; // Type ".login" once after joining the channel.
var ChannelUsers = new Array(); // Dynamic array that holds channel users.
// Add any char/account here that is supposed to perform chat actions/game announcements or join a private channel
ChannelUsers.push("YourCharNameGoesHere");
// Or
ChannelUsers.push("YourAccountNameGoesHere");
// The following key expressions will be replaced by their actual values: %game --> "gamename-" <> %counter --> number of the next game <> %time --> time in seconds till game creation <> %password --> game password
// Note that the announcement will start after the first run, so there usually won't be any anncouncement right after login - If the gamename is undefined, the bot will try to load the backup file to announce the upcoming game properly.
var GameAnnouncement = "Creating %game%counter//%password in about %time seconds.";
var ShowStatusOnStartup = true;
var JoinRetries = 5; // How many attempts before giving up the mule game?
var JoinRetryDelay = 55; // Seconds to wait between Retry Attempts.
var TimeBeforeMuleGame = 1; // Minutes to wait before creating the game.
var TimeAfterMule = 3; // Minutes to wait before logging back to bot account.
var WaitOnBlockedAccount = 2; // Minutes to wait if the mule account is currently being used by another char (this delay will be used up to 20 times).
//------------------------------------------------------------------------------
// Misc
//------------------------------------------------------------------------------
var MaximumLocationLoops = 5; // The maximum number of loops for a single location; if the window is does not respond and is caught in an infinite loop it will be restarted when the number of loops exceeds the one you specify here.
//---------------------------------------------------------------------------------------------------------------------------------------------------------
// DONT EDIT ANYTHING BELOW THIS!
//---------------------------------------------------------------------------------------------------------------------------------------------------------
// AutoMule Variables and Stuff
const DGDebug = false;
const AUTOMULE_READY = 1;
const AUTOMULE_FULL = 0;
const AUTOMULE_NOMULES = -1;
function AutomuleData()
{
this.InProgress = false;
this.PreventRecover = false;
this.IsWaiting = false;
this.State = "notmuling";
this.CurrentAccount = 0;
this.MuleIndex = 0;
this.IsReadyState = AUTOMULE_READY;
// Account creation variables
this.CreateAccount = false;
this.CharCreateNumber = -1;
this.RegMail = "";
this.MuleFull = false;
this.AccName;
this.AccPw;
this.AccPrefix;
this.AccSuffix = new Array();
this.NewAccPw = new Array();
this.UserNumbers;
this.IsLadder;
this.IsHC;
this.IsClassic;
this.RandomNameLength;
this.GameName;
this.GamePassword;
this.Mules = new Array();
this.MuleAccs;
this.MulePws;
this.NipFiles = new Array();
this.CharLoc;
this.MuleIsFullThreshold;
this.JoinBug;
this.NewCharBug = 0;
this.FullAuto = false;
}
var Automule = new AutomuleData();
Include("libs/controlInfo.ntl");
Include("libs/common/NTCommon.ntl");
Include("NTBot/mule_configs/NTConfig_AutoMule.ntl");
NT_LoadMuleConfig();
Include("libs/common/DGAutoMule.ntl");
// D2NT Manager Command
const D2NT_MGR_LOADING = 1;
const D2NT_MGR_READY = 2;
const D2NT_MGR_LOGIN = 3;
const D2NT_MGR_CREATE_GAME = 4;
const D2NT_MGR_INGAME = 5;
const D2NT_MGR_RESTART = 6;
const D2NT_MGR_CHICKEN = 7;
const D2NT_MGR_PRINT_STATUS = 8;
const D2NT_MGR_PRINT_LOG = 9;
var LastGameMade = GetTickCount();
var LastGameStatus = 0;
var NextGameMake = 0;
var InGameAt = 0;
var LocationLoops = new Array(2);
var ChatActionsDone = false;
var LastGameFailed = false;
var JoinedChannel = false;
var JustJoined = true;
var MadeAnnouncement = false;
// This is for recovering purpose, delete mulestate file is you get stuck
DGAM_ReadMuleStats();
MWAM_ReleaseUsedAccounts();
MWAM_InitializedMuleLoads(false);
var ControlData = new controlInfo();
function NTMain()
{
var _ingame, _scriptPath;
Delay(1000);
_ingame = false;
ConnectingToBnetTimeout *= 1000;
GameMinLength *= 1000;
CharacterScreenTimeout *= 1000;
PleaseWaitTimeout *= 1000;
CreateGameThreshold *= 1000;
CreateGameThresholdRandom *= 1000;
CreateGameTimeout *= 1000;
WaitInLineTimeout *= 1000;
GameDoesNotExistDelayMin *= 1000*60;
GameDoesNotExistDelayMax *= 1000*60;
GameDoesNotExistTimeout *= 1000;
ControlData.ClickDelay = ClickDelay;
ControlData.TextDelay = TextDelay;
ControlData.ClickDelayRandom = ClickDelayRandom;
ControlData.TextDelayRandom = TextDelayRandom;
RegisterEvent(EVENT_SCRIPTMSG, DGAM_MuleMsgEvents);
while(true)
{
if(me.ingame)
{
if(!InGameAt)
InGameAt = GetTickCount();
if(!_ingame)
{
if(Automule.InProgress)
{
if(DGDebug)
NTC_SendLogToOOG(NTC_LOG_COMMON, "[Debug] Joined Mule Game");
switch(Automule.State)
{
case "notmuling": // Done or not yet started
// No... we really are not supposed to be here
Automule.InProgress = false;
ExitGame();
NTC_SendLogToOOG(NTC_LOG_COMMON, "AutoMule Error, try again.");
SetStatusText("ÿc1AutoMule Error... (Wait 60s)");
Delay(60000);
break;
case "mulestart": // Still on Bot Account
_scriptPath = "NTBot/bots/NTPermGameandMule.ntj";
break;
case "mule": //Muleing
case "mulefull": // Mule Full
case "done": // Next Account
case "recover": // Recovering
_scriptPath = "NTBot/bots/NTPickStuff.ntj";
break;
default:
_scriptPath = "NTBot/NTPermGameandMule.ntj";
break;
}
if(DGDebug)
NTC_SendLogToOOG(NTC_LOG_COMMON, "Debug: Load " + _scriptPath);
RunGC();
if(Load(_scriptPath))
{
_ingame = true;
Automule.JoinBugCount = 0;
MadeAnnouncement = false;
LocationLoops[1] = 0;
MW_WriteBackupFile();
if(me.playtype > 0)
NT_SendEventToOOG(D2NT_MGR_INGAME, "Currently in Mule Game", 0);
else
NT_SendEventToOOG(D2NT_MGR_INGAME, "Oops, that's not gonna work honey.", 0);
LastGameStatus = 2; // in game successful
}
}
else
{
RunGC(); // run garbage collector between each game
if(Load("NTBot/MWBotGame.ntj"))
{
_ingame = true;
MadeAnnouncement = false;
LocationLoops[1] = 0;
MW_WriteBackupFile();
if(me.playtype > 0)
NT_SendEventToOOG(D2NT_MGR_INGAME, "In Game [IP:" + me.gameserverip.split(".")[3] + "]", 0);
else
NT_SendEventToOOG(D2NT_MGR_INGAME, "In Game", 0);
LastGameStatus = 2; // in game successful
}
}
}
Delay(1000);
}
else
{
if(Automule.IsWaiting)
Delay(1000);
else
{
if(_ingame)
{
_ingame = false;
NT_SendEventToOOG(D2NT_MGR_READY, "", 0);
Delay(4000);
}
if(Automule.InProgress)
DGAM_DoMuleLocationAction();
else
NT_LocationAction(ControlData.getLocation());
Delay(500);
}
}
}
}
function NT_LocationAction(location)
{
var _randomChannel, _output, _control;
MW_CheckLocationLoops(location);
switch(location.id)
{
case 3: // Lobby Chat
if(JustJoined)
{
JustJoined = false;
if(MW_ArrayContainsUser(ChannelUsers))
_output = "ÿc2Chat actions enabled!";
else
_output = "ÿc1Chat actions disabled!";
for(var i = 0; i < 3; i++)
{
SetStatusText(_output);
Delay(500);
SetStatusText("");
Delay(500);
}
if(IgnoreWispers)
{
Say("/o igw");
Delay(500);
}
}
if(!ChatActionsDone && MW_ArrayContainsUser(ChannelUsers))
{
ChatActionsDone = true;
Delay(Random(WaitInChatBeforeActionsMin, WaitInChatBeforeActionsMax));
if(!JoinedChannel && (JoinRandomChannel || JoinChannelInChat != ""))
{
_randomChannel = NT_GetRandomString(Random(3,10));
SetStatusText("ÿc8Joining Channel ÿc;" + (JoinRandomChannel ? _randomChannel : JoinChannelInChat));
Delay(500);
Say("/join " + (JoinRandomChannel ? _randomChannel : JoinChannelInChat));
JoinedChannel = true;
if(PerformChannelLogin)
{
SetStatusText("ÿc8Channel Login...");
Say(".login");
Delay(1000);
}
}
}
case 1: // Lobby
if(location.id == 1 && JoinChatAfterLogin)
{
Delay(Random(WaitBeforeEnterChatMin, WaitBeforeEnterChatMax));
ControlData.click(ControlData.controls.lobby.butto n.enterChat);
break;
}
if(GetTickCount() > NextGameMake)
{
LastGameFailed = false;
switch(LastGameStatus)
{
case 0:
if(MW_ArrayContainsUser(JoinRandomGamesChars))
{
_control = ControlData.get(ControlData.controls.lobby.button. join);
if(_control && _control.pressed)
{
ControlData.click(ControlData.controls.lobby.butto n.create);
Delay(500);
}
ControlData.click(ControlData.controls.lobby.butto n.join);
}
else
{
_control = ControlData.get(ControlData.controls.lobby.button. create);
if(_control && _control.pressed)
{
ControlData.click(ControlData.controls.lobby.butto n.join);
Delay(500);
}
ControlData.click(ControlData.controls.lobby.butto n.create);
}
NextGameMake = GetTickCount() + CreateGameTimeout; // set our timeout
NT_SendEventToOOG(D2NT_MGR_PRINT_STATUS, location.name, 0);
break;
case 1: // game failed, rollover to reset timer
InGameAt = GetTickCount();
LastGameFailed = true;
Delay(5000);
case 2:
NT_OutputGameLength();
LastGameStatus = 0;
NT_SetNextGameMake();
if(LastGameFailed)
{
SetStatusText("ÿc1Failed to join!");
NT_SendEventToOOG(D2NT_MGR_PRINT_LOG, "ÿBE0000Game creation failed!", 0);
Delay(1000);
}
NT_SendEventToOOG(D2NT_MGR_PRINT_STATUS, location.name, 0);
break;
}
}
else
{
if(JoinChannelInChat && !MadeAnnouncement && MW_ArrayContainsUser(ChannelUsers))
{
if(MW_AnnounceGame())
MadeAnnouncement = true;
}
MW_TimeoutDelay(NextGameMake - GetTickCount(), location, !MW_ArrayContainsUser(JoinRandomGamesChars));
}
break;
case 2: // Waiting In Line
if(GetTickCount() - LastGameMade > WaitInLineTimeout)
ControlData.click(ControlData.controls.lobby.inLin e.button.cancel);
break;
case 4: // Create Game
if(!MW_ArrayContainsUser(JoinRandomGamesChars))
{
if(!ControlData.get(ControlData.controls.lobby.cre ate.editBox.gameName))
{
ControlData.click(ControlData.controls.lobby.butto n.join);
Delay(500);
ControlData.click(ControlData.controls.lobby.butto n.create);
Delay(500);
}
_control = ControlData.get(ControlData.controls.lobby.create. button.useCharacterDifference);
if(_control)
{
if(CharacterDifference == 0 && _control.pressed || CharacterDifference >= 1 && CharacterDifference <= 99 && !_control.pressed)
{
ControlData.click(ControlData.controls.lobby.creat e.button.useCharacterDifference);
Delay(1000);
}
}
_control = ControlData.get(ControlData.controls.lobby.create. editBox.maxNumberOfPlayers);
if(_control)
{
if(PlayersPerGame >= 1 && PlayersPerGame <= 8 && _control.text != PlayersPerGame.toString())
{
ControlData.setText(ControlData.controls.lobby.cre ate.editBox.maxNumberOfPlayers, PlayersPerGame.toString());
Delay(1000);
}
}
_control = ControlData.get(ControlData.controls.lobby.create. editBox.characterDifference);
if(_control)
{
if(_control.text != CharacterDifference.toString())
{
ControlData.setText(ControlData.controls.lobby.cre ate.editBox.characterDifference, CharacterDifference.toString());
Delay(1000);
}
}
if(GameDescription)
{
ControlData.setText(ControlData.controls.lobby.cre ate.editBox.gameDescription, GameDescription);
Delay(1000);
}
NT_SendEventToOOG(D2NT_MGR_CREATE_GAME, location.name, 0);
NT_LocationTimeout(5000, location);
LastGameMade = GetTickCount();
LastGameStatus = 1; // pending creation
}
break;
case 5: // Join Game
if(MW_ArrayContainsUser(JoinRandomGamesChars))
{
var _games, _game;
_games = ControlData.get(ControlData.controls.lobby.join.te xtBox.gameList).GetText();
_game = "";
if(_games)
{
for(var i = 0; i < _games.length; i++)
{
for(var j = 0; j < JoinGameKeywords.length; j++)
{
if(_games[i].toLowerCase().indexOf(JoinGameKeywords[j].toLowerCase()) > -1)
{
_game = _games[i];
i = _games.length;
break;
}
}
}
}
if(_game != "")
{
SetStatusText("ÿc8Joining Game: " + _game);
Delay(250);
ControlData.setText(ControlData.controls.lobby.joi n.editBox.gameName, _game);
Delay(1000);
ControlData.click(ControlData.controls.lobby.join. button.joinGame);
NT_LocationTimeout(5000, location);
LastGameMade = GetTickCount();
LastGameStatus = 1; // pending creation
}
else
Delay(2500);
ControlData.click(ControlData.controls.lobby.butto n.create);
Delay(500);
ControlData.click(ControlData.controls.lobby.butto n.join);
Delay(500);
}
break;
case 6: // Ladder
break;
case 7: // Channel List
break;
case 8: // Main Menu
if(ControlData.getCurrentRealmIndex() == me.gatewayid)
{
NT_OutputGameLength();
ControlData.click(ControlData.gameTypes[me.playtype]);
}
else
ControlData.click(ControlData.controls.mainMenu.bu tton.gateway);
break;
case 9: // Login
NT_SendEventToOOG(D2NT_MGR_PRINT_STATUS, location.name, 0);
Delay(LoginDelay);
ControlData.setText(ControlData.controls.login.edi tBox.accountName, me.account);
NT_SendEventToOOG(D2NT_MGR_LOGIN, location.name, 0);
NT_LocationTimeout(5000, location);
break;
case 10: // Login Error (this is a fatal error, so stop)
NT_SendEventToOOG(D2NT_MGR_RESTART, location.name, 10);
Delay(3500);
break;
case 11: // Unable To Connect
MW_TimeoutDelay(UnableToConnectRetry*60*1000, location);
ControlData.click(ControlData.controls.login.unabl eToConnect.button.ok);
break;
case 12: // Character Select
var _time, _control;
NT_SendEventToOOG(D2NT_MGR_PRINT_STATUS, location.name, 0);
for(_time = 0 ; _time < CharacterScreenTimeout ; _time += 500)
{
_control = ControlData.get(ControlData.controls.characterSele ct.textBox.characterInfo[me.charloc]);
if(_control && _control.GetText() != undefined)
break;
Delay(500);
}
if(_time < CharacterScreenTimeout)
{
Delay(CharacterSelectDelay);
ControlData.click(ControlData.controls.characterSe lect.textBox.characters[me.charloc], 0, 0, 1);
ControlData.click(ControlData.controls.characterSe lect.textBox.characterInfo[me.charloc], 0, 0, 1);
// reset last game made, so it doesnt make a game immediately
InGameAt = 0;
NT_SetNextGameMake();
}
else
{
ControlData.click(ControlData.controls.characterSe lect.button.exit);
MW_TimeoutDelay(RealmDownRetry*60*1000, location);
}
break;
case 13: // Realm Down - Character Select screen
ControlData.click(ControlData.controls.characterSe lect.button.exit);
MW_TimeoutDelay(RealmDownRetry*60*1000, location);
break;
case 14: // Character Select - Disconnected
MW_TimeoutDelay(DisconnectedRetry*60*1000, location);
ControlData.click(ControlData.controls.characterSe lect.disconnected.button.ok);
break;
case 15: // New Character
break;
case 16: // Character Select - Please Wait popup
if(!NT_LocationTimeout(PleaseWaitTimeout, location))
ControlData.click(ControlData.controls.characterSe lect.pleaseWait.button.cancel);
break;
case 17: // Lobby - Lost Connection - just click okay, since we're toast anyway
ControlData.click(ControlData.controls.lobby.lostC onnection.button.ok);
break;
case 18: // D2 Splash
ControlData.click(ControlData.controls.d2Splash.te xtBox.copyright);
break;
case 19: // Login - Cdkey In Use
MW_TimeoutDelay(CdKeyInUseRetry*60*1000, location);
ControlData.click(ControlData.controls.login.cdkey InUse.button.ok);
break;
case 20: // Single Player - Select Difficulty
ControlData.click(ControlData.singlePlayerDifficul ties[me.diff]);
break;
case 21: // Main Menu - Connecting
if(!NT_LocationTimeout(ConnectingToBnetTimeout, location))
ControlData.click(ControlData.controls.mainMenu.co nnecting.button.cancel);
break;
case 22: // Login - Invalid Cdkey (classic or xpac)
NT_SendEventToOOG(D2NT_MGR_RESTART, location.name, 3600);
Delay(3500);
break;
case 23: // Character Select - Connecting
if(!NT_LocationTimeout(CharacterScreenTimeout, location))
ControlData.click(ControlData.controls.characterSe lect.button.exit);
break;
case 24: // Server Down - not much to do but wait..
break;
case 25: // Lobby - Please Wait
if(!NT_LocationTimeout(PleaseWaitTimeout, location))
ControlData.click(ControlData.controls.lobby.pleas eWait.button.cancel);
break;
case 26: // Lobby - Game Name Exists
NT_SendEventToOOG(D2NT_MGR_PRINT_LOG, "ÿBE0000Game already exists", 0);
SetStatusText("ÿc1Game already exists!");
InGameAt = 0;
LastGameStatus = 0;
NT_SetNextGameMake();
NT_LocationTimeout(15000, location);
break;
case 27: // Gateway Select
ControlData.clickRealmEntry(me.gatewayid);
ControlData.click(ControlData.controls.gateway.but ton.ok);
break;
case 28: // Lobby - Game Does Not Exist
InGameAt = Random(GameDoesNotExistDelayMin, GameDoesNotExistDelayMax);
LastGameStatus = 0;
NT_SetNextGameMake();
NT_LocationTimeout(GameDoesNotExistTimeout, location);
break;
}
}
function NT_SendEventToOOG(locationId, statusString, pendingTime)
{
return SendCopyData("D2NT Manager", null, (locationId<<16)|pendingTime, statusString);
}
function NT_SetNextGameMake()
{
LastGameMade = GetTickCount();
NextGameMake = LastGameMade + CreateGameThreshold + Random(0 - CreateGameThresholdRandom, CreateGameThresholdRandom) + InGameAt;
InGameAt = 0;
ChatActionsDone = false;
}
function NT_OutputGameLength()
{
var _duration;
if(InGameAt)
{
_duration = GetTickCount() - InGameAt;
if(_duration < GameMinLength)
InGameAt = GameMinLength - _duration;
else
InGameAt = 0;
}
}
function NT_LocationTimeout(time, location)
{
var _endtime = GetTickCount() + time;
while(ControlData.getLocation().id == location.id && _endtime > GetTickCount())
{
if(LocationLoops[1] > 1)
NT_SendEventToOOG(D2NT_MGR_PRINT_STATUS, location.name + " [" + MWC_ConvertTicksToTimeString(_endtime - GetTickCount()) + "] [" + LocationLoops[1] + "]", 0);
else
NT_SendEventToOOG(D2NT_MGR_PRINT_STATUS, location.name + " [" + MWC_ConvertTicksToTimeString(_endtime - GetTickCount()) + "]", 0);
Delay(1000);
}
return (ControlData.getLocation().id != location.id);
}
function MW_TimeoutDelay(time, location, showNextGameStatus)
{
var _gamename, _outputString, _timeString;
if(arguments.length < 3)
showNextGameStatus = false;
_endtime = GetTickCount() + time;
_gamename = me.gamename;
_timeString = "";
if(!_gamename)
{
_gamename = MW_ReadBackupFile(0);
if(_gamename)
SetStatusText("ÿc8Using File Backup...");
}
while(_endtime > GetTickCount())
{
_timeString = " [" + MWC_ConvertTicksToTimeString(_endtime - GetTickCount()) + "]";
NT_SendEventToOOG(D2NT_MGR_PRINT_STATUS, location.name + _timeString , 0);
if(showNextGameStatus)
{
if(LastGameFailed && parseInt(_endtime-GetTickCount()) > CreateGameThreshold && parseInt((_endtime-GetTickCount())/1000) % 30 >= 0 && parseInt((_endtime-GetTickCount())/1000) % 30 <= 5)
{
_outputString = "ÿc1Last game failed!";
_timeString = "";
}
else if(parseInt((_endtime-GetTickCount())/1000) >= 0)
{
if(_gamename && MW_GetGameCounter(_gamename, false))
_outputString = "ÿc8Next game: " + MW_GetGameName(_gamename) + MW_GetGameCounter(_gamename, false);
else
_outputString = "ÿc8Game creation pending... ";
}
MWC_SetStatusText(_outputString, _timeString);
if(me.ingame)
_endtime = GetTickCount();
}
Delay(1000);
}
if(showNextGameStatus)
SetStatusText("ÿc8Creating game...");
return;
}
function NT_GetRandomString(length)
{
_retString = "";
_charSet = "0123456789abcdefghijklmnopqrstuvwxyz";
while(length--)
{
_retString += _charSet.charAt(Random(0, _charSet.length - 1));
Delay(1);
}
return _retString;
}
function MW_GetGameName(lastGameString)
{
if(!lastGameString)
return "";
else
return lastGameString.substr(0, lastGameString.lastIndexOf('-') + 1);
}
function MW_GetGameCounter(lastGameString, simple)
{
var _count, _countString;
if(!lastGameString)
return "-1";
else
{
_countString = lastGameString.slice(lastGameString.lastIndexOf('-') + 1);
if(_countString[0] == '0')
_countString = _countString.substr(1);
_count = parseInt(_countString) + 1;
if(_count == 100)
_count = 0;
if(!simple)
{
if(_count <= 9)
return '0' + _count;
}
return _count;
}
}
function MW_ArrayContainsUser(array)
{
for(var i = 0; i < array.length; i++)
{
if(me.account.toLowerCase() == array[i].toLowerCase() || me.charname.toLowerCase() == array[i].toLowerCase())
return true;
}
return false;
}
function MW_ReadBackupFile(type)
{
var _fhandle, _buffer, _time, _now, _retValue;
_fhandle = FileOpen("/Logs/Temporary Data/" + me.charname + ".channel", 2);
_retValue = "";
_now = new Date();
if(_fhandle && _now)
{
_buffer = _fhandle.ReadLine();
if(_buffer)
{
_time = parseInt(_buffer);
if(_now.getTime() - _time < UseFileBackupTimeMax*6E4)
{
_retValue = _fhandle.ReadLine();
if(type > 0)
_retValue = _fhandle.ReadLine();
}
}
_fhandle.Close();
}
else if(_fhandle)
_fhandle.Close();
return _retValue;
}
function MW_WriteBackupFile()
{
var _fhandle, _now;
if(UseFileBackupTimeMax == 0)
return false;
_fhandle = FileOpen("/Logs/Temporary Data/" + me.charname + ".channel", 1);
_now = new Date();
if(_fhandle && _now)
{
_fhandle.WriteLine(_now.getTime());
_fhandle.WriteLine(me.gamename);
_fhandle.WriteLine(me.gamepassword);
_fhandle.Close();
return true;
}
else if(_fhandle)
_fhandle.Close();
return false;
}
function MW_CheckLocationLoops(location)
{
if(!location)
return false;
if(!LocationLoops[0] || location.id != LocationLoops[0].id)
{
LocationLoops[0] = location;
LocationLoops[1] = 0;
}
else if(LocationLoops[0].id != 5)
{
LocationLoops[1]++;
if(LocationLoops[1] >= MaximumLocationLoops)
{
if(LocationLoops[1] < 1000)
NT_SendEventToOOG(D2NT_MGR_PRINT_LOG, "ÿBE0000Location Loop Restart!;ÿc1Location Loops: " + LocationLoops[1] + "\nÿBE0000Location: " + LocationLoops[0].name + "\nÿBE0000Location ID: " + LocationLoops[0].id, 0);
LocationLoops[1] = 1000; // Make sure the location loop notification is only shown once
NT_SendEventToOOG(D2NT_MGR_RESTART, location.name, 0);
}
}
return true;
}
function MW_AnnounceGame()
{
var _gamePass, _gameName, _gameText, _delay;
_gameName = me.gamename;
if(!_gameName)
_gameName = MW_ReadBackupFile(0);
_gamePass = me.gamepassword;
if(!_gamePass)
_gamePass = MW_ReadBackupFile(1);
if(_gameName && !me.ingame)
{
_delay = (GameAnnouncementDelay > 5000) ? GameAnnouncementDelay : 5000;
_delay += (GameAnnouncementDelayRandom > 500) ? Random(0, GameAnnouncementDelayRandom) : 500;
_gameText = GameAnnouncement.replace("%password", ((_gamePass) ? _gamePass : "N/A"));
_gameText = _gameText.replace("%game", MW_GetGameName(_gameName));
_gameText = _gameText.replace("%counter", MW_GetGameCounter(_gameName, false));
_gameText = _gameText.replace("%time", parseInt((NextGameMake - GetTickCount() - _delay + ClickDelay + TextDelay) / 1000 + 5));
if(_gameText.indexOf("NaN") > -1)
return false;
if(parseInt((NextGameMake - GetTickCount() - _delay + ClickDelay + TextDelay) / 1000) > 3)
{
Delay(_delay);
return Say(_gameText);
}
}
return false;
}