mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2025-09-13 18:32:10 +02:00
Compare commits
1 Commits
experiment
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
fad7b35e04
|
@@ -1,7 +1,6 @@
|
|||||||
using NetMQ.Sockets;
|
using NetMQ.Sockets;
|
||||||
using Phantom.Agent.Rpc;
|
using Phantom.Agent.Rpc;
|
||||||
using Phantom.Common.Data.Replies;
|
using Phantom.Common.Data.Replies;
|
||||||
using Phantom.Common.Logging;
|
|
||||||
using Phantom.Common.Messages;
|
using Phantom.Common.Messages;
|
||||||
using Phantom.Common.Messages.ToAgent;
|
using Phantom.Common.Messages.ToAgent;
|
||||||
using Phantom.Common.Messages.ToServer;
|
using Phantom.Common.Messages.ToServer;
|
||||||
@@ -50,6 +49,11 @@ public sealed class MessageListener : IMessageToAgentListener {
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task HandleShutdownAgent(ShutdownAgentMessage message) {
|
||||||
|
shutdownTokenSource.Cancel();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task HandleConfigureInstance(ConfigureInstanceMessage message) {
|
public async Task HandleConfigureInstance(ConfigureInstanceMessage message) {
|
||||||
await socket.SendSimpleReply(message, await agent.InstanceSessionManager.Configure(message.Configuration));
|
await socket.SendSimpleReply(message, await agent.InstanceSessionManager.Configure(message.Configuration));
|
||||||
}
|
}
|
||||||
|
@@ -1,476 +0,0 @@
|
|||||||
using Phantom.Utils.Cryptography;
|
|
||||||
|
|
||||||
namespace Phantom.Agent;
|
|
||||||
|
|
||||||
static class AgentNameGenerator {
|
|
||||||
private static readonly string[] Prefixes = {
|
|
||||||
"Abundant",
|
|
||||||
"Ancient",
|
|
||||||
"Broken",
|
|
||||||
"Crushed",
|
|
||||||
"Damaged",
|
|
||||||
"Dark",
|
|
||||||
"Divine",
|
|
||||||
"Enchanted",
|
|
||||||
"Flaming",
|
|
||||||
"Frozen",
|
|
||||||
"Gilded",
|
|
||||||
"Glowing",
|
|
||||||
"Immaculate",
|
|
||||||
"Infested",
|
|
||||||
"Invisible",
|
|
||||||
"Luxurious",
|
|
||||||
"Mossy",
|
|
||||||
"Mysterious",
|
|
||||||
"Opulent",
|
|
||||||
"Perplexing",
|
|
||||||
"Possessed",
|
|
||||||
"Pristine",
|
|
||||||
"Rotting",
|
|
||||||
"Sophisticated",
|
|
||||||
"Spectacular",
|
|
||||||
"Stunning",
|
|
||||||
"Tenacious",
|
|
||||||
"Twisted",
|
|
||||||
"Unique",
|
|
||||||
"Venerable",
|
|
||||||
"Withering"
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly string[] Suffixes = {
|
|
||||||
"Acacia Button",
|
|
||||||
"Acacia Door",
|
|
||||||
"Acacia Fence",
|
|
||||||
"Acacia Leaves",
|
|
||||||
"Acacia Log",
|
|
||||||
"Acacia Planks",
|
|
||||||
"Acacia Sapling",
|
|
||||||
"Acacia Sign",
|
|
||||||
"Acacia Slab",
|
|
||||||
"Acacia Stairs",
|
|
||||||
"Acacia Trapdoor",
|
|
||||||
"Acacia Wood",
|
|
||||||
"Activator Rail",
|
|
||||||
"Allium",
|
|
||||||
"Ancient Debris",
|
|
||||||
"Andesite Slab",
|
|
||||||
"Andesite Stairs",
|
|
||||||
"Andesite Wall",
|
|
||||||
"Andesite",
|
|
||||||
"Anvil",
|
|
||||||
"Azalea Leaves",
|
|
||||||
"Azalea",
|
|
||||||
"Azure Bluet",
|
|
||||||
"Bamboo",
|
|
||||||
"Barrel",
|
|
||||||
"Basalt",
|
|
||||||
"Beacon",
|
|
||||||
"Bedrock",
|
|
||||||
"Bee Nest",
|
|
||||||
"Beehive",
|
|
||||||
"Beetroots",
|
|
||||||
"Bell",
|
|
||||||
"Birch Button",
|
|
||||||
"Birch Door",
|
|
||||||
"Birch Fence",
|
|
||||||
"Birch Leaves",
|
|
||||||
"Birch Log",
|
|
||||||
"Birch Planks",
|
|
||||||
"Birch Sapling",
|
|
||||||
"Birch Sign",
|
|
||||||
"Birch Slab",
|
|
||||||
"Birch Stairs",
|
|
||||||
"Birch Trapdoor",
|
|
||||||
"Birch Wood",
|
|
||||||
"Black Candle",
|
|
||||||
"Black Carpet",
|
|
||||||
"Black Concrete",
|
|
||||||
"Black Terracotta",
|
|
||||||
"Black Wool",
|
|
||||||
"Blackstone Slab",
|
|
||||||
"Blackstone Stairs",
|
|
||||||
"Blackstone Wall",
|
|
||||||
"Blackstone",
|
|
||||||
"Blast Furnace",
|
|
||||||
"Blue Candle",
|
|
||||||
"Blue Carpet",
|
|
||||||
"Blue Concrete",
|
|
||||||
"Blue Ice",
|
|
||||||
"Blue Orchid",
|
|
||||||
"Blue Terracotta",
|
|
||||||
"Blue Wool",
|
|
||||||
"Bone Block",
|
|
||||||
"Bookshelf",
|
|
||||||
"Brain Coral",
|
|
||||||
"Brewing Stand",
|
|
||||||
"Brick Slab",
|
|
||||||
"Brick Stairs",
|
|
||||||
"Brick Wall",
|
|
||||||
"Bricks",
|
|
||||||
"Brown Candle",
|
|
||||||
"Brown Carpet",
|
|
||||||
"Brown Concrete",
|
|
||||||
"Brown Mushroom",
|
|
||||||
"Brown Terracotta",
|
|
||||||
"Brown Wool",
|
|
||||||
"Bubble Column",
|
|
||||||
"Bubble Coral",
|
|
||||||
"Cactus",
|
|
||||||
"Cake",
|
|
||||||
"Calcite",
|
|
||||||
"Campfire",
|
|
||||||
"Candle",
|
|
||||||
"Carrots",
|
|
||||||
"Cartography Table",
|
|
||||||
"Carved Pumpkin",
|
|
||||||
"Cauldron",
|
|
||||||
"Cave Vines",
|
|
||||||
"Chain",
|
|
||||||
"Chest",
|
|
||||||
"Chorus Flower",
|
|
||||||
"Chorus Plant",
|
|
||||||
"Clay",
|
|
||||||
"Coal Ore",
|
|
||||||
"Coarse Dirt",
|
|
||||||
"Cobbled Deepslate",
|
|
||||||
"Cobblestone Slab",
|
|
||||||
"Cobblestone Stairs",
|
|
||||||
"Cobblestone Wall",
|
|
||||||
"Cobblestone",
|
|
||||||
"Cobweb",
|
|
||||||
"Cocoa",
|
|
||||||
"Composter",
|
|
||||||
"Conduit",
|
|
||||||
"Copper Ore",
|
|
||||||
"Cornflower",
|
|
||||||
"Crafting Table",
|
|
||||||
"Creeper Head",
|
|
||||||
"Crimson Button",
|
|
||||||
"Crimson Door",
|
|
||||||
"Crimson Fence",
|
|
||||||
"Crimson Fungus",
|
|
||||||
"Crimson Hyphae",
|
|
||||||
"Crimson Nylium",
|
|
||||||
"Crimson Planks",
|
|
||||||
"Crimson Roots",
|
|
||||||
"Crimson Sign",
|
|
||||||
"Crimson Slab",
|
|
||||||
"Crimson Stairs",
|
|
||||||
"Crimson Stem",
|
|
||||||
"Crimson Trapdoor",
|
|
||||||
"Crying Obsidian",
|
|
||||||
"Cyan Candle",
|
|
||||||
"Cyan Carpet",
|
|
||||||
"Cyan Concrete",
|
|
||||||
"Cyan Terracotta",
|
|
||||||
"Cyan Wool",
|
|
||||||
"Dandelion",
|
|
||||||
"Dead Bush",
|
|
||||||
"Deepslate Bricks",
|
|
||||||
"Deepslate Tiles",
|
|
||||||
"Deepslate",
|
|
||||||
"Detector Rail",
|
|
||||||
"Diamond Ore",
|
|
||||||
"Diorite Slab",
|
|
||||||
"Diorite Stairs",
|
|
||||||
"Diorite Wall",
|
|
||||||
"Diorite",
|
|
||||||
"Dirt",
|
|
||||||
"Dispenser",
|
|
||||||
"Dragon Egg",
|
|
||||||
"Dragon Head",
|
|
||||||
"Dripstone Block",
|
|
||||||
"Dropper",
|
|
||||||
"Emerald Ore",
|
|
||||||
"Enchanting Table",
|
|
||||||
"End Gateway",
|
|
||||||
"End Portal",
|
|
||||||
"End Rod",
|
|
||||||
"End Stone",
|
|
||||||
"Ender Chest",
|
|
||||||
"Farmland",
|
|
||||||
"Fern",
|
|
||||||
"Fire Coral",
|
|
||||||
"Fletching Table",
|
|
||||||
"Flower Pot",
|
|
||||||
"Flowering Azalea",
|
|
||||||
"Frosted Ice",
|
|
||||||
"Furnace",
|
|
||||||
"Glass Pane",
|
|
||||||
"Glass",
|
|
||||||
"Glowstone",
|
|
||||||
"Gold Ore",
|
|
||||||
"Granite Slab",
|
|
||||||
"Granite Stairs",
|
|
||||||
"Granite Wall",
|
|
||||||
"Granite",
|
|
||||||
"Grass Block",
|
|
||||||
"Grass",
|
|
||||||
"Gravel",
|
|
||||||
"Gray Candle",
|
|
||||||
"Gray Carpet",
|
|
||||||
"Gray Concrete",
|
|
||||||
"Gray Terracotta",
|
|
||||||
"Gray Wool",
|
|
||||||
"Green Candle",
|
|
||||||
"Green Carpet",
|
|
||||||
"Green Concrete",
|
|
||||||
"Green Terracotta",
|
|
||||||
"Green Wool",
|
|
||||||
"Grindstone",
|
|
||||||
"Hay Bale",
|
|
||||||
"Honey Block",
|
|
||||||
"Hopper",
|
|
||||||
"Horn Coral",
|
|
||||||
"Ice",
|
|
||||||
"Iron Bars",
|
|
||||||
"Iron Door",
|
|
||||||
"Iron Ore",
|
|
||||||
"Iron Trapdoor",
|
|
||||||
"Jack o'Lantern",
|
|
||||||
"Jigsaw Block",
|
|
||||||
"Jukebox",
|
|
||||||
"Jungle Button",
|
|
||||||
"Jungle Door",
|
|
||||||
"Jungle Fence",
|
|
||||||
"Jungle Leaves",
|
|
||||||
"Jungle Log",
|
|
||||||
"Jungle Planks",
|
|
||||||
"Jungle Sapling",
|
|
||||||
"Jungle Sign",
|
|
||||||
"Jungle Slab",
|
|
||||||
"Jungle Stairs",
|
|
||||||
"Jungle Trapdoor",
|
|
||||||
"Jungle Wood",
|
|
||||||
"Kelp Plant",
|
|
||||||
"Kelp",
|
|
||||||
"Ladder",
|
|
||||||
"Lantern",
|
|
||||||
"Large Fern",
|
|
||||||
"Lava",
|
|
||||||
"Lectern",
|
|
||||||
"Lever",
|
|
||||||
"Lightning Rod",
|
|
||||||
"Lilac",
|
|
||||||
"Lily Pad",
|
|
||||||
"Lime Candle",
|
|
||||||
"Lime Carpet",
|
|
||||||
"Lime Concrete",
|
|
||||||
"Lime Terracotta",
|
|
||||||
"Lime Wool",
|
|
||||||
"Lodestone",
|
|
||||||
"Loom",
|
|
||||||
"Magenta Candle",
|
|
||||||
"Magenta Carpet",
|
|
||||||
"Magenta Concrete",
|
|
||||||
"Magenta Terracotta",
|
|
||||||
"Magenta Wool",
|
|
||||||
"Magma Block",
|
|
||||||
"Mangrove Button",
|
|
||||||
"Mangrove Door",
|
|
||||||
"Mangrove Fence",
|
|
||||||
"Mangrove Leaves",
|
|
||||||
"Mangrove Log",
|
|
||||||
"Mangrove Planks",
|
|
||||||
"Mangrove Propagule",
|
|
||||||
"Mangrove Roots",
|
|
||||||
"Mangrove Sign",
|
|
||||||
"Mangrove Slab",
|
|
||||||
"Mangrove Stairs",
|
|
||||||
"Mangrove Trapdoor",
|
|
||||||
"Mangrove Wood",
|
|
||||||
"Melon Stem",
|
|
||||||
"Melon",
|
|
||||||
"Moss Block",
|
|
||||||
"Moss Carpet",
|
|
||||||
"Mossy Cobblestone",
|
|
||||||
"Mud Bricks",
|
|
||||||
"Mud",
|
|
||||||
"Mushroom Stem",
|
|
||||||
"Mycelium",
|
|
||||||
"Nether Bricks",
|
|
||||||
"Nether Portal",
|
|
||||||
"Nether Sprouts",
|
|
||||||
"Nether Wart",
|
|
||||||
"Netherrack",
|
|
||||||
"Note Block",
|
|
||||||
"Oak Button",
|
|
||||||
"Oak Door",
|
|
||||||
"Oak Fence",
|
|
||||||
"Oak Leaves",
|
|
||||||
"Oak Log",
|
|
||||||
"Oak Planks",
|
|
||||||
"Oak Sapling",
|
|
||||||
"Oak Sign",
|
|
||||||
"Oak Slab",
|
|
||||||
"Oak Stairs",
|
|
||||||
"Oak Trapdoor",
|
|
||||||
"Oak Wood",
|
|
||||||
"Observer",
|
|
||||||
"Obsidian",
|
|
||||||
"Ominous Banner",
|
|
||||||
"Orange Candle",
|
|
||||||
"Orange Carpet",
|
|
||||||
"Orange Concrete",
|
|
||||||
"Orange Terracotta",
|
|
||||||
"Orange Tulip",
|
|
||||||
"Orange Wool",
|
|
||||||
"Oxeye Daisy",
|
|
||||||
"Oxidized Copper",
|
|
||||||
"Packed Ice",
|
|
||||||
"Packed Mud",
|
|
||||||
"Peony",
|
|
||||||
"Pink Candle",
|
|
||||||
"Pink Carpet",
|
|
||||||
"Pink Concrete",
|
|
||||||
"Pink Terracotta",
|
|
||||||
"Pink Tulip",
|
|
||||||
"Pink Wool",
|
|
||||||
"Piston",
|
|
||||||
"Podzol",
|
|
||||||
"Pointed Dripstone",
|
|
||||||
"Polished Andesite",
|
|
||||||
"Polished Basalt",
|
|
||||||
"Polished Blackstone",
|
|
||||||
"Polished Deepslate",
|
|
||||||
"Polished Diorite",
|
|
||||||
"Polished Granite",
|
|
||||||
"Poppy",
|
|
||||||
"Potatoes",
|
|
||||||
"Powder Snow",
|
|
||||||
"Powered Rail",
|
|
||||||
"Prismarine Bricks",
|
|
||||||
"Prismarine Slab",
|
|
||||||
"Prismarine Stairs",
|
|
||||||
"Prismarine Wall",
|
|
||||||
"Prismarine",
|
|
||||||
"Pumpkin Stem",
|
|
||||||
"Pumpkin",
|
|
||||||
"Purple Candle",
|
|
||||||
"Purple Carpet",
|
|
||||||
"Purple Concrete",
|
|
||||||
"Purple Terracotta",
|
|
||||||
"Purple Wool",
|
|
||||||
"Purpur Block",
|
|
||||||
"Purpur Pillar",
|
|
||||||
"Purpur Slab",
|
|
||||||
"Purpur Stairs",
|
|
||||||
"Quartz Bricks",
|
|
||||||
"Quartz Pillar",
|
|
||||||
"Quartz Slab",
|
|
||||||
"Quartz Stairs",
|
|
||||||
"Rail",
|
|
||||||
"Red Candle",
|
|
||||||
"Red Carpet",
|
|
||||||
"Red Concrete",
|
|
||||||
"Red Mushroom",
|
|
||||||
"Red Sand",
|
|
||||||
"Red Sandstone",
|
|
||||||
"Red Terracotta",
|
|
||||||
"Red Tulip",
|
|
||||||
"Red Wool",
|
|
||||||
"Redstone Lamp",
|
|
||||||
"Redstone Ore",
|
|
||||||
"Redstone Torch",
|
|
||||||
"Redstone Wire",
|
|
||||||
"Reinforced Deepslate",
|
|
||||||
"Rooted Dirt",
|
|
||||||
"Rose Bush",
|
|
||||||
"Sand",
|
|
||||||
"Sandstone Slab",
|
|
||||||
"Sandstone Stairs",
|
|
||||||
"Sandstone Wall",
|
|
||||||
"Sandstone",
|
|
||||||
"Scaffolding",
|
|
||||||
"Sea Lantern",
|
|
||||||
"Sea Pickle",
|
|
||||||
"Seagrass",
|
|
||||||
"Shroomlight",
|
|
||||||
"Shulker Box",
|
|
||||||
"Skeleton Skull",
|
|
||||||
"Slime Block",
|
|
||||||
"Smithing Table",
|
|
||||||
"Smoker",
|
|
||||||
"Smooth Basalt",
|
|
||||||
"Smooth Sandstone",
|
|
||||||
"Smooth Stone",
|
|
||||||
"Snow Block",
|
|
||||||
"Snow",
|
|
||||||
"Soul Lantern",
|
|
||||||
"Soul Sand",
|
|
||||||
"Soul Torch",
|
|
||||||
"Sponge",
|
|
||||||
"Spore Blossom",
|
|
||||||
"Spruce Button",
|
|
||||||
"Spruce Door",
|
|
||||||
"Spruce Fence",
|
|
||||||
"Spruce Leaves",
|
|
||||||
"Spruce Log",
|
|
||||||
"Spruce Planks",
|
|
||||||
"Spruce Sapling",
|
|
||||||
"Spruce Sign",
|
|
||||||
"Spruce Slab",
|
|
||||||
"Spruce Stairs",
|
|
||||||
"Spruce Trapdoor",
|
|
||||||
"Spruce Wood",
|
|
||||||
"Sticky Piston",
|
|
||||||
"Stone Bricks",
|
|
||||||
"Stone Button",
|
|
||||||
"Stone Slab",
|
|
||||||
"Stone Stairs",
|
|
||||||
"Stone",
|
|
||||||
"Stonecutter",
|
|
||||||
"Sugar Cane",
|
|
||||||
"Sunflower",
|
|
||||||
"TNT",
|
|
||||||
"Target",
|
|
||||||
"Terracotta",
|
|
||||||
"Tinted Glass",
|
|
||||||
"Torch",
|
|
||||||
"Trapped Chest",
|
|
||||||
"Tripwire Hook",
|
|
||||||
"Tripwire",
|
|
||||||
"Tube Coral",
|
|
||||||
"Tuff",
|
|
||||||
"Turtle Egg",
|
|
||||||
"Twisting Vines",
|
|
||||||
"Verdant Froglight",
|
|
||||||
"Vines",
|
|
||||||
"Warped Button",
|
|
||||||
"Warped Door",
|
|
||||||
"Warped Fence",
|
|
||||||
"Warped Fungus",
|
|
||||||
"Warped Hyphae",
|
|
||||||
"Warped Nylium",
|
|
||||||
"Warped Planks",
|
|
||||||
"Warped Roots",
|
|
||||||
"Warped Sign",
|
|
||||||
"Warped Slab",
|
|
||||||
"Warped Stairs",
|
|
||||||
"Warped Stem",
|
|
||||||
"Warped Trapdoor",
|
|
||||||
"Water",
|
|
||||||
"Weeping Vines",
|
|
||||||
"Wheat Crops",
|
|
||||||
"White Candle",
|
|
||||||
"White Carpet",
|
|
||||||
"White Concrete",
|
|
||||||
"White Terracotta",
|
|
||||||
"White Tulip",
|
|
||||||
"White Wool",
|
|
||||||
"Wither Rose",
|
|
||||||
"Yellow Candle",
|
|
||||||
"Yellow Carpet",
|
|
||||||
"Yellow Concrete",
|
|
||||||
"Yellow Terracotta",
|
|
||||||
"Yellow Wool",
|
|
||||||
"Zombie Head"
|
|
||||||
};
|
|
||||||
|
|
||||||
public static string GenerateFrom(Guid guid) {
|
|
||||||
var rand = new Random(StableHashCode.ForString(guid.ToString()));
|
|
||||||
string prefix = Prefixes[rand.Next(Prefixes.Length)];
|
|
||||||
string suffix = Suffixes[rand.Next(Suffixes.Length)];
|
|
||||||
return string.Concat(prefix, " ", suffix);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -18,7 +18,7 @@ PosixSignals.RegisterCancellation(cancellationTokenSource, static () => {
|
|||||||
try {
|
try {
|
||||||
PhantomLogger.Root.InformationHeading("Initializing Phantom Panel agent...");
|
PhantomLogger.Root.InformationHeading("Initializing Phantom Panel agent...");
|
||||||
|
|
||||||
var (serverHost, serverPort, javaSearchPath, authToken, authTokenFilePath, agentNameOrEmpty, maxInstances, maxMemory, allowedServerPorts, allowedRconPorts) = Variables.LoadOrExit();
|
var (serverHost, serverPort, javaSearchPath, authToken, authTokenFilePath, agentName, maxInstances, maxMemory, allowedServerPorts, allowedRconPorts) = Variables.LoadOrExit();
|
||||||
|
|
||||||
AgentAuthToken agentAuthToken;
|
AgentAuthToken agentAuthToken;
|
||||||
try {
|
try {
|
||||||
@@ -46,7 +46,6 @@ try {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var agentName = string.IsNullOrEmpty(agentNameOrEmpty) ? AgentNameGenerator.GenerateFrom(agentGuid.Value) : agentNameOrEmpty;
|
|
||||||
var agentInfo = new AgentInfo(agentGuid.Value, agentName, AgentVersion, maxInstances, maxMemory, allowedServerPorts, allowedRconPorts);
|
var agentInfo = new AgentInfo(agentGuid.Value, agentName, AgentVersion, maxInstances, maxMemory, allowedServerPorts, allowedRconPorts);
|
||||||
var agentServices = new AgentServices(agentInfo, folders);
|
var agentServices = new AgentServices(agentInfo, folders);
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ sealed record Variables(
|
|||||||
string JavaSearchPath,
|
string JavaSearchPath,
|
||||||
string? AuthToken,
|
string? AuthToken,
|
||||||
string? AuthTokenFilePath,
|
string? AuthTokenFilePath,
|
||||||
string AgentNameOrEmpty,
|
string AgentName,
|
||||||
ushort MaxInstances,
|
ushort MaxInstances,
|
||||||
RamAllocationUnits MaxMemory,
|
RamAllocationUnits MaxMemory,
|
||||||
AllowedPorts AllowedServerPorts,
|
AllowedPorts AllowedServerPorts,
|
||||||
@@ -27,7 +27,7 @@ sealed record Variables(
|
|||||||
javaSearchPath,
|
javaSearchPath,
|
||||||
authToken,
|
authToken,
|
||||||
authTokenFilePath,
|
authTokenFilePath,
|
||||||
EnvironmentVariables.GetString("AGENT_NAME").OrDefault(string.Empty),
|
EnvironmentVariables.GetString("AGENT_NAME").OrThrow,
|
||||||
(ushort) EnvironmentVariables.GetInteger("MAX_INSTANCES", min: 1, max: 10000).OrThrow,
|
(ushort) EnvironmentVariables.GetInteger("MAX_INSTANCES", min: 1, max: 10000).OrThrow,
|
||||||
EnvironmentVariables.GetString("MAX_MEMORY").MapParse(RamAllocationUnits.FromString).OrThrow,
|
EnvironmentVariables.GetString("MAX_MEMORY").MapParse(RamAllocationUnits.FromString).OrThrow,
|
||||||
EnvironmentVariables.GetString("ALLOWED_SERVER_PORTS").MapParse(AllowedPorts.FromString).OrThrow,
|
EnvironmentVariables.GetString("ALLOWED_SERVER_PORTS").MapParse(AllowedPorts.FromString).OrThrow,
|
||||||
|
@@ -9,4 +9,5 @@ public interface IMessageToAgentListener {
|
|||||||
Task HandleLaunchInstance(LaunchInstanceMessage message);
|
Task HandleLaunchInstance(LaunchInstanceMessage message);
|
||||||
Task HandleStopInstance(StopInstanceMessage message);
|
Task HandleStopInstance(StopInstanceMessage message);
|
||||||
Task HandleSendCommandToInstance(SendCommandToInstanceMessage message);
|
Task HandleSendCommandToInstance(SendCommandToInstanceMessage message);
|
||||||
|
Task HandleShutdownAgent(ShutdownAgentMessage message);
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@ public static class MessageRegistries {
|
|||||||
ToAgent.Add<LaunchInstanceMessage>(3);
|
ToAgent.Add<LaunchInstanceMessage>(3);
|
||||||
ToAgent.Add<StopInstanceMessage>(4);
|
ToAgent.Add<StopInstanceMessage>(4);
|
||||||
ToAgent.Add<SendCommandToInstanceMessage>(5);
|
ToAgent.Add<SendCommandToInstanceMessage>(5);
|
||||||
|
ToAgent.Add<ShutdownAgentMessage>(6);
|
||||||
|
|
||||||
ToServer.Add<RegisterAgentMessage>(0);
|
ToServer.Add<RegisterAgentMessage>(0);
|
||||||
ToServer.Add<UnregisterAgentMessage>(1);
|
ToServer.Add<UnregisterAgentMessage>(1);
|
||||||
|
@@ -0,0 +1,10 @@
|
|||||||
|
using MessagePack;
|
||||||
|
|
||||||
|
namespace Phantom.Common.Messages.ToAgent;
|
||||||
|
|
||||||
|
[MessagePackObject]
|
||||||
|
public sealed record ShutdownAgentMessage : IMessageToAgent {
|
||||||
|
public Task Accept(IMessageToAgentListener listener) {
|
||||||
|
return listener.HandleShutdownAgent(this);
|
||||||
|
}
|
||||||
|
}
|
@@ -92,7 +92,7 @@ public sealed class AgentManager {
|
|||||||
agents.Update(agentGuid, static agent => agent with { LastPing = DateTimeOffset.Now });
|
agents.Update(agentGuid, static agent => agent with { LastPing = DateTimeOffset.Now });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> SendMessage<TMessage>(Guid guid, TMessage message) where TMessage : IMessageToAgent {
|
public async Task<bool> SendMessage<TMessage>(Guid guid, TMessage message) where TMessage : IMessageToAgent {
|
||||||
var connection = agents.GetConnection(guid);
|
var connection = agents.GetConnection(guid);
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
await connection.SendMessage(message);
|
await connection.SendMessage(message);
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
@page "/agents"
|
@page "/agents"
|
||||||
@using System.Collections.Immutable
|
@using System.Collections.Immutable
|
||||||
@using Phantom.Common.Data.Agent
|
@using Phantom.Common.Data.Agent
|
||||||
|
@using Phantom.Common.Messages.ToAgent
|
||||||
@using Phantom.Server.Services.Agents
|
@using Phantom.Server.Services.Agents
|
||||||
@using Phantom.Utils.Collections
|
@using Phantom.Utils.Collections
|
||||||
@implements IDisposable
|
@implements IDisposable
|
||||||
@@ -20,11 +21,13 @@
|
|||||||
<th style="width: 350px;">Identifier</th>
|
<th style="width: 350px;">Identifier</th>
|
||||||
<th style="width: 150px;" class="text-center">Status</th>
|
<th style="width: 150px;" class="text-center">Status</th>
|
||||||
<th style="width: 250px;" class="text-right">Last Ping</th>
|
<th style="width: 250px;" class="text-right">Last Ping</th>
|
||||||
|
<th style="width: 200px;">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@if (!agentTable.IsEmpty) {
|
@if (!agentTable.IsEmpty) {
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (var agent in agentTable) {
|
@foreach (var row in agentTable) {
|
||||||
|
var agent = row.Agent;
|
||||||
var stats = agentStats.TryGetValue(agent.Guid, out var s) ? s : null;
|
var stats = agentStats.TryGetValue(agent.Guid, out var s) ? s : null;
|
||||||
var usedInstances = stats?.UsedInstances;
|
var usedInstances = stats?.UsedInstances;
|
||||||
var usedMemory = stats?.UsedMemory.InMegabytes;
|
var usedMemory = stats?.UsedMemory.InMegabytes;
|
||||||
@@ -48,6 +51,9 @@
|
|||||||
@if (agent.IsOnline) {
|
@if (agent.IsOnline) {
|
||||||
<td class="text-center text-success">Online</td>
|
<td class="text-center text-success">Online</td>
|
||||||
<td class="text-right"></td>
|
<td class="text-right"></td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-danger btn-sm" @onclick="() => ShutdownAgent(agent.Guid)" disabled="@row.IsShutdownButtonDisabled">Shutdown</button>
|
||||||
|
</td>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<td class="text-center text-danger">Offline</td>
|
<td class="text-center text-danger">Offline</td>
|
||||||
@@ -59,6 +65,7 @@
|
|||||||
else {
|
else {
|
||||||
<td class="text-right">-</td>
|
<td class="text-right">-</td>
|
||||||
}
|
}
|
||||||
|
<td>-</td>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@@ -66,7 +73,7 @@
|
|||||||
}
|
}
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7">
|
<td colspan="8">
|
||||||
@if (agentTable.IsEmpty) {
|
@if (agentTable.IsEmpty) {
|
||||||
<text>No agents registered.</text>
|
<text>No agents registered.</text>
|
||||||
}
|
}
|
||||||
@@ -78,13 +85,15 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
private readonly Table<Agent, Guid> agentTable = new();
|
private readonly Table<AgentRow, Guid> agentTable = new();
|
||||||
private ImmutableDictionary<Guid, AgentStats> agentStats = ImmutableDictionary<Guid, AgentStats>.Empty;
|
private ImmutableDictionary<Guid, AgentStats> agentStats = ImmutableDictionary<Guid, AgentStats>.Empty;
|
||||||
|
|
||||||
|
private readonly record struct AgentRow(Agent Agent, bool IsShutdownButtonDisabled = false);
|
||||||
|
|
||||||
protected override void OnInitialized() {
|
protected override void OnInitialized() {
|
||||||
AgentManager.AgentsChanged.Subscribe(this, agents => {
|
AgentManager.AgentsChanged.Subscribe(this, agents => {
|
||||||
var sortedAgents = agents.Sort(static (a1, a2) => a1.Name.CompareTo(a2.Name));
|
var sortedAgents = agents.Sort(static (a1, a2) => a1.Name.CompareTo(a2.Name));
|
||||||
agentTable.UpdateFrom(sortedAgents, static agent => agent.Guid, static agent => agent, static (agent, _) => agent);
|
agentTable.UpdateFrom(sortedAgents, static agent => agent.Guid, static agent => new AgentRow(agent), static (agent, row) => row with { Agent = agent });
|
||||||
InvokeAsync(StateHasChanged);
|
InvokeAsync(StateHasChanged);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -94,6 +103,12 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ShutdownAgent(Guid guid) {
|
||||||
|
if (agentTable.TryUpdateRow(guid, static row => row with { IsShutdownButtonDisabled = true })) {
|
||||||
|
await AgentManager.SendMessage(guid, new ShutdownAgentMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IDisposable.Dispose() {
|
void IDisposable.Dispose() {
|
||||||
AgentManager.AgentsChanged.Unsubscribe(this);
|
AgentManager.AgentsChanged.Unsubscribe(this);
|
||||||
AgentStatsManager.AgentStatsChanged.Unsubscribe(this);
|
AgentStatsManager.AgentStatsChanged.Unsubscribe(this);
|
||||||
|
Reference in New Issue
Block a user