Skip to content

Commit

Permalink
Merge pull request #673 from starfi5h/pr-chat
Browse files Browse the repository at this point in the history
Add CLI argument -newgame-cfg and changes to chat format
  • Loading branch information
starfi5h authored Apr 10, 2024
2 parents f95aecd + 8942c9b commit 2d9b98b
Show file tree
Hide file tree
Showing 12 changed files with 301 additions and 24 deletions.
6 changes: 5 additions & 1 deletion NebulaModel/MultiplayerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ public bool StreamerMode
[DisplayName("Auto Open Chat")]
[Category("Chat")]
[Description("Auto open chat window when receiving message from other players")]
public bool AutoOpenChat { get; set; } = true;
public bool AutoOpenChat { get; set; } = false;

[DisplayName("Show Timestamp")]
[Category("Chat")]
public bool EnableTimestamp { get; set; } = true;

[DisplayName("Show system warn message")]
[Category("Chat")]
Expand Down
19 changes: 19 additions & 0 deletions NebulaModel/Packets/Chat/PlayerDataCommandPacket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using NebulaModel.DataStructures;

namespace NebulaModel.Packets.Chat;

public class PlayerDataCommandPacket
{
public PlayerDataCommandPacket() { }

public PlayerDataCommandPacket(string command, string message, PlayerData playerData = null)
{
Command = command;
Message = message;
PlayerData = playerData;
}

public string Command { get; set; }
public string Message { get; set; }
public PlayerData PlayerData { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,11 @@ protected override void ProcessPacket(NewChatMessagePacket packet, NebulaConnect

if (IsHost)
{
var player = Players.Get(conn);
Server.SendPacketExclude(packet, conn);
}

var sentAt = packet.SentAt == 0 ? DateTime.Now : DateTime.FromBinary(packet.SentAt);
ChatManager.Instance.SendChatMessage(
string.IsNullOrEmpty(packet.UserName)
? $"[{sentAt:HH:mm}] {packet.MessageText}"
: $"[{sentAt:HH:mm}] [{packet.UserName}] : {packet.MessageText}", packet.MessageType);
ChatManager.Instance.SendChatMessage(ChatManager.FormatChatMessage(sentAt, packet.UserName, packet.MessageText),
packet.MessageType);
}
}
62 changes: 62 additions & 0 deletions NebulaNetwork/PacketProcessors/Chat/PlyaerDataCommmandProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#region

using NebulaAPI.Packets;
using NebulaModel.DataStructures.Chat;
using NebulaModel.Networking;
using NebulaModel.Packets;
using NebulaModel.Packets.Chat;
using NebulaWorld;
using NebulaWorld.Chat.Commands;
using NebulaWorld.MonoBehaviours.Local.Chat;

#endregion

namespace NebulaNetwork.PacketProcessors.Chat;

[RegisterPacketProcessor]
internal class PlyaerDataCommmandProcessor : PacketProcessor<PlayerDataCommandPacket>
{
protected override void ProcessPacket(PlayerDataCommandPacket packet, NebulaConnection conn)
{
if (IsHost)
{
packet.PlayerData = null;
var playerSaves = SaveManager.PlayerSaves;
switch (packet.Command)
{
case "list":
packet.Message = PlayerDataCommandHandler.GetPlayerDataListString();
break;

case "load":
var input = packet.Message;
packet.Message = "Unable to find the target player data!";
foreach (var pair in playerSaves)
{
if (input == pair.Key.Substring(0, input.Length) || input == pair.Value.Username)
{
packet.Message = $"Load [{pair.Key.Substring(0, 5)}] {pair.Value.Username}";
packet.PlayerData = (NebulaModel.DataStructures.PlayerData)pair.Value;
break;
}
}
break;

default:
packet.Message = "Unknown command: " + packet.Command;
break;
}
conn.SendPacket(packet);
return;
}

if (IsClient)
{
ChatManager.Instance.SendChatMessage(packet.Message, ChatMessageType.CommandOutputMessage);
if (packet.PlayerData != null)
{
PlayerDataCommandHandler.LoadPlayerData(packet.PlayerData);
}
}
}
}
63 changes: 63 additions & 0 deletions NebulaPatcher/NebulaPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Reflection;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using NebulaAPI.Interfaces;
using NebulaModel.Logger;
Expand Down Expand Up @@ -79,6 +80,18 @@ private void Awake()
}
}

if (args[i] == "-newgame-cfg")
{
newgameArgExists = true;
var gameDesc = new GameDesc();
var random = new DotNet35Random((int)(DateTime.UtcNow.Ticks / 10000L));
gameDesc.SetForNewGame(UniverseGen.algoVersion, random.Next(100000000), 64, 1, 1f);
SetGameDescFromConfigFile(gameDesc);
Log.Info($">> Creating new game ({gameDesc.galaxySeed}, {gameDesc.starCount}, {gameDesc.resourceMultiplier:F1})");
GameStatesManager.NewGameDesc = gameDesc;
didLoad = true;
}

if (args[i] == "-load" && i + 1 < args.Length)
{
loadArgExists = true;
Expand Down Expand Up @@ -232,6 +245,56 @@ public static void StartDedicatedServer(GameDesc gameDesc)
}
}

public static void SetGameDescFromConfigFile(GameDesc gameDesc)
{
var customFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "nebulaGameDescSettings.cfg"), true);

var galaxySeed = customFile.Bind("Basic", "galaxySeed", -1,
"Cluster Seed. Negative value: Random or remain the same.").Value;
if (galaxySeed >= 0)
{
gameDesc.galaxySeed = galaxySeed;
}

var starCount = customFile.Bind("Basic", "starCount", -1,
"Number of Stars. Negative value: Default(64) or remain the same.").Value;
if (starCount >= 0)
{
gameDesc.starCount = starCount;
}

var resourceMultiplier = customFile.Bind("Basic", "resourceMultiplier", -1f,
"Resource Multiplier. Infinte = 100. Negative value: Default(1.0f) or remain the same.").Value;
if (resourceMultiplier >= 0f)
{
gameDesc.resourceMultiplier = resourceMultiplier;
}

gameDesc.isPeaceMode = customFile.Bind("General", "isPeaceMode", false,
"False: Enable enemy force (combat mode)").Value;
gameDesc.isSandboxMode = customFile.Bind("General", "isSandboxMode", false,
"True: Enable creative mode").Value;

gameDesc.combatSettings.aggressiveness = customFile.Bind("Combat", "aggressiveness", 1f,
new ConfigDescription("Aggressiveness (Dummy = -1, Rampage = 3)", new AcceptableValueList<float>(-1f, 0f, 0.5f, 1f, 2f, 3f))).Value;
gameDesc.combatSettings.initialLevel = customFile.Bind("Combat", "initialLevel", 0,
new ConfigDescription("Initial Level (Original range: 0 to 10)", new AcceptableValueRange<int>(0, 30))).Value;
gameDesc.combatSettings.initialGrowth = customFile.Bind("Combat", "initialGrowth", 1f,
"Initial Growth (Original range: 0 to 200%)").Value;
gameDesc.combatSettings.initialColonize = customFile.Bind("Combat", "initialColonize", 1f,
"Initial Occupation (Original range: 1% to 200%").Value;
gameDesc.combatSettings.maxDensity = customFile.Bind("Combat", "maxDensity", 1f,
"Max Density (Original range: 1 to 3)").Value;
gameDesc.combatSettings.growthSpeedFactor = customFile.Bind("Combat", "growthSpeedFactor", 1f,
"Growth Speed (Original range: 25% to 300%)").Value;
gameDesc.combatSettings.powerThreatFactor = customFile.Bind("Combat", "powerThreatFactor", 1f,
"Power Threat Factor (Original range: 1% to 1000%)").Value;
gameDesc.combatSettings.battleThreatFactor = customFile.Bind("Combat", "battleThreatFactor", 1f,
"Combat Threat Factor (Original range: 1% to 1000%)").Value;
gameDesc.combatSettings.battleExpFactor = customFile.Bind("Combat", "battleExpFactor", 1f,
"Combat XP Factor (Original range: 1% to 1000%)").Value;
}

private static async void ActivityManager_OnActivityJoin(string secret)
{
if (Multiplayer.IsActive)
Expand Down
1 change: 1 addition & 0 deletions NebulaWorld/Chat/ChatCommandRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static ChatCommandRegistry()
RegisterCommand("reconnect", new ReconnectCommandHandler(), "r");
RegisterCommand("server", new ServerCommandHandler());
RegisterCommand("playerdata", new PlayerDataCommandHandler());
RegisterCommand("dev", new DevCommandHandler());
}

private static void RegisterCommand(string commandName, IChatCommandHandler commandHandlerHandler, params string[] aliases)
Expand Down
57 changes: 57 additions & 0 deletions NebulaWorld/Chat/Commands/DevCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#region

using NebulaWorld.MonoBehaviours.Local.Chat;
using NebulaModel.DataStructures.Chat;
using HarmonyLib;

#endregion

namespace NebulaWorld.Chat.Commands;

public class DevCommandHandler : IChatCommandHandler
{
public void Execute(ChatWindow window, string[] parameters)
{
if (parameters.Length < 1)
{
throw new ChatCommandUsageException("Not enough arguments!".Translate());
}

switch (parameters[0])
{
case "sandbox":
{
GameMain.sandboxToolsEnabled = !GameMain.sandboxToolsEnabled;
GameMain.data.gameDesc.isSandboxMode = GameMain.sandboxToolsEnabled;
window.SendLocalChatMessage("SandboxTool enable: " + GameMain.sandboxToolsEnabled, ChatMessageType.CommandOutputMessage);
return;
}
case "load-cfg":
{
window.SendLocalChatMessage("Overwrite settings from nebulaGameDescSettings.cfg", ChatMessageType.CommandOutputMessage);
AccessTools.Method(AccessTools.TypeByName("NebulaPatcher.NebulaPlugin"), "SetGameDescFromConfigFile").Invoke(null, [GameMain.data.gameDesc]);
return;
}

case "self-destruct":
{
GameMain.mainPlayer.Kill();
return;
}

default:
window.SendLocalChatMessage("Unknown command: " + parameters[0], ChatMessageType.CommandOutputMessage);
return;
}
}

public string GetDescription()
{
return "Developer/Sandbox tool commands".Translate();
}

public string[] GetUsage()
{
return ["sandbox", "load-cfg", "self-destruct"];
}
}
50 changes: 38 additions & 12 deletions NebulaWorld/Chat/Commands/PlayerDataCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
#region

using NebulaWorld.MonoBehaviours.Local.Chat;
using System.Collections.Generic;
using NebulaAPI.GameState;
using HarmonyLib;
using NebulaModel.DataStructures.Chat;
using System.IO;
using NebulaModel;
using NebulaModel.Logger;
using NebulaAPI.DataStructures;
using NebulaModel.Networking;
using NebulaModel.Packets.Players;
using NebulaModel.Packets.Chat;

#endregion

Expand All @@ -26,26 +25,32 @@ public void Execute(ChatWindow window, string[] parameters)
}

// Due to dependency order, get SaveManager.playerSaves by reflection
var saveManagerType = AccessTools.TypeByName("NebulaNetwork.SaveManager");
var playerSaves = (Dictionary<string, IPlayerData>)AccessTools.Field(saveManagerType, "playerSaves").GetValue(null);
var playerSaves = SaveManager.PlayerSaves;

switch (parameters[0])
{
case "list":
{
var resp = $"Player count in .server file: {playerSaves.Count}\n";
foreach (var pair in playerSaves)
if (Multiplayer.Session.IsClient)
{
resp += $"[{pair.Key.Substring(0, 5)}] {pair.Value.Username}";
Multiplayer.Session.Client.SendPacket(new PlayerDataCommandPacket("list", ""));
return;
}
window.SendLocalChatMessage(resp, ChatMessageType.CommandOutputMessage);
break;

window.SendLocalChatMessage(GetPlayerDataListString(), ChatMessageType.CommandOutputMessage);
return;
}
case "load" when parameters.Length < 2:
throw new ChatCommandUsageException("Need to specifiy hash string or name of a player!");
case "load":
{
var input = parameters[1];
if (Multiplayer.Session.IsClient)
{
Multiplayer.Session.Client.SendPacket(new PlayerDataCommandPacket("load", input));
return;
}

foreach (var pair in playerSaves)
{
if (input == pair.Key.Substring(0, input.Length) || input == pair.Value.Username)
Expand All @@ -55,12 +60,18 @@ public void Execute(ChatWindow window, string[] parameters)
return;
}
}
break;
window.SendLocalChatMessage("Unable to find the target player data!", ChatMessageType.CommandOutputMessage);
return;
}
case "remove" when parameters.Length < 2:
throw new ChatCommandUsageException("Need to specifiy hash string or name of a player!");
case "remove":
{
if (Multiplayer.Session.IsClient)
{
throw new ChatCommandUsageException("remove command is not available in client!");
}

var input = parameters[1];
var removeHash = "";
foreach (var pair in playerSaves)
Expand All @@ -72,7 +83,10 @@ public void Execute(ChatWindow window, string[] parameters)
break;
}
}
playerSaves.Remove(removeHash);
if (!SaveManager.TryRemove(removeHash))
{
window.SendLocalChatMessage("Unable to find the target player data!", ChatMessageType.CommandOutputMessage);
}
break;
}
}
Expand All @@ -88,7 +102,19 @@ public string[] GetUsage()
return ["list", "load <hashString>", "remove <hashString>"];
}

static void LoadPlayerData(IPlayerData playerData)
public static string GetPlayerDataListString()
{
var playerSaves = SaveManager.PlayerSaves;

var resp = $"Player count in .server file: {playerSaves.Count}\n";
foreach (var pair in playerSaves)
{
resp += $"[{pair.Key.Substring(0, 5)}] {pair.Value.Username}\n";
}
return resp;
}

public static void LoadPlayerData(IPlayerData playerData)
{
Log.Info($"Teleporting to target planet {GameMain.localPlanet?.id ?? 0} => {playerData.LocalPlanetId}");
var actionSail = GameMain.mainPlayer.controller.actionSail;
Expand Down
6 changes: 3 additions & 3 deletions NebulaWorld/Chat/Commands/WhisperCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public void Execute(ChatWindow window, string[] parameters)
var recipientUserName = parameters[0];
var fullMessageBody = string.Join(" ", parameters.Skip(1));
// first echo what the player typed so they know something actually happened
ChatManager.Instance.SendChatMessage($"[{DateTime.Now:HH:mm}] [To: {recipientUserName}] : {fullMessageBody}",
ChatMessageType.PlayerMessage);
ChatManager.Instance.SendChatMessage(ChatManager.FormatChatMessage(DateTime.Now, $"[To {recipientUserName}]", fullMessageBody),
ChatMessageType.PlayerMessagePrivate);

var packet = new ChatCommandWhisperPacket(senderUsername, recipientUserName, fullMessageBody);

Expand Down Expand Up @@ -64,7 +64,7 @@ public string[] GetUsage()

public static void SendWhisperToLocalPlayer(string sender, string mesageBody)
{
ChatManager.Instance.SendChatMessage($"[{DateTime.Now:HH:mm}] [{sender} whispered] : {mesageBody}",
ChatManager.Instance.SendChatMessage(ChatManager.FormatChatMessage(DateTime.Now, $"[From {sender}]", mesageBody),
ChatMessageType.PlayerMessagePrivate);
}
}
Loading

0 comments on commit 2d9b98b

Please sign in to comment.