private static bool SetupPaths() { try { CreateDirectory(Statics.WorldPath); CreateDirectory(Statics.PluginPath); CreateDirectory(Statics.DataPath); CreateDirectory(Statics.LibrariesPath); AppDomain.CurrentDomain.AppendPrivatePath(Statics.LibrariesPath); //For Mono, The config setting doesn't f*****g work. } catch (Exception exception) { ProgramLog.Log(exception); ProgramLog.Log("Press any key to continue..."); Console.ReadKey(true); return(false); } CreateFile(Statics.DataPath + Path.DirectorySeparatorChar + "whitelist.txt"); CreateFile(Statics.DataPath + Path.DirectorySeparatorChar + "banlist.txt"); CreateFile(Statics.DataPath + Path.DirectorySeparatorChar + "oplist.txt"); CreateFile(Statics.DataPath + Path.DirectorySeparatorChar + "server.log"); return(true); }
public static void PrintUpdateInfo() { try { // ProgramLog.Log ("Attempting to retreive Build Info..."); var buildInfo = String.Empty; using (var ctx = new WebClient()) { using (var prog = new ProgressLogger(100, "Downloading build information...")) { var signal = new System.Threading.AutoResetEvent(false); ctx.DownloadProgressChanged += (sender, args) => { prog.Value = args.ProgressPercentage; }; ctx.DownloadStringCompleted += (sender, args) => { var arg = args as DownloadStringCompletedEventArgs; buildInfo = arg.Result; signal.Set(); }; ctx.DownloadStringAsync(new Uri(UpdateInfo)); signal.WaitOne(); } } if (String.IsNullOrEmpty(buildInfo)) { ProgramLog.Log("Failed to download build information."); return; } var toString = "comments: "; //if (buildInfo.ToLower().Contains(toString)) var index = buildInfo.ToLower().IndexOf(toString); if (index != -1) { buildInfo = buildInfo.Remove(0, index + toString.Length).Trim(); foreach (var pair in BuildInfoReplacements) { buildInfo = buildInfo.Replace(pair.Key, pair.Value); } ProgramLog.Log("Build Comments: \n\t " + buildInfo); } } catch (Exception) { } }
public static void Main(string[] argz) { try { Thread.CurrentThread.Name = "Main"; string MODInfo = "Terraria Sign On Door. "; try { Console.Title = MODInfo; } catch { } var options = new OptionSet() { { "p|port=", v => port = v }, }; var args = options.Parse(argz); if (args.Count == 0) { mmessage = "The server is down for maintenance."; } else if (args.Count == 1) { mmessage = args[0]; } else { mmessage = ""; for (int i = 0; i < args.Count; i++) { mmessage = mmessage + " " + args[i]; } } l = new TcpListener(IPAddress.Any, Convert.ToInt32(port)); listenThread = new Thread(new ThreadStart(ListenForClients)); listenThread.Start(); while (!listenThread.IsAlive) { ; } ProgramLog.Log("Starting TSignOnDoor \"" + mmessage + "\" "); } catch (FormatException e) { ProgramLog.Log("Port must be an Integer."); } }
public static bool PerformProcess() { if (!Program.properties.AutomaticUpdates) { return(false); } ProgramLog.Log("Checking for updates..."); int build; if (!TrySeeIfIsUpToDate(out build)) { ProgramLog.Log("Update found, performing b{0} -> b{1}", Statics.BUILD, build); PrintUpdateInfo(); string myFile = System.AppDomain.CurrentDomain.FriendlyName; PerformUpdate(UpdateLink, "Terraria_Server.upd", "Terraria_Server.bak", myFile, 1, MaxUpdates); PerformUpdate(UpdateMDBLink, "Terraria_Server.upd.mdb", "Terraria_Server.bak.mdb", myFile + ".mdb", 2, MaxUpdates); Platform.PlatformType oldPlatform = Platform.Type; //Preserve old data if command args were used Platform.InitPlatform(); //Reset Data of Platform for determinine exit/enter method. if (Platform.Type == Platform.PlatformType.WINDOWS) { try { Process.Start(myFile); } catch (Exception e) { Platform.Type = oldPlatform; ProgramLog.Log(e, "Could not boot into the new Update!"); return(false); } } else { Platform.Type = oldPlatform; ProgramLog.Log("Exiting, please re-run the program to use your new installation."); throw new UpdateCompleted(); } return(true); } else { ProgramLog.Log("TDSM is up to date."); } return(false); }
public static void StartPanic() { if (!Liquid.panicMode) { WorldModify.waterLine = Main.maxTilesY; Liquid.numLiquid = 0; LiquidBuffer.numLiquidBuffer = 0; Liquid.panicCounter = 0; Liquid.panicMode = true; Liquid.panicY = Main.maxTilesY - 3; ProgramLog.Log("Forcing water to settle."); } }
private static bool CreateFile(string filePath) { if (!File.Exists(filePath)) { try { File.Create(filePath).Close(); } catch (Exception exception) { ProgramLog.Log(exception); ProgramLog.Log("Press any key to continue..."); Console.ReadKey(true); return(false); } } return(true); }
public static void LoadPlugins() { ProgramLog.Log(Languages.Startup_LoadingPlugins); Terraria_Server.Plugins.PluginManager.Initialize(Statics.PluginPath, Statics.LibrariesPath); var ctx = new HookContext() { Sender = ConsoleSender = new ConsoleSender() }; var eArgs = new HookArgs.ServerStateChange() { ServerChangeState = ServerState.INITIALIZING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); PluginManager.LoadPlugins(); ProgramLog.Log(Languages.Startup_PluginsLoaded + ' ' + PluginManager.PluginCount); }
public static void printUpdateInfo() { try { ProgramLog.Log("Attempting to retreive Build Info..."); string buildInfo = new System.Net.WebClient().DownloadString(UpdateInfo).Trim(); string toString = "comments: "; if (buildInfo.ToLower().Contains(toString)) { buildInfo = buildInfo.Remove(0, buildInfo.ToLower().IndexOf(toString.ToLower()) + toString.Length).Trim().Replace("<br/>", "\n"); //This is also used for the forums, so easy use here ;D if (buildInfo.Length > 0) { ProgramLog.Log("Build Comments: " + buildInfo); } } } catch (Exception) { } }
public static void StopServer() { var ctx = new HookContext { Sender = new ConsoleSender(), }; var args = new HookArgs.ServerStateChange { ServerChangeState = ServerState.STOPPING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref args); //Statics.IsActive = Statics.keepRunning; //To keep console active & program alive upon restart; ProgramLog.Log("Disabling Plugins"); PluginManager.DisablePlugins(); ProgramLog.Log("Closing Connections..."); disconnect = true; }
private static void CommandThread(object result) { while (!Statics.Exit || Restarting) { try { string line = Console.ReadLine(); if (line.Length > 0) { commandParser.ParseConsoleCommand(line); } } catch (ExitException e) { ProgramLog.Log(e.Message); break; } catch (Exception e) { ProgramLog.Log(e, Languages.Startup_IssueParsingConsoleCommand); } } }
private static void ListenForClients() { try { l.Start(); ProgramLog.Log("Listening for clients on port " + port + "."); while (enabled) { //blocks until a client has connected to the server TcpClient client = l.AcceptTcpClient(); //create a thread to handle communication //with connected client Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm)); clientThread.Start(client); } ProgramLog.Log("Stopped listening for clients."); } catch (SocketException e) { if (e.ErrorCode == 10013) { ProgramLog.Log("Access denied for that port."); } else if (e.ErrorCode == 10048) { ProgramLog.Log("Port already in use."); } else { ProgramLog.Log(e.StackTrace); } } }
public static void ServerLoop() { Main.players[255].whoAmi = 255; NetPlay.serverIP = IPAddress.Parse(serverSIP); NetPlay.serverListenIP = NetPlay.serverIP; NetPlay.disconnect = false; // for (int i = 0; i < 256; i++) // { //// Netplay.slots[i] = new ServerSlot(); // Netplay.slots[i].whoAmI = i; // Netplay.slots[i].Reset(); // } Init(); NetPlay.tcpListener = new TcpListener(NetPlay.serverListenIP, NetPlay.serverPort); try { NetPlay.tcpListener.Start(); } catch (Exception exception) { ProgramLog.Error.Log("Error Starting the Server: {0}", exception); NetPlay.disconnect = true; } if (!NetPlay.disconnect) { if (!Program.updateThread.IsAlive) { Program.updateThread.Start(); } ProgramLog.Admin.Log("{0} {1}:{2}", Language.Languages.ServerStartedOn, serverSIP, serverPort); // ProgramLog.Log("Loading Plugins..."); // PluginManager.LoadAllPlugins(); // ProgramLog.Log("Plugins Loaded: " + PluginManager.Plugins.Count.ToString()); //Statics.serverStarted = true; } else { return; } SlotManager.Initialize(Program.properties.MaxPlayers, Program.properties.OverlimitSlots); ServerUp = true; var serverSock = NetPlay.tcpListener.Server; try { while (!NetPlay.disconnect) { NetPlay.anyClients = Networking.ClientConnection.All.Count > 0; //clientList.Count > 0; serverSock.Poll(500000, SelectMode.SelectRead); if (NetPlay.disconnect) { break; } // Accept new clients while (NetPlay.tcpListener.Pending()) { var client = NetPlay.tcpListener.AcceptSocket(); var accepted = AcceptClient(client); if (accepted) { NetPlay.anyClients = true; } } } } catch (Exception e) { ProgramLog.Log(e, "ServerLoop terminated with exception"); } NetPlay.anyClients = false; try { tcpListener.Stop(); } catch (SocketException) { } lock (Networking.ClientConnection.All) { var conns = Networking.ClientConnection.All.ToArray(); foreach (var conn in conns) { conn.Kick("Server is shutting down."); } } for (int i = 0; i < 255; i++) { try { slots[i].Kick("Server is shutting down."); } catch { } } Thread.Sleep(1000); for (int i = 0; i < 255; i++) { try { slots[i].Reset(); } catch { } } if (!WorldIO.SaveWorld(World.SavePath, true)) { ProgramLog.Error.Log("Saving failed. Quitting without saving."); } ServerUp = false; }
public TileCollection(int X, int Y) { ProgramLog.Log("Creating tile array of {0}x{1}, {2}MB", X, Y, Marshal.SizeOf(typeof(TileData)) * X * Y / 1024 / 1024); data = new TileData [X, Y]; }
public static int SendData(int packetId, int remoteClient = -1, int ignoreClient = -1, string text = "", int number = 0, float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0) { if (!NetPlay.anyClients) { return(0); } try { var msg = PrepareThreadInstance(); switch (packetId) { case (int)Packet.CONNECTION_REQUEST: msg.ConnectionRequest(Statics.CURRENT_TERRARIA_RELEASE_STR); break; case (int)Packet.DISCONNECT: msg.Disconnect(text); break; case (int)Packet.CONNECTION_RESPONSE: msg.ConnectionResponse(remoteClient); break; case (int)Packet.PLAYER_DATA: msg.PlayerData(number); break; case (int)Packet.INVENTORY_DATA: msg.InventoryData(number, (byte)number2, (int)number3); break; case (int)Packet.WORLD_REQUEST: msg.WorldRequest(); break; case (int)Packet.WORLD_DATA: msg.WorldData(); break; case (int)Packet.REQUEST_TILE_BLOCK: msg.RequestTileBlock(); break; case (int)Packet.SEND_TILE_LOADING: msg.SendTileLoading(number, text); break; case (int)Packet.SEND_TILE_ROW: msg.SendTileRow(number, (int)number2, (int)number3); break; case (int)Packet.SEND_TILE_CONFIRM: msg.SendTileConfirm(number, (int)number2, (int)number3, (int)number4); break; case (int)Packet.RECEIVING_PLAYER_JOINED: msg.ReceivingPlayerJoined(number); break; case (int)Packet.PLAYER_STATE_UPDATE: msg.PlayerStateUpdate(number); break; case (int)Packet.SYNCH_BEGIN: msg.SynchBegin(number, (int)number2); break; case (int)Packet.UPDATE_PLAYERS: msg.UpdatePlayers(); break; case (int)Packet.PLAYER_HEALTH_UPDATE: msg.PlayerHealthUpdate(number); break; case (int)Packet.TILE_BREAK: msg.TileBreak(number, (int)number2, (int)number3, (int)number4, (int)number5); break; case (int)Packet.TIME_SUN_MOON_UPDATE: msg.TimeSunMoonUpdate(); break; case (int)Packet.DOOR_UPDATE: msg.DoorUpdate(number, (int)number2, (int)number3, (int)number4); break; case (int)Packet.TILE_SQUARE: msg.TileSquare(number, (int)number2, (int)number3); break; case (int)Packet.ITEM_INFO: msg.ItemInfo(number); break; case (int)Packet.ITEM_OWNER_INFO: msg.ItemOwnerInfo(number); break; case (int)Packet.NPC_INFO: msg.NPCInfo(number); break; case (int)Packet.STRIKE_NPC: msg.StrikeNPC(number, (int)number2); break; case (int)Packet.PLAYER_CHAT: msg.PlayerChat(number, text, (byte)number2, (byte)number3, (byte)number4); break; case (int)Packet.STRIKE_PLAYER: msg.StrikePlayer(number, text, (int)number2, (int)number3, (int)number4); break; case (int)Packet.PROJECTILE: msg.Projectile(Main.projectile[number]); break; case (int)Packet.DAMAGE_NPC: msg.DamageNPC(number, (int)number2, number3, (int)number4); break; case (int)Packet.KILL_PROJECTILE: msg.KillProjectile(number, (int)number2); break; case (int)Packet.PLAYER_PVP_CHANGE: msg.PlayerPVPChange(number); break; case (int)Packet.OPEN_CHEST: msg.OpenChest(); break; case (int)Packet.CHEST_ITEM: msg.ChestItem(number, (int)number2); break; case (int)Packet.PLAYER_CHEST_UPDATE: msg.PlayerChestUpdate(number); break; case (int)Packet.KILL_TILE: msg.KillTile(); break; case (int)Packet.HEAL_PLAYER: msg.HealPlayer(number, (int)number2); break; case (int)Packet.ENTER_ZONE: msg.EnterZone(number); break; case (int)Packet.PASSWORD_REQUEST: msg.PasswordRequest(); break; case (int)Packet.PASSWORD_RESPONSE: msg.PasswordResponse(); break; case (int)Packet.ITEM_OWNER_UPDATE: msg.ItemOwnerUpdate(number); break; case (int)Packet.NPC_TALK: msg.NPCTalk(number); break; case (int)Packet.PLAYER_BALLSWING: msg.PlayerBallswing(number); break; case (int)Packet.PLAYER_MANA_UPDATE: msg.PlayerManaUpdate(number); break; case (int)Packet.PLAYER_USE_MANA_UPDATE: msg.PlayerUseManaUpdate(number, (int)number2); break; case (int)Packet.KILL_PLAYER_PVP: msg.KillPlayerPVP(number, text, (int)number2, (int)number3, (int)number4); break; case (int)Packet.PLAYER_JOIN_PARTY: msg.PlayerJoinParty(number); break; case (int)Packet.READ_SIGN: msg.ReadSign(number, (int)number2); break; case (int)Packet.WRITE_SIGN: msg.WriteSign(number); break; case (int)Packet.FLOW_LIQUID: msg.FlowLiquid(number, (int)number2); break; case (int)Packet.SEND_SPAWN: msg.SendSpawn(); break; case (int)Packet.PLAYER_BUFFS: msg.PlayerBuffs(number); break; case (int)Packet.SUMMON_SKELETRON: msg.SummonSkeletron((byte)number, (byte)number2); break; case (int)Packet.CHEST_UNLOCK: msg.ChestUnlock(number, (int)number2, (int)number3, (int)number4); break; case (int)Packet.NPC_ADD_BUFF: msg.NPCAddBuff(number, (int)number2, (int)number3); break; case (int)Packet.NPC_BUFFS: msg.NPCBuffs(number); break; case (int)Packet.PLAYER_ADD_BUFF: msg.PlayerAddBuff(number, (int)number2, (int)number3); break; case (int)Packet.CLIENT_MOD: msg.ClientMod(remoteClient); break; case (int)Packet.CLIENT_MOD_SPAWN_NPC: msg.RpgNPCSpawned(number); break; case (int)Packet.NPC_NAME: msg.NPCName(number, Main.chrName[number]); break; default: { //Unknown packet :3 var ctx = new HookContext() { }; var args = new HookArgs.UnkownSendPacket() { Message = msg, PacketId = packetId, RemoteClient = remoteClient, IgnoreClient = ignoreClient, Text = text, Number = number, Number2 = number2, Number3 = number3, Number4 = number4, Number5 = number5 }; HookPoints.UnkownSendPacket.Invoke(ref ctx, ref args); /* Update Locals */ msg = args.Message; remoteClient = args.RemoteClient; ignoreClient = args.IgnoreClient; if (ctx.Result != HookResult.IGNORE) { return(0); } else { break; } } } //var bytes = msg.Output; if (remoteClient == -1) { msg.BroadcastExcept(ignoreClient); // for (int num11 = 0; num11 < 256; num11++) // { // if (num11 != ignoreClient && Netplay.slots[num11].state >= SlotState.PLAYING && Netplay.slots[num11].Connected) // { // NetMessage.buffer[num11].spamCount++; // Netplay.slots[num11].Send (bytes); // } // } } else if (NetPlay.slots[remoteClient].Connected) { msg.Send(remoteClient); //NetMessage.buffer[remoteClient].spamCount++; //Netplay.slots[remoteClient].Send (bytes); } return(msg.Written); } catch (Exception e) { ProgramLog.Log(e, "SendData error"); } return(0); }
public static void ParseArgs(string[] args) { try { if (args != null && args.Length > 0) { for (int i = 0; i < args.Length; i++) { //if (i == (args.Length - 1) && args.Length > 1) { break; } string commandMessage = args[i].ToLower().Trim(); // 0 for Ops if (commandMessage.Equals("-ignoremessages:0")) { Statics.cmdMessages = false; } else if (commandMessage.Equals("-maxplayers")) { int val; if (Int32.TryParse(args[i + 1], out val)) { properties.MaxPlayers = val; } } else if (commandMessage.Equals("-ip")) { properties.ServerIP = args[i + 1]; } else if (commandMessage.Equals("-port")) { int val; if (Int32.TryParse(args[i + 1], out val)) { properties.Port = val; } } else if (commandMessage.Equals("-greeting")) { properties.Greeting = args[i + 1]; } else if (commandMessage.Equals("-worldpath")) { properties.WorldPath = args[i + 1]; } else if (commandMessage.Equals("-password")) { properties.Password = args[i + 1]; } else if (commandMessage.Equals("-allowupdates")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.AutomaticUpdates = val; } } else if (commandMessage.Equals("-npcdoorcancel")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.NPCDoorOpenCancel = val; } } else if (commandMessage.Equals("-seed")) { try { properties.Seed = args[i + 1]; } catch (Exception) { } } else if (commandMessage.Equals("-mapsize")) { properties.MapSize = args[i + 1]; } else if (commandMessage.Equals("-usecustomtiles")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.UseCustomTiles = val; } } else if (commandMessage.Equals("-maxtilesx")) { int val; if (Int32.TryParse(args[i + 1], out val)) { properties.MaxTilesX = val; } } else if (commandMessage.Equals("-maxtilesy")) { int val; if (Int32.TryParse(args[i + 1], out val)) { properties.MaxTilesY = val; } } else if (commandMessage.Equals("-numdungeons")) { int val; if (Int32.TryParse(args[i + 1], out val)) { properties.DungeonAmount = val; } } else if (commandMessage.Equals("-customworldgen")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.UseCustomGenOpts = val; } } else if (commandMessage.Equals("-numislands")) { int val; if (Int32.TryParse(args[i + 1], out val)) { properties.FloatingIslandAmount = val; } } else if (commandMessage.Equals("-whitelist")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.UseWhiteList = val; } } else if (commandMessage.Equals("-pidfile")) { try { properties.PIDFile = args[i + 1]; } catch { } } else if (commandMessage.Equals("-simpleloop")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.SimpleLoop = val; } } else if (commandMessage.Equals("-windowsoutput")) { Platform.Type = Platform.PlatformType.WINDOWS; bool val; if (Boolean.TryParse(args[i + 1], out val) && !val) { Platform.Type = Platform.PlatformType.LINUX; } } else if (commandMessage.Equals("-hackeddata")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.HackedData = val; } } else if (commandMessage.Equals("-rconip")) { try { properties.RConBindAddress = args[i + 1]; } catch { } } else if (commandMessage.Equals("-rconsalt")) { try { properties.RConHashNonce = args[i + 1]; } catch { } } else if (commandMessage.Equals("-rotatelog")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.LogRotation = val; } } else if (commandMessage.Equals("-spawnnpcmax")) { int val; if (Int32.TryParse(args[i + 1], out val)) { properties.SpawnNPCMax = val; } } else if (commandMessage.Equals("-disablemaxplayers")) { SlotManager.MaxPlayersDisabled = true; } else if (commandMessage.Equals("-allowexplosions")) { bool val; if (Boolean.TryParse(args[i + 1], out val)) { properties.AllowExplosions = val; } } else if (commandMessage.Equals("-rejectitems")) { properties.RejectedItems = args[i + 1]; } } properties.Save(); } } catch (Exception e) { ProgramLog.Log(e); } }
public static void UpdateLoop() { try { if (Terraria_Server.Main.rand == null) { Terraria_Server.Main.rand = new Random((int)DateTime.Now.Ticks); } bool hibernate = properties.StopUpdatesWhenEmpty; if (properties.SimpleLoop) { Stopwatch s = new Stopwatch(); s.Start(); double updateTime = 16.66666666666667; double nextUpdate = s.ElapsedMilliseconds + updateTime; while (!NetPlay.disconnect) { double now = s.ElapsedMilliseconds; double left = nextUpdate - now; if (left >= 0) { while (left > 1) { Thread.Sleep((int)left); left = nextUpdate - s.ElapsedMilliseconds; } nextUpdate += updateTime; } else { nextUpdate = now + updateTime; } if (NetPlay.anyClients || (hibernate == false)) { var start = s.Elapsed; Terraria_Server.Main.Update(s); LastUpdateTime = s.Elapsed - start; } } return; } double serverProcessAverage = 16.666666666666668; double leftOver = 0.0; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (!NetPlay.disconnect) { double elapsed = (double)stopwatch.ElapsedMilliseconds; if (elapsed + leftOver >= serverProcessAverage) { leftOver += elapsed - serverProcessAverage; stopwatch.Reset(); stopwatch.Start(); if (leftOver > 1000.0) { leftOver = 1000.0; } if (NetPlay.anyClients || (hibernate == false)) { Terraria_Server.Main.Update(stopwatch); } double num9 = (double)stopwatch.ElapsedMilliseconds + leftOver; if (num9 < serverProcessAverage) { int num10 = (int)(serverProcessAverage - num9) - 1; if (num10 > 1) { Thread.Sleep(num10); if (hibernate && !NetPlay.anyClients) { leftOver = 0.0; Thread.Sleep(10); } } } } Thread.Sleep(0); } } catch (Exception e) { ProgramLog.Log(e, "World update thread crashed"); } }
public static void Update(Stopwatch s) { int count = 0; int timeUpdateErrors = 0; int worldUpdateErrors = 0; int invasionUpdateErrors = 0; int serverUpdateErrors = 0; var start = s.Elapsed; foreach (Player player in Main.players) { try { player.UpdatePlayer(count); } catch (Exception e) { if (!Main.ignoreErrors) { throw; } ProgramLog.Log(e, String.Format("Player update error, slot={0}, address={1}, name={2}", player.whoAmi, player.IPAddress, player.Name != null ? string.Concat('"', player.Name, '"') : "<null>")); player.Kick("Server malfunction, please reconnect."); } count++; } LastPlayerUpdateTime = s.Elapsed - start; lock (updatingNPCs) { start = s.Elapsed; NPC.SpawnNPC(); foreach (Player player in Main.players) { player.activeNPCs = 0; player.townNPCs = 0; } if (Main.WallOfFlesh >= 0 && !Main.npcs[Main.WallOfFlesh].Active) { Main.WallOfFlesh = -1; } for (int i = 0; i < NPC.MAX_NPCS; i++) { // if (Main.npcs[i] == null) // { // ProgramLog.Debug.Log ("NPC[{0}] is null", i); // continue; // } try { NPC.UpdateNPC(i); } catch (Exception e) { if (!Main.ignoreErrors) { throw; } var npc = Main.npcs[i]; ProgramLog.Log(e, String.Format("NPC update error, id={0}, type={1}, name={2}", i, npc.Type, npc.Name)); Main.npcs[i] = Registries.NPC.Default; Main.npcs[i].netUpdate = true; } } LastNPCUpdateTime = s.Elapsed - start; } lock (updatingProjectiles) { start = s.Elapsed; for (int i = 0; i < 1000; i++) { // if (Main.projectile[i] == null) // { // ProgramLog.Debug.Log ("Projectile[{0}] is null", i); // continue; // } try { Main.projectile[i].Update(i); } catch (Exception e) { if (!Main.ignoreErrors) { throw; } var proj = Main.projectile[i]; ProgramLog.Log(e, String.Format("Projectile update error, i={0}, id={1}, owner={2}, type={3}", i, proj.identity, proj.Owner, proj.Type)); //Main.projectile[i] = new Projectile(); Projectile.Reset(i); } } LastProjectileUpdateTime = s.Elapsed - start; } lock (updatingItems) { start = s.Elapsed; for (int i = 0; i < 200; i++) { // if (Main.item[i] == null) // { // ProgramLog.Debug.Log ("Item[{0}] is null", i); // continue; // } try { Main.item[i].UpdateItem(i); } catch (Exception e) { if (!Main.ignoreErrors) { throw; } var item = Main.item[i]; ProgramLog.Log(e, String.Format("Projectile update error, i={0}, type={1}, owner={2}, stack={3}", i, item.Type, item.Owner, item.Stack)); Main.item[i] = new Item(); } } LastItemUpdateTime = s.Elapsed - start; } start = s.Elapsed; try { Main.UpdateTime(); timeUpdateErrors = 0; } catch (Exception e) { if (++timeUpdateErrors >= 5 || !Main.ignoreErrors) { throw; } ProgramLog.Log(e, "Time update error"); Main.checkForSpawns = 0; } LastTimeUpdateTime = s.Elapsed - start; start = s.Elapsed; try { WorldModify.UpdateWorld(World.Sender); worldUpdateErrors = 0; } catch (Exception e) { if (++worldUpdateErrors >= 5 || !Main.ignoreErrors) { throw; } ProgramLog.Log(e, "World update error"); } LastWorldUpdateTime = s.Elapsed - start; start = s.Elapsed; try { Main.UpdateInvasion(); invasionUpdateErrors = 0; } catch (Exception e) { if (++invasionUpdateErrors >= 5 || !Main.ignoreErrors) { throw; } ProgramLog.Log(e, "Invasion update error"); } LastInvasionUpdateTime = s.Elapsed - start; start = s.Elapsed; try { Main.UpdateServer(); serverUpdateErrors = 0; } catch (Exception e) { if (++serverUpdateErrors >= 5 || !Main.ignoreErrors) { throw; } ProgramLog.Log(e, "Server update error"); } LastServerUpdateTime = s.Elapsed - start; }
public static void UpdateLoop() { #if CATCHERROR_UPDATELOOP try { #endif if (Terraria_Server.Main.rand == null) { Terraria_Server.Main.rand = new Random((int)DateTime.Now.Ticks); } bool hibernate = properties.StopUpdatesWhenEmpty, backup = false; int collect = 0, backupInterval = properties.BackupInterval; DateTime backupDate = DateTime.Now; if (backupInterval > 0) { backup = properties.AllowBackups; } if (properties.SimpleLoop) { Stopwatch s = new Stopwatch(); s.Start(); double updateTime = 16.66666666666667; double nextUpdate = s.ElapsedMilliseconds + updateTime; while (!NetPlay.disconnect) { double now = s.ElapsedMilliseconds; double left = nextUpdate - now; if (left >= 0) { while (left > 1) { Thread.Sleep((int)left); left = nextUpdate - s.ElapsedMilliseconds; } nextUpdate += updateTime; } else { nextUpdate = now + updateTime; } if (NetPlay.anyClients || (hibernate == false)) { var start = s.Elapsed; Terraria_Server.Main.Update(s); LastUpdateTime = s.Elapsed - start; } if (collect++ >= 1000) //Every 1000 loops should be less intensive. { if (properties.CollectGarbage) { GC.Collect(); } collect = 0; } /* Check tolled tasks */ Tasks.CheckTasks(); if ((DateTime.Now - backupDate).TotalMinutes >= backupInterval && backup) { backupDate = DateTime.Now; try { BackupManager.AutoPurge(); BackupManager.PerformBackup(); } catch (Exception e) { ProgramLog.Error.Log( String.Format("Error during the backup process.\n{0}", e) ); } } } return; } double serverProcessAverage = 16.666666666666668; double leftOver = 0.0; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (!NetPlay.disconnect) { double elapsed = (double)stopwatch.ElapsedMilliseconds; if (elapsed + leftOver >= serverProcessAverage) { leftOver += elapsed - serverProcessAverage; stopwatch.Reset(); stopwatch.Start(); if (leftOver > 1000.0) { leftOver = 1000.0; } if (NetPlay.anyClients || (hibernate == false)) { Terraria_Server.Main.Update(stopwatch); } double num9 = (double)stopwatch.ElapsedMilliseconds + leftOver; if (num9 < serverProcessAverage) { int num10 = (int)(serverProcessAverage - num9) - 1; if (num10 > 1) { Thread.Sleep(num10); if (hibernate && !NetPlay.anyClients) { leftOver = 0.0; Thread.Sleep(10); } } } /* Check tolled tasks */ Tasks.CheckTasks(); if (collect++ >= 1000) //Every 1000 loops should be less intensive. { if (properties.CollectGarbage) { GC.Collect(); } collect = 0; } if ((DateTime.Now - backupDate).TotalMinutes >= backupInterval && backup) { backupDate = DateTime.Now; ProgramLog.Log("Performing backup..."); BackupManager.PerformBackup(); } } Thread.Sleep(0); } #if CATCHERROR_UPDATELOOP } catch (Exception e) { ProgramLog.Log(e, "World update thread crashed"); } #endif }
public static void UpdateLiquid(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox) { if (TileRefs == null) { TileRefs = TileCollection.ITileAt; } //{ //Liquid.cycles = 30; // Liquid.maxLiquid = 6000; //} if (!WorldModify.gen) { if (!Liquid.panicMode) { if (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > 4000) { Liquid.panicCounter++; if (Liquid.panicCounter > 1800 || Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > 13500) { Liquid.StartPanic(); } } else { Liquid.panicCounter = 0; } } if (Liquid.panicMode) { int num = 0; while (Liquid.panicY >= 3 && num < 5) { num++; Liquid.QuickWater(TileRefs, sandbox, 0, Liquid.panicY, Liquid.panicY); Liquid.panicY--; if (Liquid.panicY < 3) { ProgramLog.Log(Languages.Water_WaterHasBeenSettled); Liquid.panicCounter = 0; Liquid.panicMode = false; using (var prog = new ProgressLogger(Main.maxTilesX - 2, Languages.Water_PerformingWaterCheck)) WorldModify.WaterCheck(TileRefs, sandbox, prog); for (int i = 0; i < 255; i++) { for (int j = 0; j < Main.maxSectionsX; j++) { for (int k = 0; k < Main.maxSectionsY; k++) { NetPlay.slots[i].tileSection[j, k] = false; } } } } } return; } } Liquid.quickFall = Liquid.quickSettle || Liquid.numLiquid > 2000; Liquid.wetCounter++; int num2 = Liquid.maxLiquid / Liquid.cycles; int num3 = num2 * (Liquid.wetCounter - 1); int num4 = num2 * Liquid.wetCounter; if (Liquid.wetCounter == Liquid.cycles) { num4 = Liquid.numLiquid; } if (num4 > Liquid.numLiquid) { num4 = Liquid.numLiquid; Liquid.wetCounter = Liquid.cycles; } if (Liquid.quickFall) { for (int l = num3; l < num4; l++) { Main.liquid[l].delay = 10; Main.liquid[l].Update(TileRefs, sandbox); TileRefs(Main.liquid[l].x, Main.liquid[l].y).SetSkipLiquid(false); } } else { for (int m = num3; m < num4; m++) { if (!TileRefs(Main.liquid[m].x, Main.liquid[m].y).SkipLiquid) { Main.liquid[m].Update(TileRefs, sandbox); } else { TileRefs(Main.liquid[m].x, Main.liquid[m].y).SetSkipLiquid(false); } } } if (Liquid.wetCounter >= Liquid.cycles) { Liquid.wetCounter = 0; for (int n = Liquid.numLiquid - 1; n >= 0; n--) { if (Main.liquid[n].kill > 3) { Liquid.DelWater(TileRefs, sandbox, n); } } int num5 = Liquid.maxLiquid - (Liquid.maxLiquid - Liquid.numLiquid); if (num5 > LiquidBuffer.numLiquidBuffer) { num5 = LiquidBuffer.numLiquidBuffer; } for (int num6 = 0; num6 < num5; num6++) { TileRefs(Main.liquidBuffer[0].x, Main.liquidBuffer[0].y).SetCheckingLiquid(false); Liquid.AddWater(TileRefs, sandbox, Main.liquidBuffer[0].x, Main.liquidBuffer[0].y); LiquidBuffer.DelBuffer(0); } if (Liquid.numLiquid > 0 && Liquid.numLiquid > Liquid.stuckAmount - 50 && Liquid.numLiquid < Liquid.stuckAmount + 50) { Liquid.stuckCount++; if (Liquid.stuckCount >= 10000) { Liquid.stuck = true; for (int num7 = Liquid.numLiquid - 1; num7 >= 0; num7--) { Liquid.DelWater(TileRefs, sandbox, num7); } Liquid.stuck = false; Liquid.stuckCount = 0; return; } } else { Liquid.stuckCount = 0; Liquid.stuckAmount = Liquid.numLiquid; } } }
public static void UpdateLiquid() { Liquid.cycles = 25; Liquid.maxLiquid = 5000; if (!WorldModify.gen) { if (!Liquid.panicMode) { if (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > 4000) { Liquid.panicCounter++; if (Liquid.panicCounter > 1800 || Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > 13500) { Liquid.StartPanic(); } } else { Liquid.panicCounter = 0; } } if (Liquid.panicMode) { try { Terraria_Server.Networking.LiquidUpdateBuffer.ClearQueue(); NetMessage.DisableLiquidUpdates = true; int num = 0; while (Liquid.panicY >= 3 && num < 5) { num++; Liquid.QuickWater(0, Liquid.panicY, Liquid.panicY); Liquid.panicY--; if (Liquid.panicY < 3) { ProgramLog.Log("Water has been settled."); Liquid.panicCounter = 0; Liquid.panicMode = false; using (var prog = new ProgressLogger(Main.maxTilesX - 2, "Performing water check")) WorldModify.WaterCheck(prog); for (int i = 0; i < 255; i++) { for (int j = 0; j < Main.maxSectionsX; j++) { for (int k = 0; k < Main.maxSectionsY; k++) { NetPlay.slots[i].tileSection[j, k] = false; } } } } } return; } finally { NetMessage.DisableLiquidUpdates = false; } } } if (Liquid.quickSettle || Liquid.numLiquid > 2000) { Liquid.quickFall = true; } else { Liquid.quickFall = false; } Liquid.wetCounter++; int num2 = Liquid.maxLiquid / Liquid.cycles; int num3 = num2 * (Liquid.wetCounter - 1); int num4 = num2 * Liquid.wetCounter; if (Liquid.wetCounter == Liquid.cycles) { num4 = Liquid.numLiquid; } if (num4 > Liquid.numLiquid) { num4 = Liquid.numLiquid; Liquid.wetCounter = Liquid.cycles; } if (Liquid.quickFall) { for (int l = num3; l < num4; l++) { Main.liquid[l].delay = 10; Main.liquid[l].Update(); Main.tile.At(Main.liquid[l].x, Main.liquid[l].y).SetSkipLiquid(false); } } else { for (int m = num3; m < num4; m++) { if (!Main.tile.At(Main.liquid[m].x, Main.liquid[m].y).SkipLiquid) { Main.liquid[m].Update(); } else { Main.tile.At(Main.liquid[m].x, Main.liquid[m].y).SetSkipLiquid(false); } } } if (Liquid.wetCounter >= Liquid.cycles) { Liquid.wetCounter = 0; for (int n = Liquid.numLiquid - 1; n >= 0; n--) { if (Main.liquid[n].kill > 3) { Liquid.DelWater(n); } } int num5 = Liquid.maxLiquid - (Liquid.maxLiquid - Liquid.numLiquid); if (num5 > LiquidBuffer.numLiquidBuffer) { num5 = LiquidBuffer.numLiquidBuffer; } for (int num6 = 0; num6 < num5; num6++) { Main.tile.At(Main.liquidBuffer[0].x, Main.liquidBuffer[0].y).SetCheckingLiquid(false); Liquid.AddWater(Main.liquidBuffer[0].x, Main.liquidBuffer[0].y); LiquidBuffer.DelBuffer(0); } if (Liquid.numLiquid > 0 && Liquid.numLiquid > Liquid.stuckAmount - 50 && Liquid.numLiquid < Liquid.stuckAmount + 50) { Liquid.stuckCount++; if (Liquid.stuckCount >= 10000) { Liquid.stuck = true; for (int num7 = Liquid.numLiquid - 1; num7 >= 0; num7--) { Liquid.DelWater(num7); } Liquid.stuck = false; Liquid.stuckCount = 0; return; } } else { Liquid.stuckCount = 0; Liquid.stuckAmount = Liquid.numLiquid; } } }
private static void HandleClientComm(object client) { TcpClient tcpClient = (TcpClient)client; NetworkStream clientStream = tcpClient.GetStream(); byte[] message = new byte[4096]; int bytesRead; DateTime value = DateTime.UtcNow; string time = value.ToString("yyyy/MM/dd HH:mm:ss"); ProgramLog.Log(time + ">(" + tcpClient.Client.RemoteEndPoint.ToString() + ") Connecting..."); while (enabled) { bool finished = false; bool error = false; while (!finished) { bytesRead = 0; message = new byte[4096]; try { //blocks until a client sends a message bytesRead = clientStream.Read(message, 0, message.Length); } catch { //a socket error has occured error = true; break; } if (bytesRead == 0) { //the client has disconnected from the server error = true; break; } // ProgramLog.Log("read from client"); //message has successfully been received // string numbers = ""; // for (int j = 0; j < message[0] + 4; j++) // { // string s = Convert.ToString(message[j], 16); // numbers = numbers + " " + s; // } // ProgramLog.Log(numbers); //accept connection after first read if (message[2] == 0x01) //connection request from client { byte[] accept = { 0x04, 0x00, 0x03, 0x00 }; clientStream.Write(accept, 0, accept.Length); clientStream.Flush(); // ProgramLog.Log("write to client"); } if (message[2] == 0x04) { // parses the player info to get the player's name ASCIIEncoding en = new ASCIIEncoding(); string name = en.GetString(message, 7, message[6]); ProgramLog.Log(name + " tried to join."); } // client send request for world info, so we are done reading if (message[2] == 0x06) { // kick the client ASCIIEncoding asen = new ASCIIEncoding(); byte[] down = asen.GetBytes(mmessage); byte[] buffer2 = { (byte)(down.Length + 1), 0x00, 0x02, (byte)down.Length }; byte[] msg = new byte[down.Length + 4]; Array.Copy(buffer2, 0, msg, 0, 4); Array.Copy(down, 0, msg, 4, down.Length); clientStream.Write(msg, 0, msg.Length); clientStream.Flush(); // ProgramLog.Log("write to client"); finished = true; } } if (error) { break; } } value = DateTime.UtcNow; time = value.ToString("yyyy/MM/dd HH:mm:ss"); ProgramLog.Log(time + ">(" + tcpClient.Client.RemoteEndPoint.ToString() + ") disconnected..."); clientStream.Close(); tcpClient.Close(); }
public static bool PerformUpdate(string DownloadLink, string savePath, string backupPath, string myFile, int Update, int MaxUpdates, string header = "update ") { if (File.Exists(savePath)) { try { File.Delete(savePath); } catch (Exception e) { ProgramLog.Log(e, "Error deleting old file"); return(false); } } if (File.Exists(myFile) && !MoveFile(myFile, backupPath)) { ProgramLog.Log("Error moving current file!"); return(false); } var download = new System.Net.WebClient(); Exception error = null; string downloadText = ""; if (MaxUpdates > 1) { downloadText = "Downloading " + header + Update.ToString() + "/" + MaxUpdates.ToString() + " from server"; } else { downloadText = "Downloading " + header + "from server"; } using (var prog = new ProgressLogger(100, downloadText)) { var signal = new System.Threading.AutoResetEvent(false); download.DownloadProgressChanged += (sender, args) => { prog.Value = args.ProgressPercentage; }; download.DownloadFileCompleted += (sender, args) => { error = args.Error; signal.Set(); }; download.DownloadFileAsync(new Uri(DownloadLink), savePath); signal.WaitOne(); } if (error != null) { ProgramLog.Log(error, "Error downloading update"); return(false); } //Program.tConsole.Write("Finishing Update..."); if (!MoveFile(savePath, myFile)) { ProgramLog.Log("Error moving updated file!"); return(false); } return(true); }
public TileCollection(int X, int Y) { ProgramLog.Log("{3} {0}x{1}, {2}MB", X, Y, Marshal.SizeOf(typeof(TileData)) * X * Y / 1024 / 1024, Language.Languages.CreatingTileArrayOf); data = new TileData [X, Y]; }
public static void Main(string[] args) { Thread.CurrentThread.Name = "Main"; try { string MODInfo = "Terraria's Dedicated Server Mod. (" + VERSION_NUMBER + " {" + Statics.CURRENT_TERRARIA_RELEASE + "}) #" + Statics.BUILD; try { Console.Title = MODInfo; } catch { } var lis = new Logging.LogTraceListener(); System.Diagnostics.Trace.Listeners.Clear(); System.Diagnostics.Trace.Listeners.Add(lis); System.Diagnostics.Debug.Listeners.Clear(); System.Diagnostics.Debug.Listeners.Add(lis); ProgramLog.Log("Initializing " + MODInfo); ProgramLog.Log("Setting up Paths."); if (!SetupPaths()) { return; } Platform.InitPlatform(); ProgramLog.Log("Setting up Properties."); bool propertiesExist = File.Exists("server.properties"); SetupProperties(); if (!propertiesExist) { ProgramLog.Console.Print("New properties file created. Would you like to exit for editing? [Y/n]: "); if (Console.ReadLine().ToLower() == "y") { ProgramLog.Console.Print("Complete, Press any Key to Exit..."); Console.ReadKey(true); return; } } var logFile = Statics.DataPath + Path.DirectorySeparatorChar + "server.log"; ProgramLog.OpenLogFile(logFile); string PIDFile = properties.PIDFile.Trim(); if (PIDFile.Length > 0) { string ProcessUID = Process.GetCurrentProcess().Id.ToString(); bool Issue = false; if (File.Exists(PIDFile)) { try { File.Delete(PIDFile); } catch (Exception) { ProgramLog.Console.Print("Issue deleting PID file, Continue? [Y/n]: "); if (Console.ReadLine().ToLower() == "n") { ProgramLog.Console.Print("Press any Key to Exit..."); Console.ReadKey(true); return; } Issue = true; } } if (!Issue) { try { File.WriteAllText(PIDFile, ProcessUID); } catch (Exception) { ProgramLog.Console.Print("Issue creating PID file, Continue? [Y/n]: "); if (Console.ReadLine().ToLower() == "n") { ProgramLog.Console.Print("Press any Key to Exit..."); Console.ReadKey(true); return; } } ProgramLog.Log("PID File Created, Process ID: " + ProcessUID); } } ParseArgs(args); try { if (UpdateManager.performProcess()) { ProgramLog.Log("Restarting into new update!"); return; } } catch (UpdateCompleted) { throw; } catch (Exception e) { ProgramLog.Log(e, "Error updating"); } LoadMonitor.Start(); ProgramLog.Log("Starting remote console server"); RemoteConsole.RConServer.Start("rcon_logins.properties"); ProgramLog.Log("Starting permissions manager"); permissionManager = new PermissionManager(); ProgramLog.Log("Preparing Server Data..."); using (var prog = new ProgressLogger(1, "Loading item definitions")) Collections.Registries.Item.Load(); using (var prog = new ProgressLogger(1, "Loading NPC definitions")) Collections.Registries.NPC.Load(Collections.Registries.NPC_FILE); using (var prog = new ProgressLogger(1, "Loading projectile definitions")) Collections.Registries.Projectile.Load(Collections.Registries.PROJECTILE_FILE); commandParser = new CommandParser(); commandParser.ReadPermissionNodes(); ProgramLog.Log("Loading plugins..."); Terraria_Server.Plugins.PluginManager.Initialize(Statics.PluginPath, Statics.LibrariesPath); var ctx = new HookContext() { Sender = new ConsoleSender() }; var eArgs = new HookArgs.ServerStateChange() { ServerChangeState = ServerState.INITIALIZING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); PluginManager.LoadPlugins(); ProgramLog.Log("Plugins loaded: " + PluginManager.PluginCount); string worldFile = properties.WorldPath; FileInfo file = new FileInfo(worldFile); if (!file.Exists) { try { file.Directory.Create(); } catch (Exception exception) { ProgramLog.Log(exception); ProgramLog.Console.Print("Press any key to continue..."); Console.ReadKey(true); return; } ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.GENERATING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); ProgramLog.Log("Generating world '{0}'", worldFile); string seed = properties.Seed; if (seed == "-1") { seed = new Random().Next(100).ToString(); ProgramLog.Log("Generated seed: {0}", seed); } int worldX = properties.GetMapSizes()[0]; int worldY = properties.GetMapSizes()[1]; if (properties.UseCustomTiles) { int X = properties.MaxTilesX; int Y = properties.MaxTilesY; if (X > 0 && Y > 0) { worldX = X; worldY = Y; } if (worldX < (int)World.MAP_SIZE.SMALL_X || worldY < (int)World.MAP_SIZE.SMALL_Y) { ProgramLog.Log("World dimensions need to be equal to or larger than {0} by {1}; using built-in 'small'", (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y); worldX = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5); worldY = (int)World.MAP_SIZE.SMALL_Y; } ProgramLog.Log("Generating world with custom map size: {0}x{1}", worldX, worldY); } Terraria_Server.Main.maxTilesX = worldX; Terraria_Server.Main.maxTilesY = worldY; WorldIO.clearWorld(); Terraria_Server.Main.Initialize(); if (properties.UseCustomGenOpts) { WorldGen.numDungeons = properties.DungeonAmount; WorldModify.ficount = properties.FloatingIslandAmount; } else { WorldGen.numDungeons = 1; WorldModify.ficount = (int)((double)Terraria_Server.Main.maxTilesX * 0.0008); //The Statics one was generating with default values, We want it to use the actual tileX for the world } WorldGen.GenerateWorld(seed); WorldIO.saveWorld(worldFile, true); } ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.LOADING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); // TODO: read map size from world file instead of config int worldXtiles = properties.GetMapSizes()[0]; int worldYtiles = properties.GetMapSizes()[1]; if (properties.UseCustomTiles) { int X = properties.MaxTilesX; int Y = properties.MaxTilesY; if (X > 0 && Y > 0) { worldXtiles = X; worldYtiles = Y; } if (worldXtiles < (int)World.MAP_SIZE.SMALL_X || worldYtiles < (int)World.MAP_SIZE.SMALL_Y) { ProgramLog.Log("World dimensions need to be equal to or larger than {0} by {1}; using built-in 'small'", (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y); worldXtiles = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5); worldYtiles = (int)World.MAP_SIZE.SMALL_Y; } ProgramLog.Log("Using world with custom map size: {0}x{1}", worldXtiles, worldYtiles); } World world = new World(worldXtiles, worldYtiles); world.SavePath = worldFile; Server.InitializeData(world, properties.MaxPlayers, Statics.DataPath + Path.DirectorySeparatorChar + "whitelist.txt", Statics.DataPath + Path.DirectorySeparatorChar + "banlist.txt", Statics.DataPath + Path.DirectorySeparatorChar + "oplist.txt"); NetPlay.password = properties.Password; NetPlay.serverPort = properties.Port; NetPlay.serverSIP = properties.ServerIP; Terraria_Server.Main.Initialize(); Terraria_Server.Main.maxTilesX = worldXtiles; Terraria_Server.Main.maxTilesY = worldYtiles; Terraria_Server.Main.maxSectionsX = worldXtiles / 200; Terraria_Server.Main.maxSectionsY = worldYtiles / 150; WorldIO.LoadWorld(Server.World.SavePath); ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.LOADED }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); updateThread = new ProgramThread("Updt", Program.UpdateLoop); ProgramLog.Log("Starting the Server"); NetPlay.StartServer(); while (!NetPlay.ServerUp) { } ProgramLog.Console.Print("You can now insert Commands."); while (!Statics.Exit) { try { string line = Console.ReadLine(); if (line.Length > 0) { commandParser.ParseConsoleCommand(line); } } catch (ExitException e) { ProgramLog.Log(e.Message); break; } catch (Exception e) { ProgramLog.Log(e, "Issue parsing console command"); } } while (WorldModify.saveLock || NetPlay.ServerUp) { Thread.Sleep(100); } ProgramLog.Log("Exiting..."); Thread.Sleep(1000); } catch (UpdateCompleted) { } catch (Exception e) { try { using (StreamWriter streamWriter = new StreamWriter(Statics.DataPath + Path.DirectorySeparatorChar + "crashlog.txt", true)) { streamWriter.WriteLine(DateTime.Now); streamWriter.WriteLine("Crash Log Generated by TDSM #" + Statics.BUILD + " for " + //+ " r" + Statics.revision + " for " + VERSION_NUMBER + " {" + Statics.CURRENT_TERRARIA_RELEASE + "}"); streamWriter.WriteLine(e); streamWriter.WriteLine(""); } ProgramLog.Log(e, "Program crash"); ProgramLog.Log("Please send crashlog.txt to http://tdsm.org/"); } catch { } } if (File.Exists(properties.PIDFile.Trim())) { File.Delete(properties.PIDFile.Trim()); } Thread.Sleep(500); ProgramLog.Log("Log end."); ProgramLog.Close(); RemoteConsole.RConServer.Stop(); }
public static void Update(Stopwatch s) { int count = 0; int timeUpdateErrors = 0; int worldUpdateErrors = 0; int invasionUpdateErrors = 0; int serverUpdateErrors = 0; var start = s.Elapsed; foreach (Player player in players) { try { player.UpdatePlayer(null, null, count); } catch (Exception e) { if (!ignoreErrors) { throw; } ProgramLog.Log(e, String.Format("Player update error, slot={0}, address={1}, name={2}", player.whoAmi, player.IPAddress, player.Name != null ? string.Concat('"', player.Name, '"') : "<null>")); player.Kick("Server malfunction, please reconnect."); } count++; } LastPlayerUpdateTime = s.Elapsed - start; lock (updatingNPCs) { start = s.Elapsed; NPC.SpawnNPC(); foreach (Player player in players) { player.ActiveNPCs = 0; player.TownNPCs = 0; } if (WallOfFlesh >= 0) { var WoF = npcs[WallOfFlesh]; var isWoF = WoF.type == NPCType.N113_WALL_OF_FLESH || WoF.type == NPCType.N114_WALL_OF_FLESH_EYE; if (!isWoF && WoF.Active || !WoF.Active && isWoF) { WallOfFlesh = -1; } } for (int i = 0; i < NPC.MAX_NPCS; i++) // if (npcs[i] == null) // { // ProgramLog.Debug.Log ("NPC[{0}] is null", i); // continue; // } #if CATCHERROR_NPCUPDATES { try { #endif { NPC.UpdateNPC(i); } #if CATCHERROR_NPCUPDATES } catch (Exception e) { if (!ignoreErrors) { throw; } var npc = npcs[i]; ProgramLog.Log(e, String.Format("NPC update error, id={0}, type={1}, name={2}", i, npc.Type, npc.Name)); npcs[i] = Registries.NPC.Default; npcs[i].netUpdate = true; } #endif LastNPCUpdateTime = s.Elapsed - start; } lock (updatingProjectiles) { start = s.Elapsed; for (int i = 0; i < 1000; i++) { // if (projectile[i] == null) // { // ProgramLog.Debug.Log ("Projectile[{0}] is null", i); // continue; // } try { lock (WorldModify.playerEditLock) { var editor = TileBreakMessage.staticEditor; var sandbox = editor.Sandbox; editor.Sandbox.Initialize(); projectile[i].Update(editor.ITileAt, sandbox, i); Player player = null; if (projectile != null && projectile[i].Owner != myPlayer) { player = players[projectile[i].Owner]; } editor.Sandbox.Apply(player); } } catch (Exception e) { if (!ignoreErrors) { throw; } var proj = projectile[i]; ProgramLog.Log(e, String.Format("Projectile update error, i={0}, id={1}, owner={2}, type={3}", i, proj.identity, proj.Owner, proj.Type)); //projectile[i] = new Projectile(); Projectile.Reset(i); } } LastProjectileUpdateTime = s.Elapsed - start; } lock (updatingItems) { start = s.Elapsed; for (int i = 0; i < 200; i++) // if (item[i] == null) // { // ProgramLog.Debug.Log ("Item[{0}] is null", i); // continue; // } try { item[i].UpdateItem(null, i); } catch (Exception e) { if (!ignoreErrors) { throw; } var itm = item[i]; ProgramLog.Log(e, String.Format("Projectile update error, i={0}, type={1}, owner={2}, stack={3}", i, itm.Type, itm.Owner, itm.Stack)); item[i] = new Item(); } } LastItemUpdateTime = s.Elapsed - start; } start = s.Elapsed; try { UpdateTime(); timeUpdateErrors = 0; } catch (Exception e) { if (++timeUpdateErrors >= 5 || !ignoreErrors) { throw; } ProgramLog.Log(e, "Time update error"); checkForSpawns = 0; } LastTimeUpdateTime = s.Elapsed - start; start = s.Elapsed; try { WorldModify.UpdateWorld(null, null, World.Sender); worldUpdateErrors = 0; } catch (Exception e) { if (++worldUpdateErrors >= 5 || !ignoreErrors) { throw; } ProgramLog.Log(e, "World update error"); } LastWorldUpdateTime = s.Elapsed - start; start = s.Elapsed; try { UpdateInvasion(); invasionUpdateErrors = 0; } catch (Exception e) { if (++invasionUpdateErrors >= 5 || !ignoreErrors) { throw; } ProgramLog.Log(e, "Invasion update error"); } LastInvasionUpdateTime = s.Elapsed - start; start = s.Elapsed; try { UpdateServer(); serverUpdateErrors = 0; } catch (Exception e) { if (++serverUpdateErrors >= 5 || !ignoreErrors) { throw; } ProgramLog.Log(e, "Server update error"); } LastServerUpdateTime = s.Elapsed - start; }
public static void Main(string[] args) { Thread.CurrentThread.Name = "Main"; //header: Terraria's Dedicated Server Mod. (1.1.2 #36) ~ Build: 37 [CodeName] string codeName = Statics.CODENAME.Length > 0 ? String.Format(" [{0}]", Statics.CODENAME) : String.Empty; string MODInfo = String.Format( "Terraria's Dedicated Server Mod. ({0} #{1}) ~ Build: {2}{3}", Statics.VERSION_NUMBER, Statics.CURRENT_TERRARIA_RELEASE, Statics.BUILD, codeName ); try { try { Console.Title = MODInfo; } catch { } var lis = new Logging.LogTraceListener(); System.Diagnostics.Trace.Listeners.Clear(); System.Diagnostics.Trace.Listeners.Add(lis); System.Diagnostics.Debug.Listeners.Clear(); System.Diagnostics.Debug.Listeners.Add(lis); using (var prog = new ProgressLogger(1, "Loading language definitions")) Languages.LoadClass(Collections.Registries.LANGUAGE_FILE); if (Languages.Startup_Initializing == null) { ProgramLog.Error.Log("Please update the language file, either by deleting or finding another online."); Console.ReadKey(true); return; } ProgramLog.Log("{0} {1}", Languages.Startup_Initializing, MODInfo); ProgramLog.Log(Languages.Startup_SettingUpPaths); if (!SetupPaths()) { return; } Platform.InitPlatform(); ProgramLog.Log(Languages.Startup_SettingUpProperties); bool propertiesExist = File.Exists("server.properties"); SetupProperties(); if (!propertiesExist) { ProgramLog.Console.Print(Languages.Startup_NoPropertiesFileFound); if (Console.ReadLine().ToLower() == "y") { //ProgramLog.Console.Print(Languages.Startup_PropertiesCreationComplete); ProgramLog.Log(Languages.ExitRequestCommand); //Console.ReadKey(true); return; } } var logFile = Statics.DataPath + Path.DirectorySeparatorChar + "server.log"; ProgramLog.OpenLogFile(logFile); string PIDFile = properties.PIDFile.Trim(); if (PIDFile.Length > 0) { string ProcessUID = Process.GetCurrentProcess().Id.ToString(); bool Issue = false; if (File.Exists(PIDFile)) { try { File.Delete(PIDFile); } catch (Exception) { ProgramLog.Console.Print(Languages.Startup_IssueDeletingPID); if (Console.ReadLine().ToLower() == "n") { ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit); Console.ReadKey(true); return; } Issue = true; } } if (!Issue) { try { File.WriteAllText(PIDFile, ProcessUID); } catch (Exception) { ProgramLog.Console.Print(Languages.Startup_IssueCreatingPID); if (Console.ReadLine().ToLower() == "n") { ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit); Console.ReadKey(true); return; } } ProgramLog.Log(Languages.Startup_PIDCreated + ProcessUID); } } ParseArgs(args); try { if (UpdateManager.PerformProcess()) { ProgramLog.Log(Languages.Startup_RestartingIntoNewUpdate); return; } } catch (UpdateCompleted) { throw; } catch (Exception e) { ProgramLog.Log(e, Languages.Startup_ErrorUpdating); } LoadMonitor.Start(); ProgramLog.Log(Languages.Startup_StartingRCON); RemoteConsole.RConServer.Start("rcon_logins.properties"); ProgramLog.Log(Languages.Startup_StartingPermissions); permissionManager = new PermissionManager(); ProgramLog.Log(Languages.Startup_PreparingServerData); using (var prog = new ProgressLogger(1, Languages.Startup_LoadingItemDefinitions)) Collections.Registries.Item.Load(); using (var prog = new ProgressLogger(1, Languages.Startup_LoadingNPCDefinitions)) Collections.Registries.NPC.Load(Collections.Registries.NPC_FILE); using (var prog = new ProgressLogger(1, Languages.Startup_LoadingProjectileDefinitions)) Collections.Registries.Projectile.Load(Collections.Registries.PROJECTILE_FILE); //if (Languages.IsOutOfDate()) // ProgramLog.Error.Log( // String.Format("{0}\n{1}", // Languages.Startup_LanguageFileOOD, Languages.Startup_LanguageFileUpdate) // , true); commandParser = new CommandParser(); commandParser.ReadPermissionNodes(); LoadPlugins(); /* Save access languages - once only */ Languages.Save(Collections.Registries.LANGUAGE_FILE); HookContext ctx; HookArgs.ServerStateChange eArgs; string worldFile = properties.WorldPath; FileInfo file = new FileInfo(worldFile); if (!file.Exists) { try { file.Directory.Create(); } catch (Exception exception) { ProgramLog.Log(exception); ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit); Console.ReadKey(true); return; } ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.GENERATING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); ProgramLog.Log("{0} '{1}'", Languages.Startup_GeneratingWorld, worldFile); string seed = properties.Seed; if (seed == "-1") { seed = WorldModify.genRand.Next(Int32.MaxValue).ToString(); ProgramLog.Log("{0} {1}", Languages.Startup_GeneratedSeed, seed); } int worldX = properties.GetMapSizes()[0]; int worldY = properties.GetMapSizes()[1]; if (properties.UseCustomTiles) { int X = properties.MaxTilesX; int Y = properties.MaxTilesY; if (X > 0 && Y > 0) { worldX = X; worldY = Y; } if (worldX < (int)World.MAP_SIZE.SMALL_X || worldY < (int)World.MAP_SIZE.SMALL_Y) { ProgramLog.Log("{0} {1}x{2}", Languages.Startup_WorldSizingError, (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y); worldX = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5); worldY = (int)World.MAP_SIZE.SMALL_Y; } ProgramLog.Log("{0} {1}x{2}", Languages.Startup_GeneratingWithCustomSize, worldX, worldY); } Terraria_Server.Main.maxTilesX = worldX; Terraria_Server.Main.maxTilesY = worldY; WorldIO.ClearWorld(); Terraria_Server.Main.Initialize(); if (properties.UseCustomGenOpts) { WorldGen.numDungeons = properties.DungeonAmount; WorldModify.ficount = properties.FloatingIslandAmount; } else { WorldGen.numDungeons = 1; WorldModify.ficount = (int)((double)Terraria_Server.Main.maxTilesX * 0.0008); //The Statics one was generating with default values, We want it to use the actual tileX for the world } WorldGen.GenerateWorld(null, seed); WorldIO.SaveWorld(worldFile, true); } ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.LOADING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); // TODO: read map size from world file instead of config int worldXtiles = properties.GetMapSizes()[0]; int worldYtiles = properties.GetMapSizes()[1]; if (properties.UseCustomTiles) { int X = properties.MaxTilesX; int Y = properties.MaxTilesY; if (X > 0 && Y > 0) { worldXtiles = X; worldYtiles = Y; } if (worldXtiles < (int)World.MAP_SIZE.SMALL_X || worldYtiles < (int)World.MAP_SIZE.SMALL_Y) { ProgramLog.Log("{0} {1}x{2}", Languages.Startup_WorldSizingError, (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y); worldXtiles = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5); worldYtiles = (int)World.MAP_SIZE.SMALL_Y; } ProgramLog.Log("{0} {1}x{2}", Languages.Startup_GeneratingWithCustomSize, worldXtiles, worldXtiles); } World.SavePath = worldFile; Server.InitializeData(properties.MaxPlayers, Statics.DataPath + Path.DirectorySeparatorChar + "whitelist.txt", Statics.DataPath + Path.DirectorySeparatorChar + "banlist.txt", Statics.DataPath + Path.DirectorySeparatorChar + "oplist.txt"); NetPlay.password = properties.Password; NetPlay.serverPort = properties.Port; NetPlay.serverSIP = properties.ServerIP; Terraria_Server.Main.Initialize(); Terraria_Server.Main.maxTilesX = worldXtiles; Terraria_Server.Main.maxTilesY = worldYtiles; Terraria_Server.Main.maxSectionsX = worldXtiles / 200; Terraria_Server.Main.maxSectionsY = worldYtiles / 150; WorldIO.LoadWorld(null, null, World.SavePath); ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.LOADED }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); updateThread = new ProgramThread("Updt", Program.UpdateLoop); ProgramLog.Log(Languages.Startup_StartingTheServer); NetPlay.StartServer(); while (!NetPlay.ServerUp) { } ThreadPool.QueueUserWorkItem(CommandThread); ProgramLog.Console.Print(Languages.Startup_YouCanNowInsertCommands); while (WorldModify.saveLock || NetPlay.ServerUp || Restarting) { Thread.Sleep(100); } ProgramLog.Log(Languages.Startup_Exiting); Thread.Sleep(1000); } catch (UpdateCompleted) { } catch (Exception e) { try { using (StreamWriter streamWriter = new StreamWriter(Statics.DataPath + Path.DirectorySeparatorChar + "crashlog.txt", true)) { streamWriter.WriteLine(DateTime.Now); streamWriter.WriteLine(String.Format("{0} {1}", Languages.Startup_CrashlogGeneratedBy, MODInfo)); streamWriter.WriteLine(e); streamWriter.WriteLine(); } ProgramLog.Log(e, Languages.Startup_ProgramCrash); ProgramLog.Log("{0} crashlog.txt -> http://tdsm.org/", Languages.Startup_PleaseSend); } catch { } } if (properties != null && File.Exists(properties.PIDFile.Trim())) { File.Delete(properties.PIDFile.Trim()); } Thread.Sleep(500); ProgramLog.Log(Languages.Startup_LogEnd); ProgramLog.Close(); RemoteConsole.RConServer.Stop(); }