Bump version to 1.1.3

Added player status events
Added debugger displays for messages
This commit is contained in:
Michael Chen 2022-01-18 16:47:11 +01:00
parent 82c8313cb9
commit 6920d1a2b3
No known key found for this signature in database
GPG Key ID: 1CBC7AA5671437BB
5 changed files with 75 additions and 1 deletions

View File

@ -188,10 +188,51 @@ local function peripheralAttachEventListener(socket)
end end
end end
local function listAsSet(list)
local asSet = {}
for i,elem in pairs(list) do asSet[elem] = true end
return asSet
end
local function joinSets(a, b)
local joined = {}
for elem,exists in pairs(a) do if exists then joined[elem] = true end end
for elem,exists in pairs(b) do if exists then joined[elem] = true end end
return joined
end
local function playerStatusEventListener(socket)
local players = {}
while true do
local pd = peripheral.find("playerDetector")
if not not pd then
players = listAsSet(pd.getOnlinePlayers())
break
end
printError("playerDetector not connected!")
end
while true do
local pd = peripheral.find("playerDetector")
if not not pd then
local newPlayers = listAsSet(pd.getOnlinePlayers())
for player,_ in pairs(joinSets(players, newPlayers)) do
if players[player] and (not newPlayers[player]) then
sendJson(socket, {type = "playerstatus", player = player, status = false})
elseif (not players[player]) and newPlayers[player] then
sendJson(socket, {type = "playerstatus", player = player, status = true})
end
end
players = newPlayers
end
sleep(1)
end
end
local function eventListeners(socket) local function eventListeners(socket)
parallel.waitForAny( parallel.waitForAny(
termWaiter, termWaiter,
function() chatEventListener(socket) end, function() chatEventListener(socket) end,
function() playerStatusEventListener(socket) end,
function() peripheralDetachEventListener(socket) end, function() peripheralDetachEventListener(socket) end,
function() peripheralAttachEventListener(socket) end function() peripheralAttachEventListener(socket) end
) )

View File

@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<Version>1.1.2</Version> <Version>1.1.3</Version>
<Authors>Michael Chen</Authors> <Authors>Michael Chen</Authors>
<Company>$(Authors)</Company> <Company>$(Authors)</Company>
<RepositoryUrl>https://gitlab.com/chenmichael/mcdiscordbot</RepositoryUrl> <RepositoryUrl>https://gitlab.com/chenmichael/mcdiscordbot</RepositoryUrl>

View File

@ -1,6 +1,7 @@
using Discord.WebSocket; using Discord.WebSocket;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Diagnostics;
namespace MinecraftDiscordBot.Models; namespace MinecraftDiscordBot.Models;
@ -39,14 +40,17 @@ public abstract class Message {
} }
[MessageType(TYPE)] [MessageType(TYPE)]
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public class CapabilityMessage : Message { public class CapabilityMessage : Message {
private const string TYPE = "roles"; private const string TYPE = "roles";
public override string Type => TYPE; public override string Type => TYPE;
[JsonProperty("role", Required = Required.Always)] [JsonProperty("role", Required = Required.Always)]
public string[] Role { get; set; } = default!; public string[] Role { get; set; } = default!;
public override string ToString() => $"Capabilities: {string.Join(", ", Role)}";
} }
[MessageType(TYPE)] [MessageType(TYPE)]
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public class ReplyMessage : Message { public class ReplyMessage : Message {
private const string TYPE = "reply"; private const string TYPE = "reply";
public override string Type => TYPE; public override string Type => TYPE;
@ -60,19 +64,35 @@ public class ReplyMessage : Message {
public int Total { get; set; } = 1; public int Total { get; set; } = 1;
[JsonProperty("success", Required = Required.DisallowNull)] [JsonProperty("success", Required = Required.DisallowNull)]
public ResultState State { get; set; } = ResultState.Successful; public ResultState State { get; set; } = ResultState.Successful;
public override string ToString() => $"Reply [{AnswerId}] {State} ({Chunk}/{Total}) Length {Result.Length}";
} }
public abstract class EventMessage : Message { } public abstract class EventMessage : Message { }
[MessageType(TYPE)] [MessageType(TYPE)]
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public class PeripheralDetachEvent : EventMessage { public class PeripheralDetachEvent : EventMessage {
private const string TYPE = "peripheral_detach"; private const string TYPE = "peripheral_detach";
public override string Type => TYPE; public override string Type => TYPE;
[JsonProperty("side", Required = Required.Always)] [JsonProperty("side", Required = Required.Always)]
public string Side { get; set; } = default!; public string Side { get; set; } = default!;
public override string ToString() => $"Detached '{Side}'!";
} }
[MessageType(TYPE)] [MessageType(TYPE)]
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public class PlayerStatusEvent : EventMessage {
private const string TYPE = "playerstatus";
public override string Type => TYPE;
[JsonProperty("player", Required = Required.Always)]
public string Player { get; set; } = default!;
[JsonProperty("status", Required = Required.Always)]
public bool Online { get; set; }
public override string ToString() => $"{Player} is now {(Online ? "on" : "off")}line!";
}
[MessageType(TYPE)]
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public class PeripheralAttachEvent : EventMessage { public class PeripheralAttachEvent : EventMessage {
private const string TYPE = "peripheral"; private const string TYPE = "peripheral";
public override string Type => TYPE; public override string Type => TYPE;
@ -80,6 +100,7 @@ public class PeripheralAttachEvent : EventMessage {
public string Side => Peripheral.Side; public string Side => Peripheral.Side;
[JsonProperty("peripheral", Required = Required.Always)] [JsonProperty("peripheral", Required = Required.Always)]
public Peripheral Peripheral { get; set; } = default!; public Peripheral Peripheral { get; set; } = default!;
public override string ToString() => $"Attached {Peripheral}!";
} }
public class Peripheral { public class Peripheral {
@ -89,9 +110,11 @@ public class Peripheral {
public string Type { get; set; } = default!; public string Type { get; set; } = default!;
[JsonProperty("methods", Required = Required.Always)] [JsonProperty("methods", Required = Required.Always)]
public string[] Methods { get; set; } = default!; public string[] Methods { get; set; } = default!;
public override string ToString() => $"{Type} at '{Side}'";
} }
[MessageType(TYPE)] [MessageType(TYPE)]
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public class ChatEvent : EventMessage { public class ChatEvent : EventMessage {
private const string TYPE = "chat"; private const string TYPE = "chat";
public override string Type => TYPE; public override string Type => TYPE;
@ -103,9 +126,11 @@ public class ChatEvent : EventMessage {
public string UUID { get; set; } = default!; public string UUID { get; set; } = default!;
[JsonProperty("hidden", Required = Required.Always)] [JsonProperty("hidden", Required = Required.Always)]
public bool IsHidden { get; set; } public bool IsHidden { get; set; }
public override string ToString() => $"{(IsHidden ? "HIDDEN: " : string.Empty)}[{Username}] {Message} ({UUID})";
} }
[MessageType(TYPE)] [MessageType(TYPE)]
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
public class RequestMessage : Message { public class RequestMessage : Message {
private const string TYPE = "request"; private const string TYPE = "request";
public override string Type => TYPE; public override string Type => TYPE;
@ -121,4 +146,5 @@ public class RequestMessage : Message {
public string Method { get; set; } public string Method { get; set; }
[JsonProperty("params")] [JsonProperty("params")]
public Dictionary<string, object> Parameters { get; } public Dictionary<string, object> Parameters { get; }
public override string ToString() => $"Request [{AnswerId}] {Method}({JsonConvert.SerializeObject(Parameters)})";
} }

View File

@ -60,6 +60,7 @@ public class Program : IDisposable, ICommandHandler<ResponseType>, IUserRoleMana
_computer = new(this); _computer = new(this);
_computer.ChatMessageReceived += MinecraftMessageReceived; _computer.ChatMessageReceived += MinecraftMessageReceived;
_computer.SocketChanged += ComputerConnectedChanged; _computer.SocketChanged += ComputerConnectedChanged;
_computer.PlayerStatusChanged += PlayerStatusChanged;
_computer.PeripheralAttached += PeripheralAttached; _computer.PeripheralAttached += PeripheralAttached;
_computer.PeripheralDetached += PeripheralDetached; _computer.PeripheralDetached += PeripheralDetached;
_administrators = config.Administrators.ToHashSet(); _administrators = config.Administrators.ToHashSet();
@ -74,6 +75,8 @@ public class Program : IDisposable, ICommandHandler<ResponseType>, IUserRoleMana
_whitelistedChannels = config.Channels.ToHashSet(); _whitelistedChannels = config.Channels.ToHashSet();
} }
private void PlayerStatusChanged(object? sender, PlayerStatusEvent e)
=> _ = Task.Run(() => Broadcast(i => i.SendMessageAsync($"{e.Player} just {(e.Online ? "joined" : "left")} the server!")));
private void PeripheralAttached(object? sender, PeripheralAttachEvent e) => LogInfo("Computer", $"Peripheral {e.Peripheral.Type} was attached on side {e.Side}."); private void PeripheralAttached(object? sender, PeripheralAttachEvent e) => LogInfo("Computer", $"Peripheral {e.Peripheral.Type} was attached on side {e.Side}.");
private void PeripheralDetached(object? sender, PeripheralDetachEvent e) => LogInfo("Computer", $"Peripheral on side {e.Side} was detached."); private void PeripheralDetached(object? sender, PeripheralDetachEvent e) => LogInfo("Computer", $"Peripheral on side {e.Side} was detached.");
private void ComputerConnectedChanged(object? sender, IWebSocketConnection? e) private void ComputerConnectedChanged(object? sender, IWebSocketConnection? e)

View File

@ -26,6 +26,7 @@ public class RootCommandService : CommandRouter, ITaskWaitSource {
} }
public event EventHandler<ChatEvent>? ChatMessageReceived; public event EventHandler<ChatEvent>? ChatMessageReceived;
public event EventHandler<PlayerStatusEvent>? PlayerStatusChanged;
public event EventHandler<PeripheralAttachEvent>? PeripheralAttached; public event EventHandler<PeripheralAttachEvent>? PeripheralAttached;
public event EventHandler<PeripheralDetachEvent>? PeripheralDetached; public event EventHandler<PeripheralDetachEvent>? PeripheralDetached;
public event EventHandler<IWebSocketConnection?>? SocketChanged; public event EventHandler<IWebSocketConnection?>? SocketChanged;
@ -49,6 +50,9 @@ public class RootCommandService : CommandRouter, ITaskWaitSource {
case ChatEvent msg: case ChatEvent msg:
ChatMessageReceived?.Invoke(this, msg); ChatMessageReceived?.Invoke(this, msg);
break; break;
case PlayerStatusEvent msg:
PlayerStatusChanged?.Invoke(this, msg);
break;
case PeripheralAttachEvent msg: case PeripheralAttachEvent msg:
PeripheralAttached?.Invoke(this, msg); PeripheralAttached?.Invoke(this, msg);
break; break;