private static bool Prefix([CanBeNull] CommandDriver __instance, ITwitchMessage twitchMessage) { if (__instance == null) { return(true); } if (!TkSettings.StoreState) { return(false); } Viewer viewer = Viewers.GetViewer(twitchMessage.Username); ITwitchMessage message = twitchMessage; if (!__instance.command.defName.Equals("Buy")) { message = twitchMessage.WithMessage($"!{CommandDefOf.Buy.command} {twitchMessage.Message.Substring(1)}"); } if (message !.Message.Split(' ').Length < 2) { return(false); } Purchase_Handler.ResolvePurchase(viewer, message); return(false); }
public override bool IsPossible(string message, Viewer viewer, bool separateChannel = false) { if (!Purchase_Handler.CheckIfViewerHasEnoughCoins(viewer, this.storeIncident.cost, separateChannel)) { return(false); } if (Current.Game.GetComponent <GameComponentPawns>().HasUserBeenNamed(viewer.username)) { Toolkit.client.SendMessage($"@{viewer.username} you are already in the colony.", separateChannel); return(false); } this.separateChannel = separateChannel; this.viewer = viewer; IIncidentTarget target = Helper.AnyPlayerMap; parms = StorytellerUtility.DefaultParmsNow(IncidentCategoryDefOf.Misc, target); map = (Map)parms.target; bool cell = CellFinder.TryFindRandomEdgeCellWith((IntVec3 c) => map.reachability.CanReachColony(c) && !c.Fogged(map), map, CellFinder.EdgeRoadChance_Neutral, out loc); if (!cell) { return(false); } return(true); }
public override void RunCommand(TwitchIRCMessage message) { if (message.Message.Split(' ').Count() < 2) { return; } Purchase_Handler.ResolvePurchase(message.Viewer, message, CommandsHandler.SendToChatroom(message)); }
public override void RunCommand(IRCMessage message) { Viewer viewer = Viewers.GetViewer(message.User); if (message.Message.Split(' ').Count() < 2) { return; } Purchase_Handler.ResolvePurchase(viewer, message, CommandsHandler.SendToChatroom(message)); }
public override void RunCommand(ITwitchMessage twitchMessage) { Viewer viewer = Viewers.GetViewer(twitchMessage.Username); if (twitchMessage.Message.Split(' ').Count() < 2) { return; } Purchase_Handler.ResolvePurchase(viewer, twitchMessage); }
private static bool ResolvePurchaseSimplePrefix( [NotNull] Viewer viewer, ITwitchMessage twitchMessage, [NotNull] StoreIncidentSimple incident, string formattedMessage ) { if (!Purchase_Handler.CheckIfViewerHasEnoughCoins(viewer, incident.cost)) { return(false); } if (Purchase_Handler.CheckIfKarmaTypeIsMaxed(incident, viewer.username)) { return(false); } if (!TryMakeIncident(incident, viewer, formattedMessage, out IncidentHelper inc)) { TkUtils.Logger.Warn(@$ "The incident " "{incident.defName}" " does not define an incident helper"); return(false); } if (!inc.IsPossible()) { MessageHelper.ReplyToUser(viewer.username, "TwitchToolkitEventNotPossible".Localize()); return(false); } viewer.Charge(incident); Current.Game.GetComponent <Coordinator>()?.QueueIncident(new IncidentProxy { SimpleIncident = inc }); Current.Game.GetComponent <Store_Component>()?.LogIncident(incident); Store_Logger.LogPurchase(viewer.username, twitchMessage.Message); if (!ToolkitSettings.PurchaseConfirmations) { return(false); } TwitchWrapper.SendChatMessage( Helper.ReplacePlaceholder("TwitchToolkitEventPurchaseConfirm".Localize(), viewer: viewer.username, first: incident.label.CapitalizeFirst()) ); return(false); }
private static bool IsOnCooldown(StoreIncidentVariables incident, [NotNull] Viewer viewer) { if (incident == StoreIncidentDefOf.Item) { return(Purchase_Handler.CheckIfCarePackageIsOnCooldown(viewer.username)); } if (incident != IncidentDefOf.Sanctuary && Purchase_Handler.CheckIfKarmaTypeIsMaxed(incident, viewer.username)) { return(true); } return(Purchase_Handler.CheckIfIncidentIsOnCooldown(incident, viewer.username)); }
private static bool ResolvePurchasePrefix([NotNull] Viewer viewer, [NotNull] ITwitchMessage twitchMessage) { if (Purchase_Handler.CheckIfViewerIsInVariableCommandList(viewer.username)) { return(false); } List <string> segments = CommandFilter.Parse(twitchMessage.Message).ToList(); var worker = ArgWorker.CreateInstance(segments); if (!worker.HasNext()) { return(false); } string query = segments.Skip(1).FirstOrFallback(""); if (TryProcessIncident(viewer, twitchMessage, query)) { return(false); } Helper.Log($"abr: {query} "); segments.Insert(1, "item"); if (segments.Count < 4) { segments.Add("1"); } if (!int.TryParse(segments[3], out int _)) { segments.Insert(3, "1"); } try { Purchase_Handler.ResolvePurchaseVariables(viewer, twitchMessage, StoreIncidentDefOf.Item, string.Join(" ", segments.ToArray())); } catch (Exception e) { TkUtils.Logger.Error("Could not resolve purchase", e); } return(false); }
private void TryQueueNextMessage() { if (SimpleIncident is VotingHelper) { return; } if (SimpleIncident != null) { Purchase_Handler.QueuePlayerMessage(SimpleIncident.Viewer, SimpleIncident.message); } if (VariablesIncident != null) { Purchase_Handler.QueuePlayerMessage(VariablesIncident.Viewer, VariablesIncident.message, VariablesIncident.storeIncident.variables); } }
private static bool TryProcessVariablesIncident(Viewer viewer, ITwitchMessage twitchMessage, string query) { if (!TryFindVariableIncident(query, out StoreIncidentVariables incidentVariables)) { return(false); } try { Purchase_Handler.ResolvePurchaseVariables(viewer, twitchMessage, incidentVariables, twitchMessage.Message); } catch (Exception e) { TkUtils.Logger.Error("Could not resolve purchase", e); } return(true); }
public static bool PointsWagerIsValid(string wager, Viewer viewer, ref int pointsWager, ref StoreIncidentVariables incident, bool separateChannel = false, int quantity = 1, int maxPrice = 25000) { try { if (!int.TryParse(wager, out checked (pointsWager))) { ViewerDidWrongSyntax(viewer.username, incident.syntax); return(false); } pointsWager = checked (pointsWager * quantity); } catch (OverflowException e) { Helper.Log(e.Message); TwitchWrapper.SendChatMessage($"@{viewer.username} points wager is invalid."); return(false); } if (incident.maxWager > 0 && incident.maxWager > incident.cost && pointsWager > incident.maxWager) { TwitchWrapper.SendChatMessage($"@{viewer.username} you cannot spend more than {incident.maxWager} coins on {incident.abbreviation.CapitalizeFirst()}"); return(false); } //|| (incident.minPointsToFire > 0 && pointsWager < incident.minPointsToFire) if (pointsWager < incident.cost || pointsWager < incident.minPointsToFire) { TwitchWrapper.SendChatMessage(Helper.ReplacePlaceholder( "TwitchToolkitMinPurchaseNotMet".Translate(), viewer: viewer.username, amount: pointsWager.ToString(), first: incident.cost.ToString() )); return(false); } if (!Purchase_Handler.CheckIfViewerHasEnoughCoins(viewer, pointsWager)) { return(false); } return(true); }
private static bool ResolvePurchaseVariablesPrefix( [NotNull] Viewer viewer, ITwitchMessage twitchMessage, [NotNull] StoreIncidentVariables incident, string formattedMessage ) { if (!Purchase_Handler.CheckIfViewerHasEnoughCoins(viewer, incident.cost) || IsOnCooldown(incident, viewer)) { return(false); } if (!TryMakeIncident(incident, viewer, formattedMessage, out IncidentHelperVariables inc)) { TkUtils.Logger.Warn(@$ "The incident " "{incident.defName}" " does not define an incident helper"); return(false); } Purchase_Handler.viewerNamesDoingVariableCommands.Add(viewer.username.ToLowerInvariant()); if (!inc.IsPossible(formattedMessage, viewer)) { Purchase_Handler.viewerNamesDoingVariableCommands.Remove(viewer.username.ToLowerInvariant()); return(false); } Store_Logger.LogPurchase(viewer.username, twitchMessage.Message); Current.Game.GetComponent <Coordinator>()?.QueueIncident(new IncidentProxy { VariablesIncident = inc }); Current.Game.GetComponent <Store_Component>()?.LogIncident(incident); return(false); }
public override void Tick() { try { if (_game == null || _mod == null) { return; } _mod.Tick(); var minutes = (int)(_game.Info.RealPlayTimeInteracting / 60f); double getTime = (double)Time.time / 60f; int time = Convert.ToInt32(Math.Truncate(getTime)); if (IncidentHelpers.Count > 0) { for (int i = 0; i < IncidentHelpers.Count; i++) { var incidentHelper = IncidentHelpers.Dequeue(); if (!(incidentHelper is VotingHelper)) { Purchase_Handler.QueuePlayerMessage(incidentHelper.Viewer, incidentHelper.message); } incidentHelper.TryExecute(); } Helper.playerMessages = new List <string>(); } if (IncidentHelperVariables.Count > 0) { for (int i = 0; i < IncidentHelperVariables.Count; i++) { var incidentHelper = IncidentHelperVariables.Dequeue(); Purchase_Handler.QueuePlayerMessage(incidentHelper.Viewer, incidentHelper.message, incidentHelper.storeIncident.variables); incidentHelper.TryExecute(); if (Purchase_Handler.viewerNamesDoingVariableCommands.Contains(incidentHelper.Viewer.username)) { Purchase_Handler.viewerNamesDoingVariableCommands.Remove(incidentHelper.Viewer.username); } } Helper.playerMessages = new List <string>(); } if (Incidents.Count > 0) { var incident = Incidents.Dequeue(); IncidentParms incidentParms = new IncidentParms(); incidentParms.target = Helper.AnyPlayerMap; incident.TryExecute(incidentParms); } if (FiringIncidents.Count > 0) { Helper.Log("Firing " + FiringIncidents.First().def.defName); var incident = FiringIncidents.Dequeue(); incident.def.Worker.TryExecute(incident.parms); } VoteHandler.CheckForQueuedVotes(); if (_lastCoinReward < 0) { _lastCoinReward = time; } else if (ToolkitSettings.EarningCoins && ((time - _lastCoinReward) >= ToolkitSettings.CoinInterval) && Viewers.jsonallviewers != null) { _lastCoinReward = time; Viewers.AwardViewersCoins(); } if (_lastMinute < 0) { _lastMinute = time; } else if (_lastMinute < time) { _lastMinute = time; Toolkit.JobManager.CheckAllJobs(); Viewers.RefreshViewers(); } } catch (Exception ex) { Helper.Log("Exception: " + ex.Message + ex.StackTrace); } }
public override void ParseCommand(IRCMessage msg) { Viewer viewer = Viewers.GetViewer(msg.User); GameComponentPawns component = Current.Game.GetComponent <GameComponentPawns>(); if (msg.Message.StartsWith("!mypawnskills") && Commands.AllowCommand(msg.Channel)) { if (!component.HasUserBeenNamed(viewer.username)) { Toolkit.client.SendMessage($"@{viewer.username} you are not in the colony.", true); return; } Pawn pawn = component.PawnAssignedToUser(viewer.username); string output = $"@{viewer.username} {pawn.Name.ToStringShort.CapitalizeFirst()}'s skill levels are "; List <SkillRecord> skills = pawn.skills.skills; for (int i = 0; i < skills.Count; i++) { output += $"{skills[i].def.LabelCap}: {skills[i].levelInt}"; if (i != skills.Count - 1) { output += ", "; } } Toolkit.client.SendMessage(output, true); } if (msg.Message.StartsWith("!mypawnstory") && Commands.AllowCommand(msg.Channel)) { if (!component.HasUserBeenNamed(viewer.username)) { Toolkit.client.SendMessage($"@{viewer.username} you are not in the colony.", true); return; } Pawn pawn = component.PawnAssignedToUser(viewer.username); string output = $"@{viewer.username} About {pawn.Name.ToStringShort.CapitalizeFirst()}: "; List <Backstory> backstories = pawn.story.AllBackstories.ToList(); for (int i = 0; i < backstories.Count; i++) { output += backstories[i].titleShort; if (i != backstories.Count - 1) { output += ", "; } } output += " | Traits: "; List <Trait> traits = pawn.story.traits.allTraits; for (int i = 0; i < traits.Count; i++) { output += traits[i].LabelCap; if (i != traits.Count - 1) { output += ", "; } } Toolkit.client.SendMessage(output, true); } if (msg.Message.StartsWith("!changepawnname") && Commands.AllowCommand(msg.Channel)) { string[] command = msg.Message.Split(' '); if (command.Length < 2) { return; } string newName = command[1]; if (newName == null || newName == "" || newName.Length > 16) { Toolkit.client.SendMessage($"@{viewer.username} your name can be up to 16 characters.", true); return; } if (!component.HasUserBeenNamed(viewer.username)) { Toolkit.client.SendMessage($"@{viewer.username} you are not in the colony.", Commands.SendToChatroom(msg.Channel)); return; } if (!Purchase_Handler.CheckIfViewerHasEnoughCoins(viewer, 500, true)) { return; } viewer.TakeViewerCoins(500); nameRequests.Add(viewer.username, newName); Toolkit.client.SendMessage($"@{ToolkitSettings.Channel} {viewer.username} has requested to be named {newName}, use !approvename @{viewer.username} or !declinename @{viewer.username}", false); } if (Viewer.IsModerator(viewer.username) || viewer.username == ToolkitSettings.Channel) { if (msg.Message.StartsWith("!unstickpeople")) { Purchase_Handler.viewerNamesDoingVariableCommands = new List <string>(); } if (msg.Message.StartsWith("!approvename")) { string[] command = msg.Message.Split(' '); if (command.Length < 2) { return; } string username = command[1].Replace("@", ""); if (username == null || username == "" || !nameRequests.ContainsKey(username)) { Toolkit.client.SendMessage($"@{viewer.username} invalid username", false); return; } if (!component.HasUserBeenNamed(username)) { return; } Pawn pawn = component.PawnAssignedToUser(username); NameTriple old = pawn.Name as NameTriple; pawn.Name = new NameTriple(old.First, nameRequests[username], old.Last); Toolkit.client.SendMessage($"@{viewer.username} approved request for name change from {old} to {pawn.Name}"); } if (msg.Message.StartsWith("!declinename")) { string[] command = msg.Message.Split(' '); if (command.Length < 2) { return; } string username = command[1].Replace("@", ""); if (username == null || username == "" || !nameRequests.ContainsKey(username)) { Toolkit.client.SendMessage($"@{viewer.username} invalid username", false); return; } if (!component.HasUserBeenNamed(username)) { return; } nameRequests.Remove(username); Toolkit.client.SendMessage($"@{viewer.username} declined name change request from {username}"); } } }
public override bool IsPossible(string message, Viewer viewer, bool separateChannel = false) { this.separateChannel = separateChannel; this.viewer = viewer; string[] command = message.Split(' '); if (command.Length < 4) { VariablesHelpers.ViewerDidWrongSyntax(viewer.username, storeIncident.syntax, separateChannel); return(false); } string itemKey = command[2].ToLower(); if (itemKey == null || itemKey == "") { VariablesHelpers.ViewerDidWrongSyntax(viewer.username, storeIncident.syntax, separateChannel); return(false); } IEnumerable <Store.Item> itemSearch = StoreInventory.items.Where(s => s.price > 0 && (s.abr == itemKey || s.defname.ToLower() == itemKey) ); if (itemSearch.Count() > 0) { item = itemSearch.ElementAt(0); } if (item == null || item.price < 1) { Toolkit.client.SendMessage($"@{viewer.username} item not found.", separateChannel); return(false); } string quantityKey = command[3]; if (quantityKey == null || quantityKey == "") { VariablesHelpers.ViewerDidWrongSyntax(viewer.username, storeIncident.syntax, separateChannel); return(false); } try { if (!int.TryParse(quantityKey, out checked (quantity))) { return(false); } price = checked (item.price * quantity); } catch (OverflowException e) { Log.Warning(e.Message); return(false); } if (quantity < 1 || price < 1) { VariablesHelpers.ViewerDidWrongSyntax(viewer.username, storeIncident.syntax, separateChannel); return(false); } if (!Purchase_Handler.CheckIfViewerHasEnoughCoins(viewer, price, separateChannel)) { return(false); } if (price < ToolkitSettings.MinimumPurchasePrice) { Toolkit.client.SendMessage(Helper.ReplacePlaceholder( "TwitchToolkitMinPurchaseNotMet".Translate(), viewer: viewer.username, amount: price.ToString(), first: ToolkitSettings.MinimumPurchasePrice.ToString() ), separateChannel); return(false); } return(true); }
public override bool IsPossible(string message, Viewer viewer, bool separateChannel = false) { this.separateChannel = separateChannel; this.Viewer = viewer; string[] command = message.Split(' '); if (command.Length < 4) { VariablesHelpers.ViewerDidWrongSyntax(viewer.username, storeIncident.syntax); return(false); } string itemKey = command[2].ToLower(); if (itemKey == null || itemKey == "") { VariablesHelpers.ViewerDidWrongSyntax(viewer.username, storeIncident.syntax); return(false); } IEnumerable <Store.Item> itemSearch = StoreInventory.items.Where(s => s.price > 0 && (s.abr == itemKey || s.defname.ToLower() == itemKey) ); if (itemSearch.Count() > 0) { item = itemSearch.ElementAt(0); } if (item == null || item.price < 1) { TwitchWrapper.SendChatMessage($"@{viewer.username} item not found."); return(false); } ThingDef itemThingDef = ThingDef.Named(item.defname); bool isResearched = true; ResearchProjectDef researchProject = null; Helper.Log("Checking researched"); if (itemThingDef.recipeMaker != null && itemThingDef.recipeMaker.researchPrerequisite != null && !itemThingDef.recipeMaker.researchPrerequisite.IsFinished) { Helper.Log("Recipe not researched"); isResearched = false; researchProject = itemThingDef.recipeMaker.researchPrerequisite; } else if (!itemThingDef.IsResearchFinished) { Helper.Log("Building not researched"); isResearched = false; researchProject = itemThingDef.researchPrerequisites.ElementAt(0); } if (BuyItemSettings.mustResearchFirst && !isResearched) { string output = $"@{viewer.username} {itemThingDef.LabelCap} has not been researched yet, must finish research project {researchProject.LabelCap} first."; TwitchWrapper.SendChatMessage(output); return(false); } string quantityKey = command[3]; if (quantityKey == null || quantityKey == "") { VariablesHelpers.ViewerDidWrongSyntax(viewer.username, storeIncident.syntax); return(false); } try { if (!int.TryParse(quantityKey, out checked (quantity))) { return(false); } price = checked (item.price * quantity); } catch (OverflowException e) { Helper.Log(e.Message); return(false); } if (quantity < 1 || price < 1) { VariablesHelpers.ViewerDidWrongSyntax(viewer.username, storeIncident.syntax); return(false); } if (!Purchase_Handler.CheckIfViewerHasEnoughCoins(viewer, price)) { return(false); } if (price < ToolkitSettings.MinimumPurchasePrice) { TwitchWrapper.SendChatMessage(Helper.ReplacePlaceholder( "TwitchToolkitMinPurchaseNotMet".Translate(), viewer: viewer.username, amount: price.ToString(), first: ToolkitSettings.MinimumPurchasePrice.ToString() )); return(false); } return(true); }
public override void ParseCommand(IRCMessage msg) { Viewer viewer = Viewers.GetViewer(msg.User); GameComponentPawns component = Current.Game.GetComponent <GameComponentPawns>(); if (msg.Message.StartsWith("!mypawnskills") && Commands.AllowCommand(msg)) { if (!component.HasUserBeenNamed(viewer.username)) { Toolkit.client.SendMessage($"@{viewer.username} you are not in the colony.", Commands.SendToChatroom(msg)); return; } Pawn pawn = component.PawnAssignedToUser(viewer.username); string output = $"@{viewer.username} {pawn.Name.ToStringShort.CapitalizeFirst()}'s skill levels are "; List <SkillRecord> skills = pawn.skills.skills; for (int i = 0; i < skills.Count; i++) { if (skills[i].TotallyDisabled) { output += $"{skills[i].def.LabelCap}: -"; } else { output += $"{skills[i].def.LabelCap}: {skills[i].levelInt}"; } if (skills[i].passion == Passion.Minor) { output += "+"; } if (skills[i].passion == Passion.Major) { output += "++"; } if (i != skills.Count - 1) { output += ", "; } } Toolkit.client.SendMessage(output, Commands.SendToChatroom(msg)); } if (msg.Message.StartsWith("!mypawnstory") && Commands.AllowCommand(msg)) { if (!component.HasUserBeenNamed(viewer.username)) { Toolkit.client.SendMessage($"@{viewer.username} you are not in the colony.", Commands.SendToChatroom(msg)); return; } Pawn pawn = component.PawnAssignedToUser(viewer.username); string output = $"@{viewer.username} About {pawn.Name.ToStringShort.CapitalizeFirst()}: "; List <Backstory> backstories = pawn.story.AllBackstories.ToList(); for (int i = 0; i < backstories.Count; i++) { output += backstories[i].title; if (i != backstories.Count - 1) { output += ", "; } } output += " | " + pawn.gender; StringBuilder stringBuilder = new StringBuilder(); WorkTags combinedDisabledWorkTags = pawn.story.CombinedDisabledWorkTags; if (combinedDisabledWorkTags == WorkTags.None) { stringBuilder.Append("(" + "NoneLower".Translate() + "), "); } else { List <WorkTags> list = WorkTagsFrom(combinedDisabledWorkTags).ToList <WorkTags>(); bool flag2 = true; foreach (WorkTags tags in list) { if (flag2) { stringBuilder.Append(tags.LabelTranslated().CapitalizeFirst()); } else { stringBuilder.Append(tags.LabelTranslated()); } stringBuilder.Append(", "); flag2 = false; } } string text = stringBuilder.ToString(); text = text.Substring(0, text.Length - 2); output += " | Incapable of: " + text; output += " | Traits: "; List <Trait> traits = pawn.story.traits.allTraits; for (int i = 0; i < traits.Count; i++) { output += traits[i].LabelCap; if (i != traits.Count - 1) { output += ", "; } } Toolkit.client.SendMessage(output, Commands.SendToChatroom(msg)); } if (msg.Message.StartsWith("!changepawnname") && Commands.AllowCommand(msg)) { string[] command = msg.Message.Split(' '); if (command.Length < 2) { return; } string newName = command[1]; if (newName == null || newName == "" || newName.Length > 16) { Toolkit.client.SendMessage($"@{viewer.username} your name can be up to 16 characters.", Commands.SendToChatroom(msg)); return; } if (!component.HasUserBeenNamed(viewer.username)) { Toolkit.client.SendMessage($"@{viewer.username} you are not in the colony.", Commands.SendToChatroom(msg)); return; } if (!Purchase_Handler.CheckIfViewerHasEnoughCoins(viewer, 500, true)) { return; } viewer.TakeViewerCoins(500); nameRequests.Add(viewer.username, newName); Toolkit.client.SendMessage($"@{ToolkitSettings.Channel} {viewer.username} has requested to be named {newName}, use !approvename @{viewer.username} or !declinename @{viewer.username}", false); } if (Viewer.IsModerator(viewer.username) || viewer.username == ToolkitSettings.Channel) { if (msg.Message.StartsWith("!unstickpeople")) { Purchase_Handler.viewerNamesDoingVariableCommands = new List <string>(); } if (msg.Message.StartsWith("!approvename")) { string[] command = msg.Message.Split(' '); if (command.Length < 2) { return; } string username = command[1].Replace("@", ""); if (username == null || username == "" || !nameRequests.ContainsKey(username)) { Toolkit.client.SendMessage($"@{viewer.username} invalid username", Commands.SendToChatroom(msg)); return; } if (!component.HasUserBeenNamed(username)) { return; } Pawn pawn = component.PawnAssignedToUser(username); NameTriple old = pawn.Name as NameTriple; pawn.Name = new NameTriple(old.First, nameRequests[username], old.Last); Toolkit.client.SendMessage($"@{viewer.username} approved request for name change from {old} to {pawn.Name}"); } if (msg.Message.StartsWith("!declinename")) { string[] command = msg.Message.Split(' '); if (command.Length < 2) { return; } string username = command[1].Replace("@", ""); if (username == null || username == "" || !nameRequests.ContainsKey(username)) { Toolkit.client.SendMessage($"@{viewer.username} invalid username", Commands.SendToChatroom(msg)); return; } if (!component.HasUserBeenNamed(username)) { return; } nameRequests.Remove(username); Toolkit.client.SendMessage($"@{viewer.username} declined name change request from {username}"); } } Store_Logger.LogString("Parsed pawn command"); }