ModernUO/Projects/Scripts/Commands/Batch.cs
Kamron Batman 179cb50557 Updates Packets & Randomizer (#43)
* Fixes a bug with the main loop. Removes unnecessary optimizations for RDRand.

* WIP - Rewriting packets.

* Cleanup and updates README

* Converts more packets

* Fixes header

* Converts Effects packets.

* Forgot the send command

* Adds the start of containers packets.

* Adds message packets with caching

* Extends the send methods

* Starts to add Acquire methods

* Converted the packets

* Cleanup

* Cleanup

* Adds more packets

* Adds more packets

* Fixes clearing arrays from pool. Adds Mobile Incoming

* Converts more packets.

* Moves more packets

* Moves more packets

* Test compression

* Merges

* Migrating to an idiomatic syntax that also supports compression, and proxying.

* Optimize the stack alloc. Changes attributes

* Converted container packets

* Visual Studio doesn't auto save files. I am still getting used to subpar IDEs.

* Adds static packet caching. Will profile later. Converts more packets

* Fixes packets and changes how compression is configured

* WIP - Adds basics for Gumps. Not finished though.

* Fix file

* Fixes formatting

* Changed SpanWriter to be more idiomatic.

* Fixes Span vs RawSpan and missing stackallocs

* Converts over some more gumps

* WIP - Deletes 32bit support.

* Drops RDRand32 support.

* Fixes gump compilation

* Converting gump components

* Removes old huffman compression function

* Revert signature for backwards compatibility

* WIP - Converting more gump components

* Creates ArraySet for the strings. Updates AppendTo to reference that.

* Converts the maining gump components

* Cleans up gump components

* Cleans up directives

* Cleans up ArraySet and moves it. Adds null-coalescing-assignment

* Cleanup, Target Packets, and C# 8 changes.

* Removed OPL Packet

* World packets

* Fixing packet uses

* Cleans up code. Fixes packet uses in various places.

* More cleanup for packets

* Code cleanup

* Converts more packet uses and cleans up more code

* More code cleanup

* Finishes fixing the packets in Item

* Updates secure trade packets

* Updates core and gets it to compile.

* Moved packets to scripts. Fixed account handler use of packets

* Code cleanup

* Updates chat packets

* Code cleanuo

* Adds party packets, but need to implement them.

* Party packets WIP

* Finishes party packets

* Rearrange movement namespaces and classes

* Finishes plant packets

* Code Formatting

* Fixes moving effects

* Code cleanup, eliminates equipinfo

* Adds more packets. Fixes bugs with various packets.

* Finishes mahjon packets

* Fixes mahjong packet

* Code cleanup

* Finishes mahjong packets

* Adds Map packets

* Add multifacet maps and charts

* Cleans up some packets with UTF8

* Optimizes packets

* Cleans up more packets. Moves the MessageHelper

* Removes assistant support. Removes extended protocol. Incorporates MapUO packets as normal packets.

* Updates protocol extensions packet receiver

* Fixes a few bugs. Fixes a few more packets.

* Code cleanup and fixing more packets

* Fixes packet effects

* Cleaned up more code

* Buff Icon cleanup

* Removed unused constructors

* Code Cleanup. Adds BoatHS Packets

* Moves house files. Updates house foundation packets.

* Deployment cleanup

* Fixes:

* Code cleanup

* More code cleanup

* More code cleanup

* Cleaned up BaseHouse

* Enforces styling

* Converts foreach to linq where possible.

* Dont need that

* Goals/Readme updates

* Removes 32bit support at the highest level. Turns on HRT by default.

* Code cleanup. Fixes extended features packet.

* Fixes various bugs

* Code cleanup

* Code cleanup

* Code cleanup. Fixes gump X/Y assignment.

* Code cleanup using |= operator

* More code cleanup

* Cleanup

* Fixes spacing issues. Thanks Visual Studio. You suck.

* Compiler error

* Fixes NPE from RunUO 2.7

* Renames ScriptCompiler to AssemblyHandler. Fixes packets. Updates README

* Fixes more packets. Stupid trailing nulls.

* Fixes various bugs.

* Fixes for gumps

* Fixes more gump stuff. Going to split it out later since it is getting insane

* Recoded the gump writing

* WIP

* *Added output path of scripts project to dev branch
*Activated debugging in code
2019-11-11 12:40:16 +01:00

417 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using Server.Commands.Generic;
using Server.Gumps;
using Server.Network;
namespace Server.Commands
{
public class Batch : BaseCommand
{
public Batch()
{
Commands = new[] { "Batch" };
ListOptimized = true;
}
public BaseCommandImplementor Scope{ get; set; }
public string Condition{ get; set; } = "";
public List<BatchCommand> BatchCommands{ get; } = new List<BatchCommand>();
public override void ExecuteList(CommandEventArgs e, List<object> list)
{
if (list.Count == 0)
{
LogFailure("Nothing was found to use this command on.");
return;
}
try
{
BaseCommand[] commands = new BaseCommand[BatchCommands.Count];
CommandEventArgs[] eventArgs = new CommandEventArgs[BatchCommands.Count];
for (int i = 0; i < BatchCommands.Count; ++i)
{
BatchCommand bc = BatchCommands[i];
bc.GetDetails(out string commandString, out string argString, out string[] args);
BaseCommand command = Scope.Commands[commandString];
commands[i] = command;
eventArgs[i] = new CommandEventArgs(e.Mobile, commandString, argString, args);
if (command == null)
{
e.Mobile.SendMessage(
"That is either an invalid command name or one that does not support this modifier: {0}.",
commandString);
return;
}
if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command: {0}.", commandString);
return;
}
if (!command.ValidateArgs(Scope, eventArgs[i])) return;
}
for (int i = 0; i < commands.Length; ++i)
{
BaseCommand command = commands[i];
BatchCommand bc = BatchCommands[i];
if (list.Count > 20)
CommandLogging.Enabled = false;
List<object> usedList;
if (Utility.InsensitiveCompare(bc.Object, "Current") == 0)
{
usedList = list;
}
else
{
Dictionary<Type, PropertyInfo[]> propertyChains = new Dictionary<Type, PropertyInfo[]>();
usedList = new List<object>(list.Count);
for (int j = 0; j < list.Count; ++j)
{
object obj = list[j];
if (obj == null)
continue;
Type type = obj.GetType();
string failReason = "";
if (!propertyChains.TryGetValue(type, out PropertyInfo[] chain))
propertyChains[type] = chain = Properties.GetPropertyInfoChain(e.Mobile, type, bc.Object,
PropertyAccess.Read, ref failReason);
if (chain == null)
continue;
PropertyInfo endProp = Properties.GetPropertyInfo(ref obj, chain, ref failReason);
if (endProp == null)
continue;
try
{
obj = endProp.GetValue(obj, null);
if (obj != null)
usedList.Add(obj);
}
catch
{
// ignored
}
}
}
command.ExecuteList(eventArgs[i], usedList);
CommandLogging.Enabled |= list.Count > 20;
command.Flush(e.Mobile, list.Count > 20);
}
}
catch (Exception ex)
{
e.Mobile.SendMessage(ex.Message);
}
}
public bool Run(Mobile from)
{
if (Scope == null)
{
from.SendMessage("You must select the batch command scope.");
return false;
}
if (Condition.Length > 0 && !Scope.SupportsConditionals)
{
from.SendMessage("This command scope does not support conditionals.");
return false;
}
if (Condition.Length > 0 && !Utility.InsensitiveStartsWith(Condition, "where"))
{
from.SendMessage("The condition field must start with \"where\".");
return false;
}
string[] args = CommandSystem.Split(Condition);
Scope.Process(from, this, args);
return true;
}
public static void Initialize()
{
CommandSystem.Register("Batch", AccessLevel.Counselor, Batch_OnCommand);
}
[Usage("Batch")]
[Description("Allows multiple commands to be run at the same time.")]
public static void Batch_OnCommand(CommandEventArgs e)
{
e.Mobile.SendGump(new BatchGump(e.Mobile, new Batch()));
}
}
public class BatchCommand
{
public BatchCommand(string command, string obj)
{
Command = command;
Object = obj;
}
public string Command{ get; set; }
public string Object{ get; set; }
public void GetDetails(out string command, out string argString, out string[] args)
{
int indexOf = Command.IndexOf(' ');
if (indexOf >= 0)
{
argString = Command.Substring(indexOf + 1);
command = Command.Substring(0, indexOf);
args = CommandSystem.Split(argString);
}
else
{
argString = "";
command = Command.ToLower();
args = new string[0];
}
}
}
public class BatchGump : BaseGridGump
{
private Batch m_Batch;
private Mobile m_From;
public BatchGump(Mobile from, Batch batch) : base(30, 30)
{
m_From = from;
m_Batch = batch;
Render();
}
public void Render()
{
AddNewPage();
/* Header */
AddEntryHeader(20);
AddEntryHtml(180, Center("Batch Commands"));
AddEntryHeader(20);
AddNewLine();
AddEntryHeader(9);
AddEntryLabel(191, "Run Batch");
AddEntryButton(20, ArrowRightID1, ArrowRightID2, GetButtonID(1, 0, 0), ArrowRightWidth, ArrowRightHeight);
AddNewLine();
AddBlankLine();
/* Scope */
AddEntryHeader(20);
AddEntryHtml(180, Center("Scope"));
AddEntryHeader(20);
AddNewLine();
AddEntryHeader(9);
AddEntryLabel(191, m_Batch.Scope == null ? "Select Scope" : m_Batch.Scope.Accessors[0]);
AddEntryButton(20, ArrowRightID1, ArrowRightID2, GetButtonID(1, 0, 1), ArrowRightWidth, ArrowRightHeight);
AddNewLine();
AddBlankLine();
/* Condition */
AddEntryHeader(20);
AddEntryHtml(180, Center("Condition"));
AddEntryHeader(20);
AddNewLine();
AddEntryHeader(9);
AddEntryText(202, 0, m_Batch.Condition);
AddEntryHeader(9);
AddNewLine();
AddBlankLine();
/* Commands */
AddEntryHeader(20);
AddEntryHtml(180, Center("Commands"));
AddEntryHeader(20);
for (int i = 0; i < m_Batch.BatchCommands.Count; ++i)
{
BatchCommand bc = m_Batch.BatchCommands[i];
AddNewLine();
AddImageTiled(CurrentX, CurrentY, 9, 2, 0x24A8);
AddImageTiled(CurrentX, CurrentY + 2, 2, EntryHeight + OffsetSize + EntryHeight - 4, 0x24A8);
AddImageTiled(CurrentX, CurrentY + EntryHeight + OffsetSize + EntryHeight - 2, 9, 2, 0x24A8);
AddImageTiled(CurrentX + 3, CurrentY + 3, 6, EntryHeight + EntryHeight - 4 - OffsetSize, HeaderGumpID);
IncreaseX(9);
AddEntryText(202, 1 + i * 2, bc.Command);
AddEntryHeader(9, 2);
AddNewLine();
IncreaseX(9);
AddEntryText(202, 2 + i * 2, bc.Object);
}
AddNewLine();
AddEntryHeader(9);
AddEntryLabel(191, "Add New Command");
AddEntryButton(20, ArrowRightID1, ArrowRightID2, GetButtonID(1, 0, 2), ArrowRightWidth, ArrowRightHeight);
FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (!SplitButtonID(info.ButtonID, 1, out int type, out int index))
return;
TextRelay entry = info.GetTextEntry(0);
if (entry != null)
m_Batch.Condition = entry.Text;
for (int i = m_Batch.BatchCommands.Count - 1; i >= 0; --i)
{
BatchCommand sc = m_Batch.BatchCommands[i];
entry = info.GetTextEntry(1 + i * 2);
if (entry != null)
sc.Command = entry.Text;
entry = info.GetTextEntry(2 + i * 2);
if (entry != null)
sc.Object = entry.Text;
if (sc.Command.Length == 0 && sc.Object.Length == 0)
m_Batch.BatchCommands.RemoveAt(i);
}
switch (type)
{
case 0: // main
{
switch (index)
{
case 0: // run
{
m_Batch.Run(m_From);
break;
}
case 1: // set scope
{
m_From.SendGump(new BatchScopeGump(m_From, m_Batch));
return;
}
case 2: // add command
{
m_Batch.BatchCommands.Add(new BatchCommand("", ""));
break;
}
}
break;
}
}
m_From.SendGump(new BatchGump(m_From, m_Batch));
}
}
public class BatchScopeGump : BaseGridGump
{
private Batch m_Batch;
private Mobile m_From;
public BatchScopeGump(Mobile from, Batch batch) : base(30, 30)
{
m_From = from;
m_Batch = batch;
Render();
}
public void Render()
{
AddNewPage();
/* Header */
AddEntryHeader(20);
AddEntryHtml(140, Center("Change Scope"));
AddEntryHeader(20);
/* Options */
for (int i = 0; i < BaseCommandImplementor.Implementors.Count; ++i)
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[i];
if (m_From.AccessLevel < impl.AccessLevel)
continue;
AddNewLine();
AddEntryLabel(20 + OffsetSize + 140, impl.Accessors[0]);
AddEntryButton(20, ArrowRightID1, ArrowRightID2, GetButtonID(1, 0, i), ArrowRightWidth, ArrowRightHeight);
}
FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (SplitButtonID(info.ButtonID, 1, out int type, out int index))
switch (type)
{
case 0:
{
if (index < BaseCommandImplementor.Implementors.Count)
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[index];
if (m_From.AccessLevel >= impl.AccessLevel)
m_Batch.Scope = impl;
}
break;
}
}
m_From.SendGump(new BatchGump(m_From, m_Batch));
}
}
}