mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Give access to AutoRespond matches inside scripts
Available as %match_u%, %match_1% and so on See #770 for initial suggestion See #772 for in-progress implementation
This commit is contained in:
parent
e4e1f0b9fa
commit
00112e4c6a
25 changed files with 129 additions and 69 deletions
|
|
@ -25,10 +25,11 @@ namespace MinecraftClient
|
||||||
/// <param name="tickHandler">Tick handler for waiting after some API calls</param>
|
/// <param name="tickHandler">Tick handler for waiting after some API calls</param>
|
||||||
/// <param name="lines">Lines of the script file to run</param>
|
/// <param name="lines">Lines of the script file to run</param>
|
||||||
/// <param name="args">Arguments to pass to the script</param>
|
/// <param name="args">Arguments to pass to the script</param>
|
||||||
|
/// <param name="localVars">Local variables passed along with the script</param>
|
||||||
/// <param name="run">Set to false to compile and cache the script without launching it</param>
|
/// <param name="run">Set to false to compile and cache the script without launching it</param>
|
||||||
/// <exception cref="CSharpException">Thrown if an error occured</exception>
|
/// <exception cref="CSharpException">Thrown if an error occured</exception>
|
||||||
/// <returns>Result of the execution, returned by the script</returns>
|
/// <returns>Result of the execution, returned by the script</returns>
|
||||||
public static object Run(ChatBot apiHandler, ManualResetEvent tickHandler, string[] lines, string[] args, bool run = true)
|
public static object Run(ChatBot apiHandler, ManualResetEvent tickHandler, string[] lines, string[] args, Dictionary<string, object> localVars, bool run = true)
|
||||||
{
|
{
|
||||||
//Script compatibility check for handling future versions differently
|
//Script compatibility check for handling future versions differently
|
||||||
if (lines.Length < 1 || lines[0] != "//MCCScript 1.0")
|
if (lines.Length < 1 || lines[0] != "//MCCScript 1.0")
|
||||||
|
|
@ -132,7 +133,7 @@ namespace MinecraftClient
|
||||||
.GetType()
|
.GetType()
|
||||||
.GetMethod("__run")
|
.GetMethod("__run")
|
||||||
.Invoke(compiledScript,
|
.Invoke(compiledScript,
|
||||||
new object[] { new CSharpAPI(apiHandler, tickHandler), args });
|
new object[] { new CSharpAPI(apiHandler, tickHandler, localVars), args });
|
||||||
}
|
}
|
||||||
catch (Exception e) { throw new CSharpException(CSErrorType.RuntimeError, e); }
|
catch (Exception e) { throw new CSharpException(CSErrorType.RuntimeError, e); }
|
||||||
}
|
}
|
||||||
|
|
@ -192,15 +193,22 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private ManualResetEvent tickHandler;
|
private ManualResetEvent tickHandler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Holds local variables passed along with the script
|
||||||
|
/// </summary>
|
||||||
|
private Dictionary<string, object> localVars;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new C# API Wrapper
|
/// Create a new C# API Wrapper
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="apiHandler">ChatBot API Handler</param>
|
/// <param name="apiHandler">ChatBot API Handler</param>
|
||||||
/// <param name="tickHandler">ChatBot tick handler</param>
|
/// <param name="tickHandler">ChatBot tick handler</param>
|
||||||
public CSharpAPI(ChatBot apiHandler, ManualResetEvent tickHandler)
|
/// <param name="localVars">Local variables passed along with the script</param>
|
||||||
|
public CSharpAPI(ChatBot apiHandler, ManualResetEvent tickHandler, Dictionary<string , object> localVars)
|
||||||
{
|
{
|
||||||
SetMaster(apiHandler);
|
SetMaster(apiHandler);
|
||||||
this.tickHandler = tickHandler;
|
this.tickHandler = tickHandler;
|
||||||
|
this.localVars = localVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* == Wrappers for ChatBot API with public visibility and call limit to one per tick for safety == */
|
/* == Wrappers for ChatBot API with public visibility and call limit to one per tick for safety == */
|
||||||
|
|
@ -231,10 +239,13 @@ namespace MinecraftClient
|
||||||
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command">The command to process</param>
|
/// <param name="command">The command to process</param>
|
||||||
|
/// <param name="localVars">Local variables passed along with the script</param>
|
||||||
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
||||||
new public bool PerformInternalCommand(string command)
|
new public bool PerformInternalCommand(string command, Dictionary<string, object> localVars = null)
|
||||||
{
|
{
|
||||||
bool result = base.PerformInternalCommand(command);
|
if (localVars == null)
|
||||||
|
localVars = this.localVars;
|
||||||
|
bool result = base.PerformInternalCommand(command, localVars);
|
||||||
tickHandler.WaitOne();
|
tickHandler.WaitOne();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -302,6 +313,8 @@ namespace MinecraftClient
|
||||||
/// <returns>Value of the variable or null if no variable</returns>
|
/// <returns>Value of the variable or null if no variable</returns>
|
||||||
public object GetVar(string varName)
|
public object GetVar(string varName)
|
||||||
{
|
{
|
||||||
|
if (localVars != null && localVars.ContainsKey(varName))
|
||||||
|
return localVars[varName];
|
||||||
return Settings.GetVar(varName);
|
return Settings.GetVar(varName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,6 +325,8 @@ namespace MinecraftClient
|
||||||
/// <param name="varValue">Value of the variable</param>
|
/// <param name="varValue">Value of the variable</param>
|
||||||
public bool SetVar(string varName, object varValue)
|
public bool SetVar(string varName, object varValue)
|
||||||
{
|
{
|
||||||
|
if (localVars != null && localVars.ContainsKey(varName))
|
||||||
|
localVars.Remove(varName);
|
||||||
return Settings.SetVar(varName, varValue);
|
return Settings.SetVar(varName, varValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -385,7 +400,7 @@ namespace MinecraftClient
|
||||||
ChatBots.Script.LookForScript(ref script);
|
ChatBots.Script.LookForScript(ref script);
|
||||||
try { lines = File.ReadAllLines(script); }
|
try { lines = File.ReadAllLines(script); }
|
||||||
catch (Exception e) { throw new CSharpException(CSErrorType.FileReadError, e); }
|
catch (Exception e) { throw new CSharpException(CSErrorType.FileReadError, e); }
|
||||||
return CSharpRunner.Run(this, tickHandler, lines, args);
|
return CSharpRunner.Run(this, tickHandler, lines, args, localVars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,17 +138,36 @@ namespace MinecraftClient
|
||||||
/// <param name="data">The payload for the message</param>
|
/// <param name="data">The payload for the message</param>
|
||||||
public virtual void OnPluginMessage(string channel, byte[] data) { }
|
public virtual void OnPluginMessage(string channel, byte[] data) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when properties for the Player entity are received from the server
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prop">Dictionary of player properties</param>
|
||||||
public virtual void OnPlayerProperty(Dictionary<string, Double> prop) { }
|
public virtual void OnPlayerProperty(Dictionary<string, Double> prop) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when server TPS are recalculated by MCC based on world time updates
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tps">New estimated server TPS (between 0 and 20)</param>
|
||||||
public virtual void OnServerTpsUpdate(Double tps) { }
|
public virtual void OnServerTpsUpdate(Double tps) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when an entity moved nearby
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">Entity with updated location</param>
|
||||||
public virtual void OnEntityMove(Mapping.Entity entity) { }
|
public virtual void OnEntityMove(Mapping.Entity entity) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when an entity spawned nearby
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">New Entity</param>
|
||||||
public virtual void OnEntitySpawn(Mapping.Entity entity) { }
|
public virtual void OnEntitySpawn(Mapping.Entity entity) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when an entity despawns/dies nearby
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">Entity wich has just disappeared</param>
|
||||||
public virtual void OnEntityDespawn(Mapping.Entity entity) { }
|
public virtual void OnEntityDespawn(Mapping.Entity entity) { }
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== */
|
/* =================================================================== */
|
||||||
/* ToolBox - Methods below might be useful while creating your bot. */
|
/* ToolBox - Methods below might be useful while creating your bot. */
|
||||||
/* You should not need to interact with other classes of the program. */
|
/* You should not need to interact with other classes of the program. */
|
||||||
|
|
@ -183,11 +202,12 @@ namespace MinecraftClient
|
||||||
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
/// Perform an internal MCC command (not a server command, use SendText() instead for that!)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command">The command to process</param>
|
/// <param name="command">The command to process</param>
|
||||||
|
/// <param name="localVars">Local variables passed along with the command</param>
|
||||||
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
||||||
protected bool PerformInternalCommand(string command)
|
protected bool PerformInternalCommand(string command, Dictionary<string, object> localVars = null)
|
||||||
{
|
{
|
||||||
string temp = "";
|
string temp = "";
|
||||||
return Handler.PerformInternalCommand(command, ref temp);
|
return Handler.PerformInternalCommand(command, ref temp, localVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -195,10 +215,11 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command">The command to process</param>
|
/// <param name="command">The command to process</param>
|
||||||
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
|
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
|
||||||
|
/// <param name="localVars">Local variables passed along with the command</param>
|
||||||
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
||||||
protected bool PerformInternalCommand(string command, ref string response_msg)
|
protected bool PerformInternalCommand(string command, ref string response_msg, Dictionary<string, object> localVars = null)
|
||||||
{
|
{
|
||||||
return Handler.PerformInternalCommand(command, ref response_msg);
|
return Handler.PerformInternalCommand(command, ref response_msg, localVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -586,9 +607,10 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filename">File name</param>
|
/// <param name="filename">File name</param>
|
||||||
/// <param name="playername">Player name to send error messages, if applicable</param>
|
/// <param name="playername">Player name to send error messages, if applicable</param>
|
||||||
protected void RunScript(string filename, string playername = "")
|
/// <param name="localVars">Local variables for use in the Script</param>
|
||||||
|
protected void RunScript(string filename, string playername = null, Dictionary<string, object> localVars = null)
|
||||||
{
|
{
|
||||||
Handler.BotLoad(new ChatBots.Script(filename, playername));
|
Handler.BotLoad(new ChatBots.Script(filename, playername, localVars));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -808,15 +830,23 @@ namespace MinecraftClient
|
||||||
return Handler.InteractEntity(EntityID, type);
|
return Handler.InteractEntity(EntityID, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use item currently in the player's hand (active inventory bar slot)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
protected bool UseItemOnHand()
|
protected bool UseItemOnHand()
|
||||||
{
|
{
|
||||||
return Handler.UseItemOnHand();
|
return Handler.UseItemOnHand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a copy of the player's inventory
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Player inventory</returns>
|
||||||
protected Container GetPlayerInventory()
|
protected Container GetPlayerInventory()
|
||||||
{
|
{
|
||||||
Container container = Handler.GetPlayerInventory();
|
Container container = Handler.GetPlayerInventory();
|
||||||
return new Container(container.ID,container.Type,container.Title,container.Items);
|
return new Container(container.ID, container.Type, container.Title, container.Items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,9 @@ namespace MinecraftClient.ChatBots
|
||||||
/// <param name="username">Player who have sent the message</param>
|
/// <param name="username">Player who have sent the message</param>
|
||||||
/// <param name="message">Message to match against the regex or match string</param>
|
/// <param name="message">Message to match against the regex or match string</param>
|
||||||
/// <param name="msgType">Type of the message public/private message, or other message</param>
|
/// <param name="msgType">Type of the message public/private message, or other message</param>
|
||||||
|
/// <param name="localVars">Dictionary to populate with match variables in case of Regex match</param>
|
||||||
/// <returns>Internal command to run as a response to this user, or null if no match has been detected</returns>
|
/// <returns>Internal command to run as a response to this user, or null if no match has been detected</returns>
|
||||||
public string Match(string username, string message, MessageType msgType)
|
public string Match(string username, string message, MessageType msgType, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
string toSend = null;
|
string toSend = null;
|
||||||
|
|
||||||
|
|
@ -99,9 +100,14 @@ namespace MinecraftClient.ChatBots
|
||||||
if (regex.IsMatch(message))
|
if (regex.IsMatch(message))
|
||||||
{
|
{
|
||||||
Match regexMatch = regex.Match(message);
|
Match regexMatch = regex.Match(message);
|
||||||
|
localVars["match_0"] = regexMatch.Groups[0].Value;
|
||||||
for (int i = regexMatch.Groups.Count - 1; i >= 1; i--)
|
for (int i = regexMatch.Groups.Count - 1; i >= 1; i--)
|
||||||
|
{
|
||||||
toSend = toSend.Replace("$" + i, regexMatch.Groups[i].Value);
|
toSend = toSend.Replace("$" + i, regexMatch.Groups[i].Value);
|
||||||
|
localVars["match_" + i] = regexMatch.Groups[i].Value;
|
||||||
|
}
|
||||||
toSend = toSend.Replace("$u", username);
|
toSend = toSend.Replace("$u", username);
|
||||||
|
localVars["match_u"] = username;
|
||||||
return toSend;
|
return toSend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -109,6 +115,8 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
if (message.ToLower().Contains(match.ToLower()))
|
if (message.ToLower().Contains(match.ToLower()))
|
||||||
{
|
{
|
||||||
|
localVars["match_0"] = message;
|
||||||
|
localVars["match_u"] = username;
|
||||||
return toSend.Replace("$u", username);
|
return toSend.Replace("$u", username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -225,12 +233,13 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
foreach (RespondRule rule in respondRules)
|
foreach (RespondRule rule in respondRules)
|
||||||
{
|
{
|
||||||
string toPerform = rule.Match(sender, message, msgType);
|
Dictionary<string, object> localVars = new Dictionary<string, object>();
|
||||||
|
string toPerform = rule.Match(sender, message, msgType, localVars);
|
||||||
if (!String.IsNullOrEmpty(toPerform))
|
if (!String.IsNullOrEmpty(toPerform))
|
||||||
{
|
{
|
||||||
string response = null;
|
string response = null;
|
||||||
LogToConsole(toPerform);
|
LogToConsole(toPerform);
|
||||||
PerformInternalCommand(toPerform, ref response);
|
PerformInternalCommand(toPerform, ref response, localVars);
|
||||||
if (!String.IsNullOrEmpty(response))
|
if (!String.IsNullOrEmpty(response))
|
||||||
LogToConsole(response);
|
LogToConsole(response);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,17 +25,18 @@ namespace MinecraftClient.ChatBots
|
||||||
private bool csharp;
|
private bool csharp;
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
private ManualResetEvent tpause;
|
private ManualResetEvent tpause;
|
||||||
|
private Dictionary<string, object> localVars;
|
||||||
|
|
||||||
public Script(string filename)
|
public Script(string filename)
|
||||||
{
|
{
|
||||||
ParseArguments(filename);
|
ParseArguments(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Script(string filename, string ownername)
|
public Script(string filename, string ownername, Dictionary<string, object> localVars)
|
||||||
: this(filename)
|
: this(filename)
|
||||||
{
|
{
|
||||||
if (ownername != "")
|
this.owner = ownername;
|
||||||
owner = ownername;
|
this.localVars = localVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ParseArguments(string argstr)
|
private void ParseArguments(string argstr)
|
||||||
|
|
@ -135,14 +136,14 @@ namespace MinecraftClient.ChatBots
|
||||||
csharp = file.EndsWith(".cs");
|
csharp = file.EndsWith(".cs");
|
||||||
thread = null;
|
thread = null;
|
||||||
|
|
||||||
if (owner != null)
|
if (!String.IsNullOrEmpty(owner))
|
||||||
SendPrivateMessage(owner, "Script '" + file + "' loaded.");
|
SendPrivateMessage(owner, "Script '" + file + "' loaded.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogToConsole("File not found: '" + System.IO.Path.GetFullPath(file) + "'");
|
LogToConsole("File not found: '" + System.IO.Path.GetFullPath(file) + "'");
|
||||||
|
|
||||||
if (owner != null)
|
if (!String.IsNullOrEmpty(owner))
|
||||||
SendPrivateMessage(owner, "File not found: '" + file + "'");
|
SendPrivateMessage(owner, "File not found: '" + file + "'");
|
||||||
|
|
||||||
UnloadBot(); //No need to keep the bot active
|
UnloadBot(); //No need to keep the bot active
|
||||||
|
|
@ -161,7 +162,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CSharpRunner.Run(this, tpause, lines, args);
|
CSharpRunner.Run(this, tpause, lines, args, localVars);
|
||||||
}
|
}
|
||||||
catch (CSharpException e)
|
catch (CSharpException e)
|
||||||
{
|
{
|
||||||
|
|
@ -198,7 +199,7 @@ namespace MinecraftClient.ChatBots
|
||||||
{
|
{
|
||||||
if (instruction_line[0] != '#' && instruction_line[0] != '/' && instruction_line[1] != '/')
|
if (instruction_line[0] != '#' && instruction_line[0] != '/' && instruction_line[1] != '/')
|
||||||
{
|
{
|
||||||
instruction_line = Settings.ExpandVars(instruction_line);
|
instruction_line = Settings.ExpandVars(instruction_line, localVars);
|
||||||
string instruction_name = instruction_line.Split(' ')[0];
|
string instruction_name = instruction_line.Split(' ')[0];
|
||||||
switch (instruction_name.ToLower())
|
switch (instruction_name.ToLower())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11,40 +11,35 @@ namespace MinecraftClient
|
||||||
/// If inheriting from the 'Command' class and placed in the 'Commands' namespace, the command will be
|
/// If inheriting from the 'Command' class and placed in the 'Commands' namespace, the command will be
|
||||||
/// automatically loaded and available in main chat prompt, scripts, remote control and command help.
|
/// automatically loaded and available in main chat prompt, scripts, remote control and command help.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public abstract class Command
|
public abstract class Command
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The command name
|
/// The command name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public abstract string CMDName { get; }
|
public abstract string CMDName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Usage message, eg: 'name [args]: do something'
|
/// Usage message, eg: 'name [args]: do something'
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public abstract string CMDDesc { get; }
|
public abstract string CMDDesc { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform the command
|
/// Perform the command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command">The full command, eg: 'mycommand arg1 arg2'</param>
|
/// <param name="command">The full command, eg: 'mycommand arg1 arg2'</param>
|
||||||
|
/// <param name="localVars">Local variables passed along with the command (may be null)</param>
|
||||||
/// <returns>A confirmation/error message, or "" if no message</returns>
|
/// <returns>A confirmation/error message, or "" if no message</returns>
|
||||||
|
public abstract string Run(McTcpClient handler, string command, Dictionary<string, object> localVars);
|
||||||
public abstract string Run(McTcpClient handler, string command);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return a list of aliases for this command.
|
/// Return a list of aliases for this command.
|
||||||
/// Override this method if you wish to put aliases to the command
|
/// Override this method if you wish to put aliases to the command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public virtual IEnumerable<string> getCMDAliases() { return new string[0]; }
|
public virtual IEnumerable<string> getCMDAliases() { return new string[0]; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if at least one argument has been passed to the command
|
/// Check if at least one argument has been passed to the command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public static bool hasArg(string command)
|
public static bool hasArg(string command)
|
||||||
{
|
{
|
||||||
int first_space = command.IndexOf(' ');
|
int first_space = command.IndexOf(' ');
|
||||||
|
|
@ -55,7 +50,6 @@ namespace MinecraftClient
|
||||||
/// Extract the argument string from the command
|
/// Extract the argument string from the command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Argument or "" if no argument</returns>
|
/// <returns>Argument or "" if no argument</returns>
|
||||||
|
|
||||||
public static string getArg(string command)
|
public static string getArg(string command)
|
||||||
{
|
{
|
||||||
if (hasArg(command))
|
if (hasArg(command))
|
||||||
|
|
@ -69,7 +63,6 @@ namespace MinecraftClient
|
||||||
/// Extract the arguments as a string array from the command
|
/// Extract the arguments as a string array from the command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Argument array or empty array if no arguments</returns>
|
/// <returns>Argument array or empty array if no arguments</returns>
|
||||||
|
|
||||||
public static string[] getArgs(string command)
|
public static string[] getArgs(string command)
|
||||||
{
|
{
|
||||||
string[] args = getArg(command).Split(' ');
|
string[] args = getArg(command).Split(' ');
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "changeslot"; } }
|
public override string CMDName { get { return "changeslot"; } }
|
||||||
public override string CMDDesc { get { return "changeslot <1-9>: Change hotbar"; } }
|
public override string CMDDesc { get { return "changeslot <1-9>: Change hotbar"; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
if (!handler.GetInventoryEnabled()) return "Please enable InventoryHandling in the config file first.";
|
if (!handler.GetInventoryEnabled()) return "Please enable InventoryHandling in the config file first.";
|
||||||
if (hasArg(command))
|
if (hasArg(command))
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "connect"; } }
|
public override string CMDName { get { return "connect"; } }
|
||||||
public override string CMDDesc { get { return "connect <server> [account]: connect to the specified server."; } }
|
public override string CMDDesc { get { return "connect <server> [account]: connect to the specified server."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
if (hasArg(command))
|
if (hasArg(command))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "debug"; } }
|
public override string CMDName { get { return "debug"; } }
|
||||||
public override string CMDDesc { get { return "debug [on|off]: toggle debug messages."; } }
|
public override string CMDDesc { get { return "debug [on|off]: toggle debug messages."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
if (hasArg(command))
|
if (hasArg(command))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "exit"; } }
|
public override string CMDName { get { return "exit"; } }
|
||||||
public override string CMDDesc { get { return "exit: disconnect from the server."; } }
|
public override string CMDDesc { get { return "exit: disconnect from the server."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
Program.Exit();
|
Program.Exit();
|
||||||
return "";
|
return "";
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "getinventory"; } }
|
public override string CMDName { get { return "getinventory"; } }
|
||||||
public override string CMDDesc { get { return "getinventory: Show your inventory."; } }
|
public override string CMDDesc { get { return "getinventory: Show your inventory."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
Dictionary<int,Item> items = handler.GetPlayerInventory().Items;
|
Dictionary<int,Item> items = handler.GetPlayerInventory().Items;
|
||||||
foreach(KeyValuePair<int,Item> a in items)
|
foreach(KeyValuePair<int,Item> a in items)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "list"; } }
|
public override string CMDName { get { return "list"; } }
|
||||||
public override string CMDDesc { get { return "list: get the player list."; } }
|
public override string CMDDesc { get { return "list: get the player list."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
return "PlayerList: " + String.Join(", ", handler.GetOnlinePlayers());
|
return "PlayerList: " + String.Join(", ", handler.GetOnlinePlayers());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "log"; } }
|
public override string CMDName { get { return "log"; } }
|
||||||
public override string CMDDesc { get { return "log <text>: log some text to the console."; } }
|
public override string CMDDesc { get { return "log <text>: log some text to the console."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
if (hasArg(command))
|
if (hasArg(command))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "look"; } }
|
public override string CMDName { get { return "look"; } }
|
||||||
public override string CMDDesc { get { return "look <x y z|yaw pitch|up|down|east|west|north|south>: look at direction or coordinates."; } }
|
public override string CMDDesc { get { return "look <x y z|yaw pitch|up|down|east|west|north|south>: look at direction or coordinates."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
if (handler.GetTerrainEnabled())
|
if (handler.GetTerrainEnabled())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "move"; } }
|
public override string CMDName { get { return "move"; } }
|
||||||
public override string CMDDesc { get { return "move <on|off|get|up|down|east|west|north|south|x y z>: walk or start walking."; } }
|
public override string CMDDesc { get { return "move <on|off|get|up|down|east|west|north|south|x y z>: walk or start walking."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
string[] args = getArgs(command);
|
string[] args = getArgs(command);
|
||||||
string argStr = getArg(command).Trim().ToLower();
|
string argStr = getArg(command).Trim().ToLower();
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "reco"; } }
|
public override string CMDName { get { return "reco"; } }
|
||||||
public override string CMDDesc { get { return "reco [account]: restart and reconnect to the server."; } }
|
public override string CMDDesc { get { return "reco [account]: restart and reconnect to the server."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
string[] args = getArgs(command);
|
string[] args = getArgs(command);
|
||||||
if (args.Length > 0)
|
if (args.Length > 0)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "respawn"; } }
|
public override string CMDName { get { return "respawn"; } }
|
||||||
public override string CMDDesc { get { return "respawn: Use this to respawn if you are dead."; } }
|
public override string CMDDesc { get { return "respawn: Use this to respawn if you are dead."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
handler.SendRespawnPacket();
|
handler.SendRespawnPacket();
|
||||||
return "You have respawned.";
|
return "You have respawned.";
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "script"; } }
|
public override string CMDName { get { return "script"; } }
|
||||||
public override string CMDDesc { get { return "script <scriptname>: run a script file."; } }
|
public override string CMDDesc { get { return "script <scriptname>: run a script file."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
if (hasArg(command))
|
if (hasArg(command))
|
||||||
{
|
{
|
||||||
handler.BotLoad(new ChatBots.Script(getArg(command)));
|
handler.BotLoad(new ChatBots.Script(getArg(command), null, localVars));
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
else return CMDDesc;
|
else return CMDDesc;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "send"; } }
|
public override string CMDName { get { return "send"; } }
|
||||||
public override string CMDDesc { get { return "send <text>: send a chat message or command."; } }
|
public override string CMDDesc { get { return "send <text>: send a chat message or command."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
if (hasArg(command))
|
if (hasArg(command))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "set"; } }
|
public override string CMDName { get { return "set"; } }
|
||||||
public override string CMDDesc { get { return "set varname=value: set a custom %variable%."; } }
|
public override string CMDDesc { get { return "set varname=value: set a custom %variable%."; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
if (hasArg(command))
|
if (hasArg(command))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Commands
|
||||||
public override string CMDName { get { return "useitem"; } }
|
public override string CMDName { get { return "useitem"; } }
|
||||||
public override string CMDDesc { get { return "useitem: Use (left click) an item on the hand"; } }
|
public override string CMDDesc { get { return "useitem: Use (left click) an item on the hand"; } }
|
||||||
|
|
||||||
public override string Run(McTcpClient handler, string command)
|
public override string Run(McTcpClient handler, string command, Dictionary<string, object> localVars)
|
||||||
{
|
{
|
||||||
handler.UseItemOnHand();
|
handler.UseItemOnHand();
|
||||||
return "Use an item";
|
return "Use an item";
|
||||||
|
|
|
||||||
|
|
@ -313,8 +313,9 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command">The command</param>
|
/// <param name="command">The command</param>
|
||||||
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
|
/// <param name="response_msg">May contain a confirmation or error message after processing the command, or "" otherwise.</param>
|
||||||
|
/// <param name="localVars">Local variables passed along with the command</param>
|
||||||
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
/// <returns>TRUE if the command was indeed an internal MCC command</returns>
|
||||||
public bool PerformInternalCommand(string command, ref string response_msg)
|
public bool PerformInternalCommand(string command, ref string response_msg, Dictionary<string, object> localVars = null)
|
||||||
{
|
{
|
||||||
/* Load commands from the 'Commands' namespace */
|
/* Load commands from the 'Commands' namespace */
|
||||||
|
|
||||||
|
|
@ -363,7 +364,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
else if (cmds.ContainsKey(command_name))
|
else if (cmds.ContainsKey(command_name))
|
||||||
{
|
{
|
||||||
response_msg = cmds[command_name].Run(this, command);
|
response_msg = cmds[command_name].Run(this, command, localVars);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -388,15 +388,15 @@ namespace MinecraftClient
|
||||||
|
|
||||||
if (command.StartsWith("reco"))
|
if (command.StartsWith("reco"))
|
||||||
{
|
{
|
||||||
message = new Commands.Reco().Run(null, Settings.ExpandVars(command));
|
message = new Commands.Reco().Run(null, Settings.ExpandVars(command), null);
|
||||||
}
|
}
|
||||||
else if (command.StartsWith("connect"))
|
else if (command.StartsWith("connect"))
|
||||||
{
|
{
|
||||||
message = new Commands.Connect().Run(null, Settings.ExpandVars(command));
|
message = new Commands.Connect().Run(null, Settings.ExpandVars(command), null);
|
||||||
}
|
}
|
||||||
else if (command.StartsWith("exit") || command.StartsWith("quit"))
|
else if (command.StartsWith("exit") || command.StartsWith("quit"))
|
||||||
{
|
{
|
||||||
message = new Commands.Exit().Run(null, Settings.ExpandVars(command));
|
message = new Commands.Exit().Run(null, Settings.ExpandVars(command), null);
|
||||||
}
|
}
|
||||||
else if (command.StartsWith("help"))
|
else if (command.StartsWith("help"))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -792,11 +792,12 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replace %variables% with their value
|
/// Replace %variables% with their value from global AppVars
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="str">String to parse</param>
|
/// <param name="str">String to parse</param>
|
||||||
|
/// <param name="localContext">Optional local variables overriding global variables</param>
|
||||||
/// <returns>Modifier string</returns>
|
/// <returns>Modifier string</returns>
|
||||||
public static string ExpandVars(string str)
|
public static string ExpandVars(string str, Dictionary<string, object> localVars = null)
|
||||||
{
|
{
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
for (int i = 0; i < str.Length; i++)
|
for (int i = 0; i < str.Length; i++)
|
||||||
|
|
@ -808,7 +809,7 @@ namespace MinecraftClient
|
||||||
|
|
||||||
for (int j = i + 1; j < str.Length; j++)
|
for (int j = i + 1; j < str.Length; j++)
|
||||||
{
|
{
|
||||||
if (!char.IsLetterOrDigit(str[j]))
|
if (!char.IsLetterOrDigit(str[j]) && str[j] != '_')
|
||||||
{
|
{
|
||||||
if (str[j] == '%')
|
if (str[j] == '%')
|
||||||
varname_ok = var_name.Length > 0;
|
varname_ok = var_name.Length > 0;
|
||||||
|
|
@ -829,7 +830,11 @@ namespace MinecraftClient
|
||||||
case "serverip": result.Append(ServerIP); break;
|
case "serverip": result.Append(ServerIP); break;
|
||||||
case "serverport": result.Append(ServerPort); break;
|
case "serverport": result.Append(ServerPort); break;
|
||||||
default:
|
default:
|
||||||
if (AppVars.ContainsKey(varname_lower))
|
if (localVars != null && localVars.ContainsKey(varname_lower))
|
||||||
|
{
|
||||||
|
result.Append(localVars[varname_lower].ToString());
|
||||||
|
}
|
||||||
|
else if (AppVars.ContainsKey(varname_lower))
|
||||||
{
|
{
|
||||||
result.Append(AppVars[varname_lower].ToString());
|
result.Append(AppVars[varname_lower].ToString());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Minecraft Client v1.13.0 for Minecraft 1.4.6 to 1.13.2 - By ORelio & Contributors
|
Minecraft Console Client User Manual
|
||||||
======
|
======
|
||||||
|
|
||||||
**Thanks for dowloading Minecraft Console Client!**
|
**Thanks for dowloading Minecraft Console Client!**
|
||||||
|
|
@ -17,7 +17,7 @@ On Mac or Linux you need to install the Mono Runtime:
|
||||||
- On Linux: sudo apt-get install mono-runtime libmono-reflection-cil
|
- On Linux: sudo apt-get install mono-runtime libmono-reflection-cil
|
||||||
Then, open a terminal in this folder and run "mono MinecraftClient.exe".
|
Then, open a terminal in this folder and run "mono MinecraftClient.exe".
|
||||||
If you cannot authenticate on Mono, you'll need to run "mozroots --import --ask-remove" once.
|
If you cannot authenticate on Mono, you'll need to run "mozroots --import --ask-remove" once.
|
||||||
If Mono crashes, retry with mono-complete instead of mono-runtime. Mono v4.0 to 4.2 is recommended.
|
If Mono crashes, retry with mono-complete instead of mono-runtime. Use at least Mono v4.0.
|
||||||
|
|
||||||
Using Configuration files & Enabling bots
|
Using Configuration files & Enabling bots
|
||||||
------
|
------
|
||||||
|
|
@ -235,7 +235,6 @@ Using the Auto Attack
|
||||||
|
|
||||||
The AutoAttack bot allows you to automatically attack mobs around you (precisely within radius of 4 block).
|
The AutoAttack bot allows you to automatically attack mobs around you (precisely within radius of 4 block).
|
||||||
To use this bot, you will need to enable **Entity Handling** in the config file first.
|
To use this bot, you will need to enable **Entity Handling** in the config file first.
|
||||||
**You have been reminded that we will not take any responsible if you got banned by your server while using this bot.**
|
|
||||||
|
|
||||||
Using the Auto Fishing
|
Using the Auto Fishing
|
||||||
------
|
------
|
||||||
|
|
@ -249,19 +248,21 @@ Steps for using this bot:
|
||||||
1. Hold a fishing rod and aim towards the sea before login with MCC
|
1. Hold a fishing rod and aim towards the sea before login with MCC
|
||||||
2. Make sure AutoFish is enabled in config file
|
2. Make sure AutoFish is enabled in config file
|
||||||
3. Login with MCC
|
3. Login with MCC
|
||||||
4. Do /useitem and you should see "threw a fishing rod"
|
4. Do `/useitem` and you should see "threw a fishing rod"
|
||||||
5. To stop fishing, do /useitem again
|
5. To stop fishing, do `/useitem` again
|
||||||
|
|
||||||
Disclaimer
|
Disclaimer
|
||||||
------
|
------
|
||||||
|
|
||||||
Even if everything should work, I am not responsible of any damage this app could cause to your computer or your server.
|
Even if everything should work, We are not responsible for any damage this app could cause to your computer or your server.
|
||||||
This app does not steal your password. If you don't trust it, don't use it or check & compile from the source code.
|
This app does not steal your password. If you don't trust it, don't use it or check & compile from the source code.
|
||||||
|
|
||||||
Also, remember that when you connect to a server with this program, you will appear where you left the last time.
|
Also, remember that when you connect to a server with this program, you will appear where you left the last time.
|
||||||
This means that you can die if you log in in an unsafe place on a survival server!
|
This means that **you can die if you log in in an unsafe place on a survival server!**
|
||||||
Use the script scheduler bot to send a teleport command after logging in.
|
Use the script scheduler bot to send a teleport command after logging in.
|
||||||
|
|
||||||
|
You have been reminded that **you may get banned** by your server for using this program. Use accordinly with server rules.
|
||||||
|
|
||||||
License
|
License
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
@ -294,8 +295,8 @@ would not have been possible without the help of talented contributors:
|
||||||
**Code contributions:**
|
**Code contributions:**
|
||||||
|
|
||||||
Allyoutoo, Aragas, Bancey, bearbear12345, corbanmailloux, dbear20, dogwatch, initsuj,
|
Allyoutoo, Aragas, Bancey, bearbear12345, corbanmailloux, dbear20, dogwatch, initsuj,
|
||||||
JamieSinn, justcool393, lokulin, maxpowa, medxo, Pokechu22, repository, TheMeq, TheSnoozer,
|
JamieSinn, justcool393, lokulin, maxpowa, medxo, milutinke, Pokechu22, ReinforceZwei,
|
||||||
vkorn, v1RuX, ZizzyDizzyMC, milutinke
|
repository, TheMeq, TheSnoozer, vkorn, v1RuX, yunusemregul, ZizzyDizzyMC
|
||||||
|
|
||||||
**Libraries:**
|
**Libraries:**
|
||||||
|
|
||||||
|
|
@ -324,5 +325,5 @@ Like Minecraft Console Client? You can buy me a coffee here:
|
||||||
Code contributions, bug reports and any kind of comments are also highly appreciated :)
|
Code contributions, bug reports and any kind of comments are also highly appreciated :)
|
||||||
|
|
||||||
+-----------------------------------+
|
+-----------------------------------+
|
||||||
| © 2012-2019 ORelio & Contributors |
|
| © 2012-2020 ORelio & Contributors |
|
||||||
+-----------------------------------+
|
+-----------------------------------+
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,11 @@
|
||||||
# Regex matches are also supported eg $1, $2, $3.. in actions
|
# Regex matches are also supported eg $1, $2, $3.. in actions
|
||||||
# Matches can optionally be restricted to bot owners only
|
# Matches can optionally be restricted to bot owners only
|
||||||
|
|
||||||
|
# When running a script from an AutoRespond match,
|
||||||
|
# additional %variables% are available from within your script:
|
||||||
|
# %match_u% will hold username of the player triggering the match
|
||||||
|
# %match_1%, %match_2%, %match_3%.. will hold regex matches
|
||||||
|
|
||||||
# Simple example: Respond to a message containing a keyword
|
# Simple example: Respond to a message containing a keyword
|
||||||
|
|
||||||
[Match]
|
[Match]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue