public static void Load() { if (!Directory.Exists(ControlDirectory)) { Directory.CreateDirectory(ControlDirectory); } if (!File.Exists(SavePath)) { File.Create(SavePath).Close(); } var error = false; foreach (var args in File.ReadAllLines(SavePath).Select(line => line.Split('|')).Where(args => args.Length >= 4)) { try { var sign = new Sign(); sign.SetID(int.Parse(args[0])); sign.SetPosition(new Vector2(int.Parse(args[1]), int.Parse(args[2]))); sign.SetPassword(args[3], args[3] != ""); if (args.Length == 5) { sign.SetWarp(args[4]); } //check if sign still exists in world var id = Terraria.Sign.ReadSign((int)sign.GetPosition().X, (int)sign.GetPosition().Y); if (id != 1) { //the id of sign changed if (id != sign.GetID()) { sign.SetID(id); } //add to array AddSign(sign); } } catch { error = true; } } //TODO: lazy loading of signs ( null checks ) //fill empty slots for (var i = 0; i < Signs.Length; i++) { if (Signs[i] == null) { Signs[i] = new Sign(); Signs[i].SetID(i); } } if (error) { Console.WriteLine("Failed to load some sign data, corresponding signs will be left unprotected."); } }
public static void AddSign(Sign sign) { SetSign(sign.GetID(), sign); }
private static void Set(CommandArgs args) { if (SignControl.Players[args.Player.Index].GetState() == SettingState.Setting) { SignControl.Players[args.Player.Index].PasswordForSign = ""; SignControl.Players[args.Player.Index].SetState(SettingState.None); args.Player.SendMessage(Messages.stopSelecting, Color.BlueViolet); } else { if (args.Parameters.Count < 1) { args.Player.SendMessage(Messages.enterPassword, Color.Red); return; } if ((args.Parameters.Count == 3 || args.Parameters.Count == 4) && args.Parameters[0].ToUpper() == "REGION") { //sets password for all signs in region if (!args.Player.Group.HasPermission(Permissions.protectallsigns)) { args.Player.SendMessage(Messages.noPermissionRegionProtect, Color.Red); return; } if (args.Parameters.Count == 4 && args.Parameters[3].ToUpper() != "TRUE" && args.Parameters[3].ToUpper() != "FALSE") { args.Player.SendMessage(Messages.wrongBool, Color.Red); return; } var region = TShock.Regions.GetRegionByName(args.Parameters[1]); if (region == null) { args.Player.SendMessage(Messages.noRegion, Color.Red); return; } if (!region.HasPermissionToBuildInRegion(args.Player)) { args.Player.SendMessage(Messages.noRegionPermission, Color.Red); return; } for (int l = 0; l < Terraria.Sign.maxSigns; l++) { if (Terraria.Main.sign[l] != null) { if (region.InArea(new Rectangle(Terraria.Main.sign[l].x, Terraria.Main.sign[l].y, 0, 0))) { var sign = SignManager.GetSign(l); var vasnull = false; if (sign == null) { sign = new Sign(); vasnull = true; } if (args.Parameters.Count == 4) { if (args.Parameters[3].ToUpper() == "FALSE" && sign.IsLocked()) { //if already protected skip it continue; } } sign.SetID(l); sign.SetPassword(args.Parameters[2]); sign.SetPosition(Terraria.Main.sign[l].x, Terraria.Main.sign[l].y); if (vasnull) { SignManager.SetSign(l, sign); } SignControl.Players[args.Player.Index].AddSignAccess(l); } } } args.Player.SendMessage(string.Format(Messages.regionLocked, region.Name), Color.BlueViolet); } else if (args.Parameters.Count > 1) { args.Player.SendMessage(Messages.tooManyParams, Color.Red); return; } else { //normal selecting SignControl.Players[args.Player.Index].PasswordForSign = args.Parameters[0]; SignControl.Players[args.Player.Index].SetState(SettingState.Setting); args.Player.SendMessage(string.Format(Messages.openSignTo, Messages.protect), Color.BlueViolet); } } }
private void NetHooks_GetData(GetDataEventArgs e) { try { switch (e.MsgID) { case PacketTypes.SignRead: //on open sign set/unset protection using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) { var reader = new BinaryReader(data); int x = reader.ReadInt32(); int y = reader.ReadInt32(); reader.Close(); int id = Terraria.Sign.ReadSign(x, y); SPlayer splayer = Players[e.Msg.whoAmI]; TSPlayer tplayer = TShock.Players[e.Msg.whoAmI]; if (id != -1) { Sign sign = SignManager.GetSign(id); bool messageSent = false; switch (splayer.GetState()) { case SettingState.Setting: if (sign.IsLocked()) { tplayer.SendMessage(Messages.alreadyProtected, Color.Red); messageSent = true; } else { sign.SetID(id); sign.SetPosition(x, y); sign.SetPassword(splayer.PasswordForSign); splayer.AddSignAccess(id); //unlock this sign for him tplayer.SendMessage(Messages.nowProtected, Color.Red); messageSent = true; } splayer.SetState(SettingState.None); break; case SettingState.Deleting: if (sign.IsLocked()) { if (tplayer.Group.HasPermission(Permissions.removesignprotection) || sign.CheckPassword(splayer.PasswordForSign)) { sign.SetPassword(""); SPlayer.RemoveSignAccessFromAll(id); //remove access to this sign tplayer.SendMessage(Messages.removed, Color.Red); messageSent = true; } else { tplayer.SendMessage(Messages.wrongPassword, Color.Red); messageSent = true; } } else { tplayer.SendMessage(Messages.notProtected, Color.Red); messageSent = true; } splayer.SetState(SettingState.None); break; case SettingState.UnLocking: if (sign.IsLocked()) { if (sign.CheckPassword(splayer.PasswordForSign)) { splayer.AddSignAccess(id); //unlock this sign for him tplayer.SendMessage(Messages.unlocked, Color.Red); messageSent = true; } else { tplayer.SendMessage(Messages.wrongPassword, Color.Red); messageSent = true; } } else { tplayer.SendMessage(Messages.notProtected, Color.Red); messageSent = true; } splayer.SetState(SettingState.None); break; case SettingState.WarpSetting: if ((sign.IsLocked() && (tplayer.Group.HasPermission(Permissions.editallsigns) || splayer.CanEditSign(id))) || !sign.IsLocked()) { sign.SetWarp(splayer.WarpForSign); tplayer.SendMessage(string.Format(Messages.warpTo, splayer.WarpForSign), Color.Plum); messageSent = true; } else { tplayer.SendMessage(Messages.isProtected, Color.Red); messageSent = true; } splayer.SetState(SettingState.None); break; case SettingState.DeletingWarp: if (sign.IsWarping()) { if ((sign.IsLocked() && (tplayer.Group.HasPermission(Permissions.editallsigns) || splayer.CanEditSign(id))) || !sign.IsLocked()) { sign.SetWarp(""); tplayer.SendMessage(Messages.notWarping, Color.Red); messageSent = true; } else { tplayer.SendMessage(Messages.noEdit, Color.Red); messageSent = true; } } else { tplayer.SendMessage(Messages.noWarp, Color.Red); messageSent = true; } splayer.SetState(SettingState.None); break; } if (!messageSent) { if (sign.IsLocked()) { if (tplayer.Group.HasPermission(Permissions.editallsigns) || splayer.CanEditSign(id)) { tplayer.SendMessage(Messages.editable, Color.YellowGreen); } else { tplayer.SendMessage(Messages.notEditable, Color.Yellow); if (tplayer.Group.HasPermission(Permissions.canunlocksign)) { tplayer.SendMessage(Messages.password, Color.Yellow); } } } else { tplayer.SendMessage(Messages.notProtected, Color.Yellow); } } if (sign.IsWarping()) { var warp = TShock.Warps.FindWarp(sign.GetWarp()); if (warp.WarpName != null) { tplayer.Teleport((int)warp.WarpPos.X, (int)warp.WarpPos.Y); tplayer.SendMessage(string.Format(Messages.teleported, warp.WarpName), Color.Blue); } else { tplayer.SendMessage(Messages.wrongWarp, Color.Red); } } } if (splayer.GetState() != SettingState.None) { //if player is still setting something - end his setting splayer.SetState(SettingState.None); } } break; case PacketTypes.SignNew: //editing sign if (!e.Handled) { using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) { var reader = new BinaryReader(data); var signId = reader.ReadInt16(); var x = reader.ReadInt32(); var y = reader.ReadInt32(); reader.Close(); //FIXME: hacked clients can theoreticaly bypass it ( seems like it checks by id only ) - needs testing var id = Terraria.Sign.ReadSign(x, y); var splayer = Players[e.Msg.whoAmI]; var tplayer = TShock.Players[e.Msg.whoAmI]; if (id != -1) { //FIXME: get sign by x and y to prevent that bug var sign = SignManager.GetSign(id); if (sign.IsLocked()) { if (!tplayer.Group.HasPermission(Permissions.editallsigns) && !splayer.CanEditSign(id)) //if player doesnt have permission, then break and message { tplayer.SendMessage(Messages.stopEdit, Color.IndianRed); if (tplayer.Group.HasPermission(Permissions.canunlocksign)) { tplayer.SendMessage(Messages.password, Color.IndianRed); } e.Handled = true; tplayer.SendData(PacketTypes.SignNew, "", id); return; } } } else { //there is no sign so stop editing - little fixy .) tplayer.SendMessage(Messages.wrongtile, Color.IndianRed); tplayer.SendData(PacketTypes.SignNew, "", id); e.Handled = true; return; } } } break; case PacketTypes.TileKill: case PacketTypes.Tile: using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) { var reader = new BinaryReader(data); if (e.MsgID == PacketTypes.Tile) { var type = reader.ReadByte(); if (!(type == 0 || type == 4)) { return; } } var x = reader.ReadInt32(); var y = reader.ReadInt32(); reader.Close(); var id = Terraria.Sign.ReadSign(x, y); if (id != -1) //if have found sign { //FIXME: get sign by x and y var sign = SignManager.GetSign(id); if (sign.IsLocked()) //if locked stop removing { var tplayer = TShock.Players[e.Msg.whoAmI]; tplayer.SendMessage(Messages.isProtected, Color.Red); //display more verbose info to player who has permission to remove protection on this chest if (tplayer.Group.HasPermission(Permissions.removesignprotection) || tplayer.Group.HasPermission(Permissions.protectsign)) { tplayer.SendMessage(Messages.removeSign, Color.Red); } //and stop tplayer.SendTileSquare(x, y); e.Handled = true; return; } //reset sign to remove all ponys in it cause the sign will get removed and we dont want that another sign get protected if placed in same place sign.Reset(); } //TODO: protect the 2 tiles on which is locked sign placed to prevent auto remove (checking x+-1 and y+-1 of tile for sign) } break; } } catch (Exception ex) { Console.WriteLine(ex); } }
private static void Set(CommandArgs args) { if (SignControl.Players[args.Player.Index].GetState() == SettingState.Setting) { SignControl.Players[args.Player.Index].PasswordForSign = ""; SignControl.Players[args.Player.Index].SetState(SettingState.None); args.Player.SendMessage(Messages.stopSelecting, Color.BlueViolet); } else { if (args.Parameters.Count < 1) { args.Player.SendMessage(Messages.enterPassword, Color.Red); return; } if ((args.Parameters.Count == 3 || args.Parameters.Count == 4) && args.Parameters[0].ToUpper() == "REGION") { //sets password for all signs in region if (!args.Player.Group.HasPermission(Permissions.protectallsigns)) { args.Player.SendMessage(Messages.noPermissionRegionProtect, Color.Red); return; } if (args.Parameters.Count == 4 && args.Parameters[3].ToUpper() != "TRUE" && args.Parameters[3].ToUpper() != "FALSE") { args.Player.SendMessage(Messages.wrongBool, Color.Red); return; } var region = TShock.Regions.GetRegionByName(args.Parameters[1]); if (region == null) { args.Player.SendMessage(Messages.noRegion, Color.Red); return; } if (!region.HasPermissionToBuildInRegion(args.Player)) { args.Player.SendMessage(Messages.noRegionPermission, Color.Red); return; } for (int l = 0; l < Terraria.Sign.maxSigns; l++) { if (Terraria.Main.sign[l] != null) { if (region.InArea(new Rectangle(Terraria.Main.sign[l].x, Terraria.Main.sign[l].y, 0, 0))) { var sign = SignManager.GetSign(l); var vasnull = false; if (sign == null) { sign = new Sign(); vasnull = true; } if (args.Parameters.Count == 4) { if (args.Parameters[3].ToUpper() == "FALSE" && sign.IsLocked()) { //if already protected skip it continue; } } sign.SetID(l); sign.SetPassword(args.Parameters[2]); sign.SetPosition(Terraria.Main.sign[l].x, Terraria.Main.sign[l].y); if (vasnull) SignManager.SetSign(l, sign); SignControl.Players[args.Player.Index].AddSignAccess(l); } } } args.Player.SendMessage(string.Format(Messages.regionLocked, region.Name), Color.BlueViolet); } else if (args.Parameters.Count > 1) { args.Player.SendMessage(Messages.tooManyParams, Color.Red); return; } else { //normal selecting SignControl.Players[args.Player.Index].PasswordForSign = args.Parameters[0]; SignControl.Players[args.Player.Index].SetState(SettingState.Setting); args.Player.SendMessage(string.Format(Messages.openSignTo, Messages.protect), Color.BlueViolet); } } }