Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix and enhancement #650

Merged
merged 6 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions NebulaModel/MultiplayerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class MultiplayerOptions : ICloneable

[DisplayName("Nickname")] public string Nickname { get; set; } = string.Empty;

[DisplayName("NameTagSize")] public int NameTagSize { get; set; } = 100;

[DisplayName("Server Password")]
[Category("Network")]
[Description("If provided, this will set a password for your hosted server.")]
Expand Down Expand Up @@ -118,6 +120,10 @@ public bool StreamerMode
}
}

[DisplayName("Enable Achievement")]
[Description("Toggle to enable achievement in multiplayer game")]
public bool EnableAchievement { get; set; } = true;

[DisplayName("Chat Hotkey")]
[Category("Chat")]
[Description("Keyboard shortcut to toggle the chat window")]
Expand Down
3 changes: 2 additions & 1 deletion NebulaModel/Packets/Universe/DysonSphereLoadRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ public enum DysonSphereRequestEvent
{
List = 1,
Load = 2,
Unload = 3
Unload = 3,
Query = 4
}
19 changes: 13 additions & 6 deletions NebulaNetwork/Messaging/WebSocketService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ protected override void OnMessage(MessageEventArgs e)

protected override void OnClose(CloseEventArgs e)
{
var connection = connections[Context.UserEndPoint.GetHashCode()];
connections.Remove(connection.GetHashCode());
if (!connections.TryGetValue(Context.UserEndPoint.GetHashCode(), out var connection))
{
return;
}
connections.Remove(Context.UserEndPoint.GetHashCode());

// If the reason of a client disconnect is because we are still loading the game,
// we don't need to inform the other clients since the disconnected client never
// joined the game in the first place.
Expand All @@ -81,19 +85,22 @@ protected override void OnClose(CloseEventArgs e)

protected override void OnError(ErrorEventArgs e)
{
if (!connections.TryGetValue(Context.UserEndPoint.GetHashCode(), out var connection))
{
return;
}
PhantomGamers marked this conversation as resolved.
Show resolved Hide resolved
connections.Remove(Context.UserEndPoint.GetHashCode());

// TODO: seems like clients erroring out in the sync process can lock the host with the joining player message, maybe this fixes it

Log.Info($"Client disconnected because of an error: {ID}, reason: {e.Exception}");
UnityDispatchQueue.RunOnMainThread(() =>
{
// This is to make sure that we don't try to deal with player disconnection
// if it is because we have stopped the server and are not in a multiplayer game anymore.
if (Multiplayer.IsActive)
{
Server.OnSocketDisconnection(new NebulaConnection(Context.WebSocket, Context.UserEndPoint,
PacketProcessor));
Server.OnSocketDisconnection(connection);
}
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,29 @@ protected override void ProcessPacket(DysonSphereLoadRequest packet, NebulaConne
case DysonSphereRequestEvent.Unload:
Multiplayer.Session.DysonSpheres.UnRegisterPlayer(conn, packet.StarIndex);
break;

case DysonSphereRequestEvent.Query:
// Ignore query if dyson sphere doesn't exist on host
if (packet.StarIndex < 0 || packet.StarIndex >= GameMain.data.galaxy.starCount)
{
return;
}
dysonSphere = GameMain.data.dysonSpheres[packet.StarIndex];
if (dysonSphere == null)
{
return;
}
using (var writer = new BinaryUtils.Writer())
{
dysonSphere.Export(writer.BinaryWriter);
var data = writer.CloseAndGetBytes();
Log.Info($"Sent {data.Length} bytes of data for DysonSphereData (INDEX: {packet.StarIndex})");
conn.SendPacket(new FragmentInfo(data.Length));
conn.SendPacket(new DysonSphereData(packet.StarIndex, data, DysonSphereRespondEvent.Load));
Multiplayer.Session.DysonSpheres.RegisterPlayer(conn, packet.StarIndex);
}
break;

default:
throw new ArgumentOutOfRangeException(nameof(packet), "Unknown DysonSphereRequestEvent: " + packet.Event);
}
Expand Down
2 changes: 1 addition & 1 deletion NebulaNetwork/SaveManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public static void LoadServerData()
break;
}

if (playerSaves.ContainsKey(hash) && playerData != null)
if (!playerSaves.ContainsKey(hash) && playerData != null)
{
playerSaves.Add(hash, playerData);
}
Expand Down
20 changes: 20 additions & 0 deletions NebulaPatcher/Patches/Dynamic/AbnormalityLogic_Patch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#region

using HarmonyLib;
using NebulaModel;
using NebulaWorld;

#endregion

namespace NebulaPatcher.Patches.Dynamic;

[HarmonyPatch(typeof(AbnormalityLogic))]
internal class AbnormalityLogic_Patch
{
[HarmonyPrefix]
[HarmonyPatch(nameof(AbnormalityLogic.GameTick))]
public static bool GameTick_Prefix()
{
return !Multiplayer.IsActive || !Config.Options.EnableAchievement;
}
}
27 changes: 27 additions & 0 deletions NebulaPatcher/Patches/Dynamic/AchievementLogic_Patch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#region

using HarmonyLib;
using NebulaModel;
using NebulaWorld;

#endregion

namespace NebulaPatcher.Patches.Dynamic;

[HarmonyPatch(typeof(AchievementLogic))]
internal class AchievementLogic_Patch
{
[HarmonyPrefix]
[HarmonyPatch(nameof(AchievementLogic.isSelfFormalGame), MethodType.Getter)]
public static bool IsSelfFormalGame_Prefix(ref bool __result)
{
if (!Multiplayer.IsActive)
{
return true;
}

// Decide to enable achievement or not in multiplayer game
__result = Config.Options.EnableAchievement;
return false;
}
}
35 changes: 35 additions & 0 deletions NebulaPatcher/Patches/Dynamic/GameAbnormalityData_0925_Patch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#region

using ABN;
using HarmonyLib;
using NebulaModel;
using NebulaWorld;

#endregion

namespace NebulaPatcher.Patches.Dynamic;

[HarmonyPatch(typeof(GameAbnormalityData_0925))]
internal class GameAbnormalityData_0925_Patch
{
[HarmonyPrefix]
[HarmonyPatch(nameof(GameAbnormalityData_0925.TriggerAbnormality))]
public static bool TriggerAbnormality_Prefix()
{
return !Multiplayer.IsActive || !Config.Options.EnableAchievement;
}

[HarmonyPrefix]
[HarmonyPatch(nameof(GameAbnormalityData_0925.NothingAbnormal))]
[HarmonyPatch(nameof(GameAbnormalityData_0925.IsAbnormalTriggerred))]
public static bool NothingAbnormal_Prefix(ref bool __result)
{
if (!Multiplayer.IsActive || !Config.Options.EnableAchievement)
{
return true;
}

__result = true;
return false;
}
}
25 changes: 25 additions & 0 deletions NebulaPatcher/Patches/Dynamic/UIStarmap_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using System.Diagnostics.CodeAnalysis;
using HarmonyLib;
using NebulaModel.Packets.Universe;
using NebulaWorld;

#endregion
Expand Down Expand Up @@ -49,4 +50,28 @@ public static bool TeleportToUPosition_Prefix(VectorLF3 uPos)
InGamePopup.ShowWarning("Unavailable", "Cannot teleport to gas giant", "OK");
return false;
}

static int s_queryingIndex = -1;

[HarmonyPrefix]
[HarmonyPatch(typeof(UIStarmap), nameof(UIStarmap.OnCursorFunction2Click))]
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")]
public static void QueryDysonSphere(UIStarmap __instance)
{
// Client: Query existing dyson sphere when clicking on 'View' star on starmap
if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost || Multiplayer.Session.IsInLobby || __instance.focusStar == null)
{
return;
}

var starIndex = __instance.focusStar.star.index;
if (GameMain.data.dysonSpheres[starIndex] == null)
{
if (s_queryingIndex != starIndex)
{
Multiplayer.Session.Network.SendPacket(new DysonSphereLoadRequest(starIndex, DysonSphereRequestEvent.Query));
s_queryingIndex = starIndex;
}
}
}
}
2 changes: 1 addition & 1 deletion NebulaWorld/Logistics/StationUIManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static void UpdateStation(ref StationUI packet)
public void UpdateStorage(StorageUI packet)
{
var stationComponent = GetStation(packet.PlanetId, packet.StationId, packet.StationGId);
if (stationComponent == null || stationComponent.storage.Length == 0)
if (stationComponent?.storage == null || stationComponent.storage.Length == 0)
{
return;
}
Expand Down
2 changes: 1 addition & 1 deletion NebulaWorld/RemotePlayerModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public RemotePlayerModel(ushort playerId, string username)
public Transform PlayerModelTransform { get; set; }
public RemotePlayerMovement Movement { get; set; }
public RemotePlayerAnimation Animator { get; set; }
public GameObject InGameNameText { get; set; }
public TextMesh InGameNameText { get; set; }
public Text StarmapNameText { get; set; }
public Transform StarmapTracker { get; set; }

Expand Down
50 changes: 16 additions & 34 deletions NebulaWorld/SimulatedWorld.cs
Original file line number Diff line number Diff line change
Expand Up @@ -455,54 +455,50 @@ public void ClearPlayerNameTagsOnStarmap()

public void RenderPlayerNameTagsInGame()
{
TextMesh uiSailIndicator_targetText = null;

using (GetRemotePlayersModels(out var remotePlayersModels))
{
foreach (var playerModel in remotePlayersModels.Select(player => player.Value))
{
GameObject playerNameText;
TextMesh playerNameText;
if (playerModel.InGameNameText != null)
{
playerNameText = playerModel.InGameNameText;
}
else
{
// Only get the field required if we actually need to, no point getting it every time
if (uiSailIndicator_targetText == null)
{
uiSailIndicator_targetText = UIRoot.instance.uiGame.sailIndicator.targetText;
}
var uiSailIndicator_targetText = UIRoot.instance.uiGame.sailIndicator.targetText;

// Initialise a new game object to contain the text
playerModel.InGameNameText = playerNameText = new GameObject();
var go = new GameObject();
// Make it follow the player transform
playerNameText.transform.SetParent(playerModel.PlayerTransform, false);
go.transform.SetParent(playerModel.PlayerTransform, false);
// Add a meshrenderer and textmesh component to show the text with a different font
var meshRenderer = playerNameText.AddComponent<MeshRenderer>();
var textMesh = playerNameText.AddComponent<TextMesh>();
var meshRenderer = go.AddComponent<MeshRenderer>();
meshRenderer.sharedMaterial =
uiSailIndicator_targetText.gameObject.GetComponent<MeshRenderer>().sharedMaterial;

var textMesh = go.AddComponent<TextMesh>();
// Set the text to be their name
textMesh.text = $"{playerModel.Username}";
// Align it to be centered below them
textMesh.anchor = TextAnchor.UpperCenter;
// Copy the font over from the sail indicator
textMesh.font = uiSailIndicator_targetText.font;
meshRenderer.sharedMaterial =
uiSailIndicator_targetText.gameObject.GetComponent<MeshRenderer>().sharedMaterial;
textMesh.fontSize = 36;

playerNameText.SetActive(true);
playerModel.InGameNameText = playerNameText = textMesh;
playerNameText.gameObject.SetActive(true);
}

// If the player is not on the same planet or is in space, then do not render their in-world tag
if (playerModel.Movement.localPlanetId != Multiplayer.Session.LocalPlayer.Data.LocalPlanetId &&
playerModel.Movement.localPlanetId <= 0)
{
playerNameText.SetActive(false);
playerNameText.gameObject.SetActive(false);
}
else if (!playerNameText.activeSelf)
else if (!playerNameText.gameObject.activeSelf)
{
playerNameText.SetActive(true);
playerNameText.gameObject.SetActive(true);
}

// Make sure the text is pointing at the camera
Expand All @@ -512,23 +508,9 @@ public void RenderPlayerNameTagsInGame()
// Resizes the text based on distance from camera for better visual quality
var distanceFromCamera =
Vector3.Distance(playerNameText.transform.position, transform.position);
var nameTextMesh = playerNameText.GetComponent<TextMesh>();

switch (distanceFromCamera)
{
case > 100f:
nameTextMesh.characterSize = 0.2f;
nameTextMesh.fontSize = 60;
break;
case > 50f:
nameTextMesh.characterSize = 0.15f;
nameTextMesh.fontSize = 48;
break;
default:
nameTextMesh.characterSize = 0.1f;
nameTextMesh.fontSize = 36;
break;
}
var scaleRatio = Config.Options.NameTagSize / (GameCamera.instance.planetMode ? 10000f : 30000f);
playerNameText.characterSize = scaleRatio * Mathf.Clamp(distanceFromCamera, 20f, 200f);
}
}
}
Expand Down
Loading