public static int AddSign(PSSign sign) { try { if (Utils.TryGetSign(sign.X, sign.Y, out var temp)) { return(-1); } using (RunSQL($"INSERT INTO PowerfulSign (Owner,Friends,X,Y,Text,CanEdit,WorldID) VALUES (@0,@1,@2,@3,@4,@5,@6)", new object[] { sign.Owner, string.Join(",", sign.Friends), sign.X, sign.Y, sign.Text ?? "", sign.CanEdit ? 0 : 1, Main.worldID })) { } using (var reader = RunSQL($"SELECT MAX(SignID) FROM PowerfulSign;")) { reader.Read(); sign.ID = reader.Get <int>("MAX(SignID)"); PSPlugin.SignList.Add(sign); return(sign.ID); } } catch (Exception ex) { TShock.Log.ConsoleError(ex.InnerException == null ? ex.Message : ex.InnerException.Message); return(-1); } }
public static void DelSign(PSSign sign) { try { RunSQL($"DELETE FROM PowerfulSign WHERE SignID={sign.ID};"); PSPlugin.SignList.Remove(sign); } catch { } }
public static void BuyItem(this TSPlayer plr, UserAccount owner, PSSign sign, Item item, int stack, int cost) { if (sign.ChestID != -1) { if (sign.Shop.UnLimit) { if (plr.TakeMoney(cost) && UEF.MoneyUp(owner.Name, cost)) { plr.SendSuccessMessage($"[C/66D093:<PowerfulSign>] 成功购买 {stack} 个 {item.Name}, 花费 {cost} {PSPlugin.Config.MoneyName}."); plr.GiveItemEX(item.type, stack, item.prefix); } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 发生错误."); } } else { if (sign.Inventory >= stack) { if (plr.Balance() >= cost) { if (plr.IsInventoryAviliable(item, stack)) { if (sign.DelItemFromChest(item, stack) && plr.TakeMoney(cost) && UEF.MoneyUp(owner.Name, cost)) { plr.SendSuccessMessage($"[C/66D093:<PowerfulSign>] 成功购买 {stack} 个 {item.Name}, 花费 {cost} {PSPlugin.Config.MoneyName}."); plr.GiveItemEX(item.type, stack, item.prefix); } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 发生错误."); } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 背包空间不足, 无法装下 {stack} 个 {item.Name}."); } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 你的余额不足. 当前剩余 {plr.Balance()}."); } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 商店库存不足, 无法购买. 当前剩余: {sign.Inventory}."); } } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 未发现此商店的附属储存空间."); } }
public static void SendSignData(this TSPlayer plr, PSSign sign) { var psp = plr.PSP(); if (psp.LastSignIndex > 998) { psp.LastSignIndex = -1; } psp.LastSignIndex++; plr.SendSignDataDirect(sign, sign == psp.VisitingSign, psp.LastSignIndex); }
public static bool TryGetSignByGuess(int x, int y, out PSSign sign) { sign = PSPlugin.SignList.FirstOrDefault(s => new Rectangle(s.X, s.Y, 2, 2).Contains(x, y)); if (sign == null) { return(false); } else { return(true); } }
public static void SellItem(this TSPlayer plr, UserAccount owner, PSSign sign, Item item, int stack, int cost) { if (sign.ChestID != -1) { if (sign.Shop.UnLimit) { if (plr.DelItemFromInventory(item, stack) && plr.GiveMoney(cost)) { plr.SendSuccessMessage($"[C/66D093:<PowerfulSign>] 成功出售 {stack} 个 {item.Name}, 获得 {cost} {PSPlugin.Config.MoneyName}."); } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 发生错误."); } } else { if (sign.AviliableSlot >= stack) { if (UEF.Balance(owner.Name) >= cost) { if (plr.ItemNumInInventory(item.type, item.prefix) >= stack) { if (sign.AddItemToChest(item, stack) && plr.DelItemFromInventory(item, stack) && plr.GiveMoney(cost) && UEF.MoneyDown(owner.Name, cost)) { plr.SendSuccessMessage($"[C/66D093:<PowerfulSign>] 成功出售 {stack} 个 {item.Name}, 获得 {cost} {PSPlugin.Config.MoneyName}."); } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 发生错误."); } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 未在你的背包中发现足够的 {item.Name}. 已找到 {plr.ItemNumInInventory(item.type, item.prefix)} 个."); } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 卖家余额不足以支付此次交易."); } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 商店储存空间不足, 无法装下 {stack} 个 {item.Name}. 当前剩余空间 {sign.AviliableSlot}."); } } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 未发现此商店的附属储存空间."); } }
public static bool TryGetSign(int x, int y, out PSSign sign) { sign = PSPlugin.SignList.FirstOrDefault(s => s.X == x && s.Y == y); if (sign == null) { return(false); } else { return(true); } }
public static void UpdateSign(PSSign sign) { try { RunSQL($"UPDATE PowerfulSign SET Text=@0,Friends=@1,CanEdit=@2 Owner=@3 WHERE SignID='{sign.ID}';", new object[] { sign.Text ?? "", string.Join(",", sign.Friends), sign.CanEdit ? 0 : 1, sign.Owner }); } catch (Exception ex) { TShock.Log.ConsoleError(ex.InnerException == null ? ex.Message : ex.InnerException.Message); } }
/// <summary> /// 表示是否为批量商店购买文本 /// </summary> /// <param name="text"></param> /// <param name="plr"></param> /// <param name="sign"></param> /// <returns>true为是, false为别的文本.</returns> public static bool CheckShopText(string text, TSPlayer plr, PSSign sign) { try { if (text.Contains("\n")) { var lines = text.Split("\n"); if (lines[0].StartsWith("[") && lines[0].EndsWith("]")) { var maintype = lines[0].SearchString("[", "]").ToLower(); if (maintype == "customer") { if (!text.StartsWith("[Customer]\n请勿修改所有已存在文本, 直接输入要购买/出售的数量.\n")) { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 购买/出售格式无效, 请勿随意改动原有文本."); plr.SendSignDataVisiting(sign); return(true); } if (int.TryParse(lines[2], out int num) && num > 0) { var owner = sign.Account; var cost = sign.Shop.Price * num; var item = sign.Shop.Item; var stack = sign.Shop.Stack * num; if (sign.Shop.Type == PSSign_Shop.SELL) { plr.BuyItem(owner, sign, item, stack, cost); //卖家卖就是玩家买 } else { plr.SellItem(owner, sign, item, stack, cost); } plr.SendShopText(sign); } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 购买/出售数量无效, 请输入大于0的正整数."); } return(true); } } } } catch (Exception ex) { TShock.Log.ConsoleError(ex.Message); } return(false); }
public void UseCommandSign(PSSign sign) { if (Player.ContainsData($"PSCommandCoolDown_{sign.ID}")) { var time = (DateTime.Now - Player.GetData <DateTime>($"PSCommandCoolDown_{sign.ID}")).TotalMilliseconds / 1000.0; if (time > sign.Command.CoolDown) { Player.SendCombatText($"命令标牌尚未冷却. 剩余 {sign.Command.CoolDown - time:0.00} 秒.", Color.White); return; } else { Player.RemoveData($"PSCommandCoolDown_{sign.ID}"); } } else { Player.SetData($"PSCommandCoolDown_{sign.ID}", DateTime.Now); return; } if (sign.Command.Cost != 0) { if (UnifiedEconomyFramework.UEF.Balance(Player.Name) < sign.Command.Cost) { Player.SendCombatText($"你的余额不足以支付此命令标牌使用费用.", Color.White); return; } else { UnifiedEconomyFramework.UEF.MoneyDown(Player.Name, sign.Command.Cost); } } var group = Player.Group; if (sign.Command.IgnorePermissions) { Player.Group = new SuperAdminGroup(); } sign.Command.Commands.ForEach(c => { Commands.HandleCommand(Player, c.Replace("{name}", Player.Name)); }); Player.Group = group; }
public static void SendSignDataDirect(this TSPlayer plr, PSSign sign, bool open, int index) { try { var psp = plr.PSP(); if (index == 0) { psp.LastSignIndex = 0; } if (open) { psp.VisitingSign = sign; NetMessage.PlayNetSound(new NetMessage.NetSoundInfo(plr.TPlayer.position, 122, -1, 0.62f), plr.Index); } if (Netplay.Clients[plr.Index].IsConnected()) { plr.SendRawData(new RawDataBuilder(PacketTypes.SignNew).PackInt16((short)index).PackInt16((short)sign.X).PackInt16((short)sign.Y).PackString(open ? sign.Text : sign.PromptText).PackByte((byte)plr.Index).PackByte(new BitsByte(!open)).GetByteData()); } } catch (Exception ex) { TShock.Log.Error(ex.Message); } }
async void Loop() { await Task.Run(() => { int autorefreshCount = 0; int errorCount = 0; Dictionary <int, int> combatCount = new Dictionary <int, int>(); while (Player.Active) { try { var position = Player.TPlayer.position; var combatrect = new Rectangle((int)(position.X / 16 - PSPlugin.Config.CombatTextRange), (int)(position.Y / 16 - PSPlugin.Config.CombatTextRange), 2 + PSPlugin.Config.CombatTextRange * 2, 2 + PSPlugin.Config.CombatTextRange * 2); if (VisitingSign != null && !new Rectangle(VisitingSign.X, VisitingSign.Y, 2, 2).Intersects(new Rectangle((int)(position.X / 16 - 5), (int)(position.Y / 16 - 5), 2 + PSPlugin.Config.CombatTextRange * 12, 12))) { VisitingSign = null; //超出范围则未在编辑标牌. } PSPlugin.SignList.Where(s => combatrect.Intersects(new Rectangle(s.X, s.Y, 2, 2))).ForEach(s => { if (!combatCount.ContainsKey(s.ID)) { Player.SendCombatText(s.CombatText, s.Color, s.X, s.Y); combatCount.Add(s.ID, 0); } if (s.Type == PSSign.Types.Command && s.Command.Type == 1) { UseCommandSign(s); } }); if (autorefreshCount >= PSPlugin.Config.AutoRefreshLevel && Player.Active) { Player.SendSignDataInCircle(PSPlugin.Config.RefreshRadius); autorefreshCount = 0; } else { autorefreshCount++; } if (errorCount >= 4) { PSPlugin.SignList.Where(s => s.Owner == Account.ID && s.Error).ForEach(s => Player.SendCombatText($"<PowerfulSign>\n标牌无效", Color.Red, s.X, s.Y)); errorCount = 0; } else { autorefreshCount++; } foreach (var item in combatCount.ToList()) { if (combatCount[item.Key] >= PSPlugin.Config.CombatTextSendLevel) { combatCount.Remove(item.Key); } else { combatCount[item.Key]++; } } if (_WannaTrade != null) { if (TradeTimer < 10) { TradeTimer++; } else { Player.SendInfoMessage($"[C/66D093:<PowerfulSign>] 购买/出售请求已超时."); _WannaTrade = null; TradeTimer = 0; } } Task.Delay(500).Wait(); } catch (Exception ex) { TShock.Log.ConsoleError(ex.Message); } } }); }
public static void OnGetData(GetDataEventArgs args) { using (MemoryStream r = new MemoryStream(args.Msg.readBuffer, args.Index, args.Length - 1)) { using (var reader = new BinaryReader(r)) { var plr = TShock.Players[args.Msg.whoAmI] ?? new TSPlayer(-1); var psp = plr.GetData <PSPlayer>("PSPlayer"); var userID = plr.AccountEX().ID; switch (args.MsgID) { case PacketTypes.SignRead: args.Handled = true; var x = reader.ReadInt16(); var y = reader.ReadInt16(); if (Utils.TryGetSign(x, y, out var sign)) { switch (sign.Type) { case PSSign.Types.Normal: if (sign.Owner != userID && sign.Owner != -1 && !sign.CanEdit && !sign.Friends.Contains(userID)) { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 你没有编辑此标牌的权限."); } else { plr.SendSignDataVisiting(sign); } break; case PSSign.Types.Shop: if (sign.Owner != userID) { if (sign.Error) { plr.SendInfoMessage("[C/66D093:<PowerfulSign>] 此标牌商店暂时无法使用."); } else { if (sign.Shop.CanBuySet) { plr.SendShopText(sign); } else { if (psp.WannaTrade == null) { plr.SendInfoMessage($"[C/66D093:<PowerfulSign>] 确定要{(sign.Shop.Type == PSSign_Shop.SELL ? "购买" : "出售")} {sign.Shop.Stack} 个 {sign.Shop.Item.Name} ? 你将{(sign.Shop.Type == PSSign_Shop.SELL ? "失去" : "获得")} {sign.Shop.Price} {PSPlugin.Config.MoneyName}.\n请在5秒内再次点击此标牌来确认{(sign.Shop.Type == PSSign_Shop.SELL ? "购买" : "出售")}."); psp.WannaTrade = sign; } else { var tempowner = TShock.UserAccounts.GetUserAccountByID(sign.Owner) ?? new TShockAPI.DB.UserAccount(); if (sign.Shop.Type == PSSign_Shop.SELL) { plr.BuyItem(tempowner, sign, sign.Shop.Item, sign.Shop.Stack, sign.Shop.Price); //卖家卖就是玩家买 } else { plr.SellItem(tempowner, sign, sign.Shop.Item, sign.Shop.Stack, sign.Shop.Price); } psp.WannaTrade = null; } } } } else { plr.SendSignDataVisiting(sign); } break; case PSSign.Types.Command: if (sign.Owner != userID) { if (sign.Command.Type == 0 || sign.Command.Type == 2) { psp.UseCommandSign(sign); } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 你没有编辑此标牌的权限."); } } else { plr.SendSignDataVisiting(sign); } break; } } else { var tempSign = new PSSign(userID, new List <int>(), x, y, ""); DB.AddSign(tempSign); plr.SendSignDataVisiting(tempSign); } break; case PacketTypes.SignNew: args.Handled = true; reader.ReadInt16(); x = reader.ReadInt16(); y = reader.ReadInt16(); var text = reader.ReadString(); var owner = reader.ReadInt16(); if (Utils.TryGetSign(x, y, out sign) && !CheckShopText(text, plr, sign)) { psp.VisitingSign = null; if (sign.Owner == -1) { sign.Owner = userID; sign.Update(); } if (sign.Text != text) { if (sign.Owner == userID || sign.Owner == -1 || sign.Friends.Contains(userID) || plr.HasPermission("ps.admin.edit")) { sign.Text = text; sign.Update(); psp.VisitingSign = null; plr.SendSignDataVisiting(sign); //编辑者要多发一次来关掉牌子 if (sign.ProcessText()) { sign.Owner = plr.AccountEX().ID; plr.SendSuccessMessage("[C/66D093:<PowerfulSign>] 已成功创建特殊标牌."); } else { plr.SendSuccessMessage("[C/66D093:<PowerfulSign>] 已更新标牌文本."); } } else { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 你没有编辑此标牌的权限."); } } else { } } else if (sign == null) { var tempSign = new PSSign(userID, new List <int>(), x, y, text); DB.AddSign(tempSign); plr.SendSignDataVisiting(sign); } break; case PacketTypes.PlaceObject: x = reader.ReadInt16(); y = reader.ReadInt16(); var type = reader.ReadInt16(); if (Main.tileSign[type] && !Utils.TryGetSign(x, y, out sign)) { var tempSign = new PSSign(userID, new List <int>(), x, y, ""); DB.AddSign(tempSign); plr.SendSignData(tempSign); } break; case PacketTypes.ChestGetContents: x = reader.ReadInt16(); y = reader.ReadInt16(); if (Utils.TryGetSign(x - 2, y, out sign)) { if (sign.Owner != userID && sign.Type == PSSign.Types.Shop && !plr.HasPermission("ps.admin.open")) { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 此箱子已被作为标牌商店容器, 无法打开."); args.Handled = true; } } break; case PacketTypes.PlaceChest: var status = reader.ReadByte(); x = reader.ReadInt16(); y = reader.ReadInt16(); var chestID = Utils.FindChestByGuessing(x, y); if (chestID != -1 && Utils.TryGetSign(Main.chest[chestID].x - 2, Main.chest[chestID].y, out sign)) { if (status == 1) { if (sign.Owner != userID && sign.Type == PSSign.Types.Shop && !plr.HasPermission("ps.admin.destroy")) { plr.SendErrorMessage($"[C/66D093:<PowerfulSign>] 此箱子已被作为标牌商店容器, 无法摧毁."); WorldGen.SquareTileFrame(x, y); args.Handled = true; } else { sign.Error = true; } } else if (status == 0) { sign.Error = false; plr.SendSuccessMessage($"[C/66D093:<PowerfulSign>] 已为标牌商店放置容器."); } } break; } } } }
public static void SendShopText(this TSPlayer plr, PSSign sign) { var text = $"[Customer]\n请勿修改所有已存在文本, 直接输入要购买/出售的数量.\n"; plr.SendRawData(new RawDataBuilder(PacketTypes.SignNew).PackInt16((short)0).PackInt16((short)sign.X).PackInt16((short)sign.Y).PackString(text).PackByte((byte)plr.Index).PackByte(new BitsByte(false)).GetByteData()); }
public static void SendSignDataVisiting(this TSPlayer plr, PSSign sign) => plr.SendSignDataDirect(sign, true, 0);