Zabiju je

This commit is contained in:
2026-04-26 13:30:33 +02:00
parent 208696487e
commit 700e6bfbfc
143 changed files with 11027 additions and 1298 deletions

View File

@@ -5,6 +5,7 @@ using UnityEngine;
using System.Collections.Generic;
using Subsystems;
using System.Linq;
using UnityEngine.SceneManagement;
namespace Subsystems
{
@@ -13,9 +14,20 @@ namespace Subsystems
private const string _serverAddress = "geosus.honzuvkod.dev";
private const int _serverPort = 7777;
private GameClient _gameClient;
private GameManager_Map _mapSubsystem;
public async void OpenConection()
private GameManager _manager; // may be null for test clients
private bool _pendingMapBuild;
public GameManager_Network(GameClient gameClient, GameManager manager)
{
_gameClient = gameClient;
_manager = manager;
RegisterEventHandlers();
}
public async void OpenConnection()
{
int retries = 0;
int delayMs = 5000;
while (true)
{
Task<bool> state = _gameClient.ConnectAsync(_serverAddress, _serverPort);
@@ -25,18 +37,18 @@ namespace Subsystems
Debug.Log("Connected to server.");
break;
}
else
retries++;
if (retries >= 10)
{
Debug.Log("Failed to connect to server");
Debug.LogError("Failed to connect after 10 attempts. Giving up.");
break;
}
await Task.Delay(5000);
Debug.Log($"Failed to connect (attempt {retries}). Retrying in {delayMs / 1000}s...");
await Task.Delay(delayMs);
delayMs = Mathf.Min(delayMs * 2, 30000); // exponential backoff, cap 30s
}
}
public GameManager_Network(GameClient gameClient)
{
_gameClient = gameClient;
RegisterEventHandlers();
}
public void RegisterEventHandlers()
{
_gameClient.OnConnected += OnConnected;
@@ -45,117 +57,307 @@ namespace Subsystems
_gameClient.OnMessage += OnMessage;
_gameClient.OnGameEvent += OnGameEvent;
}
private void OnConnected()
{
Debug.Log("Successfully connected to the server.");
}
private void OnDisconnected(string reason)
{
Debug.Log($"Host disconnected due to {reason}");
Debug.Log($"Disconnected: {reason}");
// Auto-reconnect unless the app is quitting
if (reason != "Disposed" && _manager != null)
_manager.StartCoroutine(ReconnectAfterDelay(3f));
}
private System.Collections.IEnumerator ReconnectAfterDelay(float seconds)
{
yield return new UnityEngine.WaitForSeconds(seconds);
Debug.Log("Attempting to reconnect...");
OpenConnection();
}
private void OnError(string error)
{
Debug.LogError($"Network error: {error}");
}
private void OnMessage(Message message)
{
switch (message.Type)
{
case "GameEvent":
OnGameEvent(message as GameEvent);
// handled via OnGameEvent
break;
case "CreateLobbyResponse":
Debug.Log("Received CreateLobbyResponse message");
HandleCreateLobbyResponse(message as CreateLobbyResponse);
break;
case "JoinLobbyResponse":
Debug.Log("Received JoinLobbyResponse message");
HandleJoinLobbyResponse(message as JoinLobbyResponse);
break;
case "PositionBroadcast":
HandlePositionBroadcast(message as PositionBroadcast);
break;
case "Ack":
Debug.Log("Received Ack message");
break;
default:
Debug.Log("Received message of type: " + message.Type);
break;
}
}
private void OnGameEvent(GameEvent gameEvent)
{
switch (gameEvent.EventType)
{
case "PlayerJoined":
Debug.Log($"Player {gameEvent.GetPayload<PlayerJoinedPayload>().DisplayName} joined");
break;
case "PlayerLeft":
Debug.Log($"Player {gameEvent.GetPayload<PlayerLeftPayload>()} left");
case "HostChanged":
// SDK already updates CurrentLobbyState; just refresh UI
_manager?.uiSubsystem?.NotifyLobbyChanged();
break;
case "GameStarting":
Debug.Log("Game is starting!");
break;
case "GameStarted":
Debug.Log("Game started");
HandleGameStarting();
break;
case "MapDataReady":
Debug.Log("Map data ready");
HandleMapDataReady();
break;
case "PlayerMapDataReceived":
Debug.Log("Player map data recieved");
case "GameStarted":
HandleGameStarted();
break;
case "RoleAssigned":
HandleRoleAssigned(gameEvent);
break;
case "TaskCompleted":
HandleTaskCompleted(gameEvent);
break;
case "PlayerKilled":
HandlePlayerKilled(gameEvent);
break;
case "BodyReported":
case "EmergencyMeetingCalled":
HandleMeetingCalled(gameEvent);
break;
case "MeetingStarted":
HandleMeetingStarted(gameEvent);
break;
case "VotingClosed":
HandleVotingClosed(gameEvent);
break;
case "GameEnded":
HandleGameEnded(gameEvent);
break;
case "ReturnedToLobby":
HandleReturnedToLobby();
break;
case "SabotageStarted":
HandleSabotageStarted(gameEvent);
break;
case "SabotageRepaired":
case "SabotageMeltdown":
_manager?.uiSubsystem?.HideSabotageTimer();
_manager?.mapSubsystem?.ClearSabotageMarkers();
break;
case "MapDataError":
Debug.Log("Received MapData server error");
Debug.LogError("Server could not generate map data.");
break;
default:
Debug.Log("Received GameEvent of type: " + gameEvent.EventType);
Debug.Log("GameEvent: " + gameEvent.EventType);
break;
}
}
// ── Lobby responses ───────────────────────────────────────────────────
private void HandleCreateLobbyResponse(CreateLobbyResponse message)
{
if (message == null) return;
if (message.Success)
{
Debug.Log("Lobby created successfully. Join Code: " + message.JoinCode + ", Lobby ID: " + message.LobbyId);
Debug.Log($"Lobby created. Code: {message.JoinCode}, ID: {message.LobbyId}");
// Navigate to the create/waiting scene
SceneManager.LoadScene("create", LoadSceneMode.Single);
// Mark lobby UI dirty so LobbyDisplayUI refreshes once the scene is loaded
_manager?.uiSubsystem?.NotifyLobbyChanged();
}
else
{
Debug.LogError("Failed to create lobby: " + message.Error);
}
}
private void HandleJoinLobbyResponse(JoinLobbyResponse message)
{
if (message == null) return;
if (message.Success)
{
Debug.Log("Lobby created successfully." + ", Lobby ID: " + message.LobbyId);
Debug.Log($"Joined lobby: {message.LobbyId}");
SceneManager.LoadScene("join loading", LoadSceneMode.Single);
// Mark lobby UI dirty so LobbyDisplayUI refreshes once the scene is loaded
_manager?.uiSubsystem?.NotifyLobbyChanged();
}
else
{
Debug.LogError("Failed to create lobby: " + message.Error);
Debug.LogError("Failed to join lobby: " + message.Error);
}
}
public void CrateLobby(double lat, double lon)
// ── Game flow events ──────────────────────────────────────────────────
private void HandleGameStarting()
{
_gameClient.CreateLobby(new Position(lat, lon));
_pendingMapBuild = false;
// SDK sets Phase = Loading; load Client.unity
SceneManager.LoadScene("Client", LoadSceneMode.Single);
}
private void HandleMapDataReady()
{
_pendingMapBuild = true;
TryBuildMapAndMarkers();
}
/// <summary>
/// Called from GameManager.OnSceneLoaded("Client") after scene objects are bound.
/// Ensures map construction still happens even if MapDataReady arrived earlier.
/// </summary>
public void OnClientSceneReady()
{
TryBuildMapAndMarkers();
}
private void TryBuildMapAndMarkers()
{
if (!_pendingMapBuild) return;
if (_manager?.mapSubsystem == null) return;
if (!_manager.mapSubsystem.IsSceneReady) return;
if (_gameClient?.CurrentLobbyState?.MapData == null) return;
_manager.mapSubsystem.BuildMap();
_manager.mapSubsystem.CreateTaskMarkers(_gameClient.MyTasks);
_pendingMapBuild = false;
Debug.Log("[Network] Map built and task markers refreshed.");
}
private void HandleGameStarted()
{
Debug.Log("Game started");
// Phase is now Playing; GPS loop will start sending positions
}
private void HandleRoleAssigned(GameEvent evt)
{
var payload = evt.GetPayload<RoleAssignedPayload>();
if (payload == null || payload.ClientUuid != _gameClient.ClientUuid) return;
Debug.Log($"Role: {payload.Role}, Tasks: {payload.Tasks?.Count ?? 0}");
_manager?.taskSubsystem?.Initialize(_gameClient.MyTasks);
}
private void HandleTaskCompleted(GameEvent evt)
{
var payload = evt.GetPayload<TaskCompletedPayload>();
if (payload == null) return;
_manager?.uiSubsystem?.UpdateTaskProgress(payload.TotalCompleted, payload.TotalTasks);
_manager?.mapSubsystem?.RemoveTaskMarker(payload.TaskId);
}
private void HandlePlayerKilled(GameEvent evt)
{
var payload = evt.GetPayload<PlayerKilledPayload>();
if (payload == null) return;
_manager?.mapSubsystem?.CreateBodyMarker(payload.BodyId, payload.Location);
if (payload.VictimId == _gameClient.ClientUuid)
_manager?.uiSubsystem?.OnLocalPlayerDied();
}
private void HandleMeetingCalled(GameEvent evt)
{
_manager?.uiSubsystem?.ShowMeetingAlert();
}
private void HandleMeetingStarted(GameEvent evt)
{
var payload = evt.GetPayload<MeetingStartedPayload>();
if (payload == null) return;
_manager?.uiSubsystem?.ShowMeetingPanel(_gameClient.CurrentLobbyState?.Players, payload);
}
private void HandleVotingClosed(GameEvent evt)
{
var payload = evt.GetPayload<VotingClosedPayload>();
if (payload == null) return;
_manager?.uiSubsystem?.ShowVoteResult(payload, _gameClient.CurrentLobbyState?.Players);
_manager?.mapSubsystem?.ClearBodyMarkers();
}
private void HandleGameEnded(GameEvent evt)
{
var payload = evt.GetPayload<GameEndedPayload>();
if (payload == null) return;
_manager?.uiSubsystem?.ShowGameEndPanel(payload, _gameClient.ClientUuid);
}
private void HandleReturnedToLobby()
{
if (_gameClient.IsOwner)
SceneManager.LoadScene("create", LoadSceneMode.Single);
else
SceneManager.LoadScene("join loading", LoadSceneMode.Single);
}
private void HandleSabotageStarted(GameEvent evt)
{
var payload = evt.GetPayload<SabotageStartedPayload>();
if (payload == null) return;
_manager?.mapSubsystem?.CreateSabotageMarkers(payload.RepairStations);
if (payload.Type == SabotageType.CriticalMeltdown && payload.Deadline.HasValue)
_manager?.uiSubsystem?.ShowSabotageTimer(payload.Deadline.Value);
if (payload.Type == SabotageType.CommsBlackout)
_manager?.uiSubsystem?.SetCommsBlackout(true);
}
private void HandlePositionBroadcast(PositionBroadcast broadcast)
{
if (broadcast == null) return;
_manager?.mapSubsystem?.UpdatePlayerAvatars(_gameClient.PlayerPositions, _gameClient.ClientUuid);
}
// ── Send helpers ──────────────────────────────────────────────────────
public void CreateLobby(double lat, double lon, double radius = 500, int impostorCount = 1, int taskCount = 5)
{
_gameClient.CreateLobby(new Position(lat, lon), impostorCount, taskCount, null, radius);
}
public void JoinLobby(string joinCode)
{
try
{
_gameClient.JoinLobby(joinCode);
}
catch (System.Exception ex)
{
Debug.LogError("Error joining lobby: " + ex.Message);
}
try { _gameClient.JoinLobby(joinCode); }
catch (System.Exception ex) { Debug.LogError("JoinLobby error: " + ex.Message); }
}
public void LeaveLobby()
{
_gameClient.Disconnect();
Application.Quit();
_gameClient.LeaveLobby();
SceneManager.LoadScene(_manager?.firstMenuScene ?? "main menu asi idk lol", LoadSceneMode.Single);
}
public void StartGame()
{
_gameClient.StartGame();
}
}
}