new API and rematch WIP
This commit is contained in:
@@ -142,13 +142,30 @@ public static class Cupid
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Matchmaker GET / body: <c>"0"</c> while waiting; otherwise a JSON room object.</summary>
|
/// <summary>Matchmaker GET / body: <c>"0"</c> while waiting; otherwise a JSON room object.</summary>
|
||||||
public static CupidRoom? ParseRoom(string data)
|
public static CupidRoom? ParseRoom(string data) => ParseRoom(data, 0, null);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ParseRoom(string)"/>
|
||||||
|
/// <param name="currentUserId">Used to pick <c>for_red</c> vs <c>for_blue</c> when both list the same players.</param>
|
||||||
|
/// <param name="teamDisambiguation">Optional hint (e.g. <see cref="GameManager.MyTeam"/>) when the roster is duplicated on both sides.</param>
|
||||||
|
public static CupidRoom? ParseRoom(string data, int currentUserId, Team? teamDisambiguation)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(data))
|
if (string.IsNullOrWhiteSpace(data))
|
||||||
return null;
|
return null;
|
||||||
string t = data.Trim();
|
string t = data.Trim();
|
||||||
if (t == "0")
|
if (t == "0")
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if (t.IndexOf("\"for_red\"", StringComparison.Ordinal) >= 0)
|
||||||
|
{
|
||||||
|
MatchmadeResponse env = JsonUtility.FromJson<MatchmadeResponse>(t);
|
||||||
|
if (env == null || !env.ok || !MatchmadeResponse.IsMatchReady(env))
|
||||||
|
return null;
|
||||||
|
MatchmadeTeamPayload branch = MatchmadeResponse.SelectTeamPayload(env, currentUserId, teamDisambiguation);
|
||||||
|
if (branch == null || branch.Port <= 0)
|
||||||
|
return null;
|
||||||
|
return ToCupidRoom(branch);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CupidRoom room = JsonUtility.FromJson<CupidRoom>(t);
|
CupidRoom room = JsonUtility.FromJson<CupidRoom>(t);
|
||||||
@@ -161,6 +178,32 @@ public static class Cupid
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CupidRoom ToCupidRoom(MatchmadeTeamPayload p)
|
||||||
|
{
|
||||||
|
var room = new CupidRoom
|
||||||
|
{
|
||||||
|
GameName = p.GameName ?? "",
|
||||||
|
Port = p.Port,
|
||||||
|
InitTime = p.InitTime,
|
||||||
|
match_id = p.match_id,
|
||||||
|
your_team = p.your_team ?? ""
|
||||||
|
};
|
||||||
|
if (p.Players != null)
|
||||||
|
{
|
||||||
|
room.Players = new CupidQueueEntry[p.Players.Length];
|
||||||
|
for (int i = 0; i < p.Players.Length; i++)
|
||||||
|
{
|
||||||
|
room.Players[i] = new CupidQueueEntry
|
||||||
|
{
|
||||||
|
Name = p.Players[i].Name,
|
||||||
|
LastSeen = p.Players[i].LastSeen,
|
||||||
|
UserId = p.Players[i].UserId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return room;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
using UnityEngine.Networking;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
@@ -102,7 +101,12 @@ public class CupidLobby : MonoBehaviour
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CupidRoom? room = Cupid.ParseRoom(text);
|
Team? teamHint = LoginManager.MatchYourTeam;
|
||||||
|
if (!teamHint.HasValue && GameManager.instance != null)
|
||||||
|
teamHint = GameManager.MyTeam;
|
||||||
|
int userId = LoginManager.CurrentUser != null ? LoginManager.CurrentUser.id : 0;
|
||||||
|
|
||||||
|
CupidRoom? room = Cupid.ParseRoom(text, userId, teamHint);
|
||||||
if (room == null)
|
if (room == null)
|
||||||
{
|
{
|
||||||
if (text != null && text.Trim() != "0")
|
if (text != null && text.Trim() != "0")
|
||||||
@@ -113,29 +117,35 @@ public class CupidLobby : MonoBehaviour
|
|||||||
CupidRoom _room = (CupidRoom)room;
|
CupidRoom _room = (CupidRoom)room;
|
||||||
Logger.Log("Got into a room");
|
Logger.Log("Got into a room");
|
||||||
Logger.Log(text);
|
Logger.Log(text);
|
||||||
MatchmadeResponse matchmadeResponse = JsonUtility.FromJson<MatchmadeResponse>(text);
|
MatchmadeResponse env = JsonUtility.FromJson<MatchmadeResponse>(text);
|
||||||
if(matchmadeResponse.Players.Length < 2){
|
MatchmadeTeamPayload branch = MatchmadeResponse.SelectTeamPayload(env, userId, teamHint);
|
||||||
Debug.Log("Waiting for the other player to show up");
|
if (branch == null || !MatchmadeResponse.TryResolveMyAndOpponent(env, branch, userId, out MatchmadePlayer myPlayer, out MatchmadePlayer opponentPlayer))
|
||||||
|
{
|
||||||
|
Debug.Log("Waiting for the other player to show up (could not resolve roster)");
|
||||||
yield return new WaitForSeconds(1);
|
yield return new WaitForSeconds(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Team myTeam = matchmadeResponse.your_team == "red" ? Team.Red : Team.Blue;
|
|
||||||
|
|
||||||
MatchmadePlayer myPlayer = matchmadeResponse.Players.First(p => p.UserId == LoginManager.CurrentUser.id);
|
string yt = (branch.your_team ?? "").Trim().ToLowerInvariant();
|
||||||
MatchmadePlayer opponentPlayer = matchmadeResponse.Players.First(p => p.UserId != LoginManager.CurrentUser.id);
|
Team myTeam = yt == "blue" ? Team.Blue : Team.Red;
|
||||||
|
|
||||||
if(myTeam==Team.Red){
|
if (myTeam == Team.Red)
|
||||||
|
{
|
||||||
GameManager.RedPlayer = myPlayer;
|
GameManager.RedPlayer = myPlayer;
|
||||||
GameManager.BluePlayer = opponentPlayer;
|
GameManager.BluePlayer = opponentPlayer;
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
GameManager.BluePlayer = myPlayer;
|
GameManager.BluePlayer = myPlayer;
|
||||||
GameManager.RedPlayer = opponentPlayer;
|
GameManager.RedPlayer = opponentPlayer;
|
||||||
}
|
}
|
||||||
GameManager.MyTeam = myTeam;
|
GameManager.MyTeam = myTeam;
|
||||||
|
|
||||||
// LevelLoadManager.instance.SetupMatchMade(myTeam, myPlayer.Name, opponentPlayer.Name, $"L10 {myPlayer.l10_wins}-{myPlayer.l10_losses}", $"L10 {opponentPlayer.l10_wins}-{opponentPlayer.l10_losses}");
|
int rcPrizeCoins = env.rc_prize > 0 ? env.rc_prize : branch.rc_prize;
|
||||||
LevelLoadManager.instance.SetupMatchMade(myTeam, myPlayer, opponentPlayer);
|
GameManager.MatchRcPrizeCoins = rcPrizeCoins;
|
||||||
GameManager.ConfigureDedicatedMatchReporting(matchmadeResponse.match_id);
|
|
||||||
|
LevelLoadManager.instance.SetupMatchMade(myTeam, myPlayer, opponentPlayer, CoinHelper.FormatString(rcPrizeCoins) + " RC");
|
||||||
|
GameManager.ConfigureDedicatedMatchReporting(branch.match_id);
|
||||||
Logger.Log("Setting cupid to load game scene");
|
Logger.Log("Setting cupid to load game scene");
|
||||||
Cupid.RoomPort = _room.Port;
|
Cupid.RoomPort = _room.Port;
|
||||||
LoginManager.SetMatchYourTeam(_room.your_team);
|
LoginManager.SetMatchYourTeam(_room.your_team);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+61
-56
@@ -1,57 +1,62 @@
|
|||||||
Logger initiated at 5/2/2026 10:17:33 PM
|
Logger initiated at 5/4/2026 5:31:47 PM
|
||||||
|
|
||||||
[5/2/2026 10:17:33 PM] Cupid init success
|
[5/4/2026 5:31:47 PM] Cupid init success
|
||||||
[5/2/2026 10:17:33 PM] Starting matchmake as warlock2
|
[5/4/2026 5:31:48 PM] Starting matchmake as warlock2
|
||||||
[5/2/2026 10:17:34 PM] Starting matchmake as warlock
|
[5/4/2026 5:31:49 PM] Starting matchmake as warlock
|
||||||
[5/2/2026 10:17:38 PM] Got into a room
|
[5/4/2026 5:31:52 PM] Still waiting: {"ok":true,"entry_fee":21,"rc_prize":37,"for_red":{"Players":[{"Name":"warlock2","LastSeen":1777896112344,"UserId":5,"l10_wins":3,"l10_losses":4}],"GameName":"soccar","Port":26825,"InitTime":1777896112344,"entry_fee":21,"match_id":248,"rc_prize":37,"your_team":"red"},"for_blue":null}
|
||||||
[5/2/2026 10:17:38 PM] {"Players":[{"Name":"warlock","LastSeen":1777740457910,"UserId":4,"l10_wins":1,"l10_losses":0}],"GameName":"soccar","Port":26494,"InitTime":1777740457910,"match_id":236,"your_team":"red"}
|
[5/4/2026 5:31:53 PM] Got into a room
|
||||||
[5/2/2026 10:17:38 PM] Got into a room
|
[5/4/2026 5:31:53 PM] {"ok":true,"entry_fee":21,"rc_prize":37,"for_red":{"Players":[{"Name":"warlock2","LastSeen":1777896112344,"UserId":5,"l10_wins":3,"l10_losses":4},{"Name":"warlock","LastSeen":1777896113172,"UserId":4,"l10_wins":4,"l10_losses":3}],"GameName":"soccar","Port":26825,"InitTime":1777896112344,"entry_fee":21,"match_id":248,"instance_started":true,"rc_prize":37,"your_team":"red"},"for_blue":{"Players":[{"Name":"warlock2","LastSeen":1777896112344,"UserId":5,"l10_wins":3,"l10_losses":4},{"Name":"warlock","LastSeen":1777896113172,"UserId":4,"l10_wins":4,"l10_losses":3}],"GameName":"soccar","Port":26825,"InitTime":1777896112344,"entry_fee":21,"match_id":248,"instance_started":true,"rc_prize":37,"your_team":"blue"}}
|
||||||
[5/2/2026 10:17:38 PM] {"Players":[{"Name":"warlock","LastSeen":1777740457910,"UserId":4,"l10_wins":1,"l10_losses":0},{"Name":"warlock2","LastSeen":1777740458378,"UserId":5,"l10_wins":0,"l10_losses":1}],"GameName":"soccar","Port":26494,"InitTime":1777740457910,"match_id":236,"instance_started":true,"your_team":"blue"}
|
[5/4/2026 5:31:53 PM] Configured dedicated match reporting for match id 248 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kickkingsapi.playpoolstudios.com
|
||||||
[5/2/2026 10:17:38 PM] Configured dedicated match reporting for match id 236 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kickkingsapi.playpoolstudios.com
|
[5/4/2026 5:31:53 PM] Setting cupid to load game scene
|
||||||
[5/2/2026 10:17:38 PM] Setting cupid to load game scene
|
[5/4/2026 5:31:53 PM] Loading game scene
|
||||||
[5/2/2026 10:17:38 PM] Loading game scene
|
[5/4/2026 5:31:53 PM] Got into a room
|
||||||
[5/2/2026 10:17:39 PM] Got into a room
|
[5/4/2026 5:31:53 PM] {"ok":true,"entry_fee":21,"rc_prize":37,"for_red":{"Players":[{"Name":"warlock2","LastSeen":1777896113824,"UserId":5,"l10_wins":3,"l10_losses":4},{"Name":"warlock","LastSeen":1777896113172,"UserId":4,"l10_wins":4,"l10_losses":3}],"GameName":"soccar","Port":26825,"InitTime":1777896112344,"entry_fee":21,"match_id":248,"instance_started":true,"rc_prize":37,"your_team":"red"},"for_blue":{"Players":[{"Name":"warlock2","LastSeen":1777896113824,"UserId":5,"l10_wins":3,"l10_losses":4},{"Name":"warlock","LastSeen":1777896113172,"UserId":4,"l10_wins":4,"l10_losses":3}],"GameName":"soccar","Port":26825,"InitTime":1777896112344,"entry_fee":21,"match_id":248,"instance_started":true,"rc_prize":37,"your_team":"blue"}}
|
||||||
[5/2/2026 10:17:39 PM] {"Players":[{"Name":"warlock","LastSeen":1777740459663,"UserId":4,"l10_wins":1,"l10_losses":0},{"Name":"warlock2","LastSeen":1777740458378,"UserId":5,"l10_wins":0,"l10_losses":1}],"GameName":"soccar","Port":26494,"InitTime":1777740457910,"match_id":236,"instance_started":true,"your_team":"red"}
|
[5/4/2026 5:31:53 PM] Configured dedicated match reporting for match id 248 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kickkingsapi.playpoolstudios.com
|
||||||
[5/2/2026 10:17:39 PM] Configured dedicated match reporting for match id 236 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kickkingsapi.playpoolstudios.com
|
[5/4/2026 5:31:53 PM] Setting cupid to load game scene
|
||||||
[5/2/2026 10:17:39 PM] Setting cupid to load game scene
|
[5/4/2026 5:31:53 PM] Loading game scene
|
||||||
[5/2/2026 10:17:39 PM] Loading game scene
|
[5/4/2026 5:32:00 PM] Starting client at $kickkingsapi.playpoolstudios.com:26825
|
||||||
[5/2/2026 10:17:45 PM] Starting client at $kickkingsapi.playpoolstudios.com:26494
|
[5/4/2026 5:32:00 PM] Client connected
|
||||||
[5/2/2026 10:17:45 PM] Client connected
|
[5/4/2026 5:32:00 PM] Starting client at $kickkingsapi.playpoolstudios.com:26825
|
||||||
[5/2/2026 10:17:50 PM] Starting client at $kickkingsapi.playpoolstudios.com:26494
|
[5/4/2026 5:32:00 PM] Client connected
|
||||||
[5/2/2026 10:17:50 PM] Client connected
|
[5/4/2026 5:32:08 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:17:59 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:32:08 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:17:59 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:32:14 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:09 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:32:14 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:10 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:32:20 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:18:15 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:32:20 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:18:15 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:32:25 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:21 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:32:26 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:21 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:32:28 PM] Score changed from 0 to 1
|
||||||
[5/2/2026 10:18:25 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:32:28 PM] Score changed from 0 to 1
|
||||||
[5/2/2026 10:18:25 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:32:31 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:18:33 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:32:31 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:18:33 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:32:39 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:37 PM] Score changed from 0 to 1
|
[5/4/2026 5:32:39 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:37 PM] Score changed from 0 to 1
|
[5/4/2026 5:32:45 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:18:40 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:32:45 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:18:40 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:32:52 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:48 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:32:52 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:48 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:32:57 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:18:54 PM] Score changed from 1 to 2
|
[5/4/2026 5:32:57 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:18:54 PM] Score changed from 1 to 2
|
[5/4/2026 5:33:08 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:57 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:33:08 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:18:57 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:33:13 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:19:05 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:33:13 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:19:05 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:33:17 PM] Score changed from 0 to 1
|
||||||
[5/2/2026 10:19:11 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:33:17 PM] Score changed from 0 to 1
|
||||||
[5/2/2026 10:19:12 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:33:20 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:19:19 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:33:20 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:19:19 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:33:29 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:19:27 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:33:30 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:19:27 PM] Selected team changed from Red to Blue
|
[5/4/2026 5:33:35 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:19:34 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:33:35 PM] Selected team changed from Blue to Red
|
||||||
[5/2/2026 10:19:34 PM] Score changed from 2 to 3
|
[5/4/2026 5:33:39 PM] Score changed from 1 to 2
|
||||||
[5/2/2026 10:19:34 PM] Selected team changed from Blue to Red
|
[5/4/2026 5:33:39 PM] Score changed from 1 to 2
|
||||||
[5/2/2026 10:19:34 PM] Score changed from 2 to 3
|
[5/4/2026 5:33:42 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:19:37 PM] Client disconnected
|
[5/4/2026 5:33:42 PM] Selected team changed from Red to Blue
|
||||||
[5/2/2026 10:19:38 PM] Client disconnected
|
[5/4/2026 5:33:52 PM] Selected team changed from Blue to Red
|
||||||
|
[5/4/2026 5:33:52 PM] Selected team changed from Blue to Red
|
||||||
|
[5/4/2026 5:33:57 PM] Score changed from 2 to 3
|
||||||
|
[5/4/2026 5:33:57 PM] Score changed from 2 to 3
|
||||||
|
[5/4/2026 5:34:39 PM] Client disconnected
|
||||||
|
[5/4/2026 5:34:42 PM] Client disconnected
|
||||||
|
|||||||
@@ -2590,7 +2590,7 @@ GameObject:
|
|||||||
m_Icon: {fileID: 0}
|
m_Icon: {fileID: 0}
|
||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
m_StaticEditorFlags: 0
|
m_StaticEditorFlags: 0
|
||||||
m_IsActive: 0
|
m_IsActive: 1
|
||||||
--- !u!224 &784446025213843339
|
--- !u!224 &784446025213843339
|
||||||
RectTransform:
|
RectTransform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -2906,9 +2906,9 @@ RectTransform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 741608775212071875}
|
m_Father: {fileID: 741608775212071875}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0.5, y: 1}
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
m_AnchorMax: {x: 0.5, y: 1}
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
m_AnchoredPosition: {x: 0, y: -999.55}
|
m_AnchoredPosition: {x: 0, y: 80.45001}
|
||||||
m_SizeDelta: {x: 419.1856, y: 93.29602}
|
m_SizeDelta: {x: 419.1856, y: 93.29602}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!222 &3617049431174458592
|
--- !u!222 &3617049431174458592
|
||||||
@@ -3628,6 +3628,7 @@ MonoBehaviour:
|
|||||||
redIcon: {fileID: 7194123030578827194, guid: 809c8d780dc80f14e80fd92c6e42ed71, type: 3}
|
redIcon: {fileID: 7194123030578827194, guid: 809c8d780dc80f14e80fd92c6e42ed71, type: 3}
|
||||||
blueIcon: {fileID: 7609527126711406816, guid: 8d015c6e4a5ab8540814b06ae5f85980, type: 3}
|
blueIcon: {fileID: 7609527126711406816, guid: 8d015c6e4a5ab8540814b06ae5f85980, type: 3}
|
||||||
txtMiddle: {fileID: 2458004521057696282}
|
txtMiddle: {fileID: 2458004521057696282}
|
||||||
|
txtRcPrize: {fileID: 8330661879995437874}
|
||||||
p1_winner: {fileID: 5375017959079975307}
|
p1_winner: {fileID: 5375017959079975307}
|
||||||
p2_winner: {fileID: 2911971058065672229}
|
p2_winner: {fileID: 2911971058065672229}
|
||||||
--- !u!225 &7794655613667813618
|
--- !u!225 &7794655613667813618
|
||||||
|
|||||||
+2743
-5
File diff suppressed because it is too large
Load Diff
@@ -4859,22 +4859,6 @@ PrefabInstance:
|
|||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
m_TransformParent: {fileID: 0}
|
m_TransformParent: {fileID: 0}
|
||||||
m_Modifications:
|
m_Modifications:
|
||||||
- target: {fileID: 3194354901675590681, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
|
||||||
propertyPath: m_IsActive
|
|
||||||
value: 1
|
|
||||||
objectReference: {fileID: 0}
|
|
||||||
- target: {fileID: 4033947976462218865, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
|
||||||
propertyPath: m_AnchorMax.y
|
|
||||||
value: 0.5
|
|
||||||
objectReference: {fileID: 0}
|
|
||||||
- target: {fileID: 4033947976462218865, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
|
||||||
propertyPath: m_AnchorMin.y
|
|
||||||
value: 0.5
|
|
||||||
objectReference: {fileID: 0}
|
|
||||||
- target: {fileID: 4033947976462218865, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
|
||||||
propertyPath: m_AnchoredPosition.y
|
|
||||||
value: 80.45001
|
|
||||||
objectReference: {fileID: 0}
|
|
||||||
- target: {fileID: 6417757714012981459, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
- target: {fileID: 6417757714012981459, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
||||||
propertyPath: m_Pivot.x
|
propertyPath: m_Pivot.x
|
||||||
value: 0
|
value: 0
|
||||||
@@ -4955,10 +4939,6 @@ PrefabInstance:
|
|||||||
propertyPath: m_LocalEulerAnglesHint.z
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
value: 0
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7133780496080864158, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
|
||||||
propertyPath: m_IsActive
|
|
||||||
value: 1
|
|
||||||
objectReference: {fileID: 0}
|
|
||||||
- target: {fileID: 8578419198713715619, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
- target: {fileID: 8578419198713715619, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: LevelLoader
|
value: LevelLoader
|
||||||
|
|||||||
@@ -3306,8 +3306,8 @@ RectTransform:
|
|||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0, y: 0}
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
m_AnchorMax: {x: 0, y: 0}
|
m_AnchorMax: {x: 0, y: 0}
|
||||||
m_AnchoredPosition: {x: 0, y: 0}
|
m_AnchoredPosition: {x: 164.3, y: -73.801}
|
||||||
m_SizeDelta: {x: 0, y: 102.62}
|
m_SizeDelta: {x: 95.636, y: 102.62}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!114 &830868269
|
--- !u!114 &830868269
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@@ -3481,8 +3481,8 @@ RectTransform:
|
|||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0, y: 0}
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
m_AnchorMax: {x: 0, y: 0}
|
m_AnchorMax: {x: 0, y: 0}
|
||||||
m_AnchoredPosition: {x: 0, y: 0}
|
m_AnchoredPosition: {x: 47.817, y: -73.8}
|
||||||
m_SizeDelta: {x: 0, y: 102.6215}
|
m_SizeDelta: {x: 95.6344, y: 102.6215}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!114 &874144767
|
--- !u!114 &874144767
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class GameCanvas : MonoBehaviour
|
|||||||
public TMP_Text blueTurnTimer;
|
public TMP_Text blueTurnTimer;
|
||||||
[FormerlySerializedAs("txtTurnTimer")] public TMP_Text redTurnTimer;
|
[FormerlySerializedAs("txtTurnTimer")] public TMP_Text redTurnTimer;
|
||||||
public TMP_Text redName,blueName;
|
public TMP_Text redName,blueName;
|
||||||
|
public TMP_Text txtRcPrize;
|
||||||
public TMP_Text txtWhosTurn;
|
public TMP_Text txtWhosTurn;
|
||||||
public Image blueTurnTimerRound;
|
public Image blueTurnTimerRound;
|
||||||
[FormerlySerializedAs("turnTimerRound")] public Image redTurnTimerRound;
|
[FormerlySerializedAs("turnTimerRound")] public Image redTurnTimerRound;
|
||||||
@@ -87,6 +88,9 @@ public class GameCanvas : MonoBehaviour
|
|||||||
}catch{
|
}catch{
|
||||||
Logger.Log("Failed to fetch red and blue names, isServer?");
|
Logger.Log("Failed to fetch red and blue names, isServer?");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (txtRcPrize != null)
|
||||||
|
txtRcPrize.text = CoinHelper.FormatString(GameManager.MatchRcPrizeCoins) + " RC";
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEmoteTextPressed(string txtName){
|
void OnEmoteTextPressed(string txtName){
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ public class GameManager : NetworkBehaviour
|
|||||||
public static Team MyTeam { get; set; }
|
public static Team MyTeam { get; set; }
|
||||||
public static MatchmadePlayer RedPlayer { get; set; }
|
public static MatchmadePlayer RedPlayer { get; set; }
|
||||||
public static MatchmadePlayer BluePlayer { get; set; }
|
public static MatchmadePlayer BluePlayer { get; set; }
|
||||||
|
/// <summary>Coin units from matchmaker <c>rc_prize</c>; used for in-game prize UI.</summary>
|
||||||
|
public static int MatchRcPrizeCoins { get; set; }
|
||||||
/// <summary>Set by dedicated server startup (e.g. CupidConnector parsing <c>-matchId</c>). PATCH is skipped if id ≤ 0 or secret is empty.</summary>
|
/// <summary>Set by dedicated server startup (e.g. CupidConnector parsing <c>-matchId</c>). PATCH is skipped if id ≤ 0 or secret is empty.</summary>
|
||||||
public static int DedicatedMatchId { get; private set; }
|
public static int DedicatedMatchId { get; private set; }
|
||||||
/// <summary>Sent as <c>X-Dedicated-Server-Secret</c>. From <c>-dedicatedSecret</c> arg or <c>DEDICATED_SERVER_SECRET</c> env.</summary>
|
/// <summary>Sent as <c>X-Dedicated-Server-Secret</c>. From <c>-dedicatedSecret</c> arg or <c>DEDICATED_SERVER_SECRET</c> env.</summary>
|
||||||
@@ -257,7 +259,7 @@ public class GameManager : NetworkBehaviour
|
|||||||
using (var req = DedicatedMatschInternalApi.BuildWinnerRequest(baseUrl, matchId, secret, jsonBody))
|
using (var req = DedicatedMatschInternalApi.BuildWinnerRequest(baseUrl, matchId, secret, jsonBody))
|
||||||
{
|
{
|
||||||
yield return req.SendWebRequest();
|
yield return req.SendWebRequest();
|
||||||
DedicatedMatschInternalApi.LogIfFailed(req);
|
DedicatedMatschInternalApi.LogWinnerPatchResult(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,7 +690,7 @@ public class GameManager : NetworkBehaviour
|
|||||||
yield return new WaitForSeconds(2f);
|
yield return new WaitForSeconds(2f);
|
||||||
yield return CoroutineFetchBothPlayersL10();
|
yield return CoroutineFetchBothPlayersL10();
|
||||||
|
|
||||||
StopClient();
|
// StopClient();
|
||||||
|
|
||||||
LevelLoadManager.instance.SetupGameOver(team,redScore,blueScore);
|
LevelLoadManager.instance.SetupGameOver(team,redScore,blueScore);
|
||||||
GameOverCanvas.instance.Show(team, MyTeam, redScore, blueScore);
|
GameOverCanvas.instance.Show(team, MyTeam, redScore, blueScore);
|
||||||
@@ -810,6 +812,9 @@ public class GameManager : NetworkBehaviour
|
|||||||
freezeInput=false;
|
freezeInput=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Headless dedicated server → matchmaker internal PATCH. Runs only where started (server-side coroutines).</summary>
|
/// <summary>Headless dedicated server → matchmaker internal PATCH. Runs only where started (server-side coroutines).</summary>
|
||||||
@@ -850,4 +855,54 @@ static class DedicatedMatschInternalApi
|
|||||||
Logger.Log("More details : " + req.url + " " + req.method + " " + req.uploadHandler.data + " " + req.downloadHandler.text);
|
Logger.Log("More details : " + req.url + " " + req.method + " " + req.uploadHandler.data + " " + req.downloadHandler.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Handles <c>PATCH /internal/match/:id/winner</c>: 200 parses economy; 409 idempotent (already paid).</summary>
|
||||||
|
public static void LogWinnerPatchResult(UnityWebRequest req)
|
||||||
|
{
|
||||||
|
long code = req.responseCode;
|
||||||
|
string body = req.downloadHandler != null ? req.downloadHandler.text : "";
|
||||||
|
|
||||||
|
if (code == 200 && req.result == UnityWebRequest.Result.Success)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var parsed = JsonUtility.FromJson<DedicatedWinnerPatchResponse>(body);
|
||||||
|
if (parsed != null && parsed.ok && parsed.economy != null)
|
||||||
|
GameManager.MatchRcPrizeCoins = parsed.economy.rc_prize;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Log("Dedicated winner PATCH: could not parse economy: " + e.Message + " body=" + body);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Log("Dedicated match winner PATCH success: " + code + " " + body);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == 409)
|
||||||
|
{
|
||||||
|
Logger.Log("Dedicated match winner PATCH: winner already recorded (409 idempotent), no second payout. " + body);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Log("Dedicated match winner PATCH failed: " + code + " " + req.error + " " + body);
|
||||||
|
Logger.Log("More details : " + req.url + " " + req.method + " " + body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
class DedicatedWinnerPatchEconomy
|
||||||
|
{
|
||||||
|
public int entry_fee_rc;
|
||||||
|
public int rc_prize;
|
||||||
|
public int participant_cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
class DedicatedWinnerPatchResponse
|
||||||
|
{
|
||||||
|
public bool ok;
|
||||||
|
public int id;
|
||||||
|
public int winner_id;
|
||||||
|
public DedicatedWinnerPatchEconomy economy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using DG.Tweening;
|
using DG.Tweening;
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
|
using UnityEngine.Networking;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
public class GameOverCanvas : MonoBehaviour
|
public class GameOverCanvas : MonoBehaviour
|
||||||
{
|
{
|
||||||
@@ -28,7 +30,7 @@ public class GameOverCanvas : MonoBehaviour
|
|||||||
public Sprite redIcon, blueIcon;
|
public Sprite redIcon, blueIcon;
|
||||||
|
|
||||||
public RectTransform p1_winner, p2_winner;
|
public RectTransform p1_winner, p2_winner;
|
||||||
[Header("Rematch")]
|
[Header("Game Over Data")]
|
||||||
public Button btnRematch;
|
public Button btnRematch;
|
||||||
public Button btnLeave;
|
public Button btnLeave;
|
||||||
public GameObject rematchWarningLoser;
|
public GameObject rematchWarningLoser;
|
||||||
@@ -39,6 +41,17 @@ public class GameOverCanvas : MonoBehaviour
|
|||||||
|
|
||||||
public float returnToMenuCountdown = 15f;
|
public float returnToMenuCountdown = 15f;
|
||||||
|
|
||||||
|
|
||||||
|
[Header("Rematch panel")]
|
||||||
|
public CanvasGroup rematchPanel;
|
||||||
|
public RectTransform rematchPopup;
|
||||||
|
public TMP_Text txtMyRCBalance, txtOpponentRCBalance;
|
||||||
|
public TMP_Text txtSelectedBet;
|
||||||
|
public Slider betSlider;
|
||||||
|
public Button btnConfirmBet;
|
||||||
|
public Button btnCancelBet;
|
||||||
|
|
||||||
|
|
||||||
public static GameOverCanvas instance;
|
public static GameOverCanvas instance;
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
@@ -64,11 +77,38 @@ public class GameOverCanvas : MonoBehaviour
|
|||||||
|
|
||||||
btnRematch.onClick.AddListener(OnBtnRematchClicked);
|
btnRematch.onClick.AddListener(OnBtnRematchClicked);
|
||||||
btnLeave.onClick.AddListener(OnBtnLeaveGameClicked);
|
btnLeave.onClick.AddListener(OnBtnLeaveGameClicked);
|
||||||
|
|
||||||
|
betSlider.onValueChanged.AddListener(OnBetSliderValueChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnBetSliderValueChanged(float value){
|
||||||
|
txtSelectedBet.text = CoinHelper.FormatString((int)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnBtnRematchClicked(){
|
void OnBtnRematchClicked(){
|
||||||
// LevelLoadManager.LoadLevel("Game");
|
// LevelLoadManager.LoadLevel("Game");
|
||||||
|
NetPlayer.localPlayer.RequestRematch();
|
||||||
|
SetRematchPendingState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnRematchRequested(){
|
||||||
|
if(winningTeam == myTeam){
|
||||||
|
//Only i can initiate the rematch, so here we go
|
||||||
|
ShowRematchPanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRematchPendingState(bool val){
|
||||||
|
btnRematch.interactable = false;
|
||||||
|
btnLeave.interactable = !val;
|
||||||
|
if(val){
|
||||||
|
StopCoroutine(countdownCoroutine);
|
||||||
|
}else{
|
||||||
|
countdownCoroutine = StartCoroutine(CoroutineCountdown());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void OnBtnLeaveGameClicked(){
|
void OnBtnLeaveGameClicked(){
|
||||||
LevelLoadManager.LoadLevel("MainMenu");
|
LevelLoadManager.LoadLevel("MainMenu");
|
||||||
}
|
}
|
||||||
@@ -115,10 +155,17 @@ public class GameOverCanvas : MonoBehaviour
|
|||||||
canvasGroup.alpha = 0;
|
canvasGroup.alpha = 0;
|
||||||
canvasGroup.blocksRaycasts = false;
|
canvasGroup.blocksRaycasts = false;
|
||||||
canvasGroup.interactable = false;
|
canvasGroup.interactable = false;
|
||||||
|
|
||||||
|
rematchPanel.alpha=0;
|
||||||
|
rematchPanel.blocksRaycasts = false;
|
||||||
|
rematchPanel.interactable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Team winningTeam;
|
||||||
|
Team myTeam;
|
||||||
public void Setup(Team winningTeam, Team myTeam, int redScore, int blueScore){
|
public void Setup(Team winningTeam, Team myTeam, int redScore, int blueScore){
|
||||||
|
this.winningTeam = winningTeam;
|
||||||
|
this.myTeam = myTeam;
|
||||||
p1_winner.gameObject.SetActive(false);
|
p1_winner.gameObject.SetActive(false);
|
||||||
p2_winner.gameObject.SetActive(false);
|
p2_winner.gameObject.SetActive(false);
|
||||||
if(myTeam == Team.Red){
|
if(myTeam == Team.Red){
|
||||||
@@ -184,10 +231,12 @@ public class GameOverCanvas : MonoBehaviour
|
|||||||
rcPrize = 8.2f;
|
rcPrize = 8.2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
btnRematch.interactable = winningTeam == myTeam;
|
btnRematch.interactable = winningTeam != myTeam;
|
||||||
rematchWarningLoser.SetActive(winningTeam != myTeam);
|
rematchWarningLoser.SetActive(winningTeam == myTeam);
|
||||||
|
|
||||||
StartCoroutine(CoroutineShow());
|
StartCoroutine(CoroutineShow());
|
||||||
|
|
||||||
|
StartCoroutine(CoroutineFetchAndUpdateBalances());
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator CoroutineShow(){
|
IEnumerator CoroutineShow(){
|
||||||
@@ -232,9 +281,9 @@ public class GameOverCanvas : MonoBehaviour
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
StartCoroutine(CoroutineCountdown());
|
countdownCoroutine = StartCoroutine(CoroutineCountdown());
|
||||||
}
|
}
|
||||||
|
Coroutine countdownCoroutine;
|
||||||
|
|
||||||
IEnumerator CoroutineSetTextNumber(float number, TMP_Text text, float speed = 100f, string formatting = "N0", string prefix = "", string suffix = ""){
|
IEnumerator CoroutineSetTextNumber(float number, TMP_Text text, float speed = 100f, string formatting = "N0", string prefix = "", string suffix = ""){
|
||||||
float t=0;
|
float t=0;
|
||||||
@@ -260,4 +309,102 @@ public class GameOverCanvas : MonoBehaviour
|
|||||||
|
|
||||||
LevelLoadManager.LoadLevel("MainMenu");
|
LevelLoadManager.LoadLevel("MainMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ShowRematchPanel(){
|
||||||
|
SetRematchPendingState(true);
|
||||||
|
StartCoroutine(CoroutineShowRematchPanel());
|
||||||
|
|
||||||
|
betSlider.maxValue = (LevelLoadManager.myPlayer.rc < LevelLoadManager.opponentPlayer.rc) ? LevelLoadManager.myPlayer.rc : LevelLoadManager.opponentPlayer.rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator CoroutineShowRematchPanel(){
|
||||||
|
rematchPopup.localScale = new Vector3(0, 0, 0);
|
||||||
|
rematchPanel.blocksRaycasts = true;
|
||||||
|
rematchPanel.interactable = true;
|
||||||
|
rematchPanel.DOFade(1, 0.3f).SetEase(Ease.InOutBack);
|
||||||
|
yield return new WaitForSeconds(0.1f);
|
||||||
|
|
||||||
|
rematchPopup.DOScale(1, 0.2f).SetEase(Ease.OutBack);
|
||||||
|
yield return new WaitForSeconds(0.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void OnRematchCancelled(){
|
||||||
|
SetRematchPendingState(false);
|
||||||
|
StartCoroutine(CoroutineHideRematchPanel());
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator CoroutineHideRematchPanel(){
|
||||||
|
rematchPopup.DOScale(0, 0.2f).SetEase(Ease.InBack);
|
||||||
|
yield return new WaitForSeconds(0.2f);
|
||||||
|
rematchPanel.DOFade(0, 0.3f).SetEase(Ease.InOutBack);
|
||||||
|
yield return new WaitForSeconds(0.3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator CoroutineFetchAndUpdateBalances()
|
||||||
|
{
|
||||||
|
var my = LevelLoadManager.myPlayer;
|
||||||
|
var opp = LevelLoadManager.opponentPlayer;
|
||||||
|
|
||||||
|
string baseUrl = (GameManager.DedicatedInternalApiBase ?? "").TrimEnd('/');
|
||||||
|
if (string.IsNullOrEmpty(baseUrl) || my == null || opp == null)
|
||||||
|
{
|
||||||
|
ApplyRcBalancesToUi(null);
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (my.UserId > 0)
|
||||||
|
yield return FetchPlayerRcAndApply(baseUrl, my);
|
||||||
|
if (opp.UserId > 0 && opp.UserId != my.UserId)
|
||||||
|
yield return FetchPlayerRcAndApply(baseUrl, opp);
|
||||||
|
|
||||||
|
ApplyRcBalancesToUi(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyRcBalancesToUi(string loadingPlaceholder)
|
||||||
|
{
|
||||||
|
var my = LevelLoadManager.myPlayer;
|
||||||
|
var opp = LevelLoadManager.opponentPlayer;
|
||||||
|
string myText = loadingPlaceholder ?? (my != null ? CoinHelper.FormatString((int)my.rc) : "0.0 RC");
|
||||||
|
string oppText = loadingPlaceholder ?? (opp != null ? CoinHelper.FormatString((int)opp.rc) : "0.0 RC");
|
||||||
|
|
||||||
|
if (txtMyRCBalance != null)
|
||||||
|
txtMyRCBalance.text = myText;
|
||||||
|
if (txtOpponentRCBalance != null)
|
||||||
|
txtOpponentRCBalance.text = oppText;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator FetchPlayerRcAndApply(string baseUrl, MatchmadePlayer player)
|
||||||
|
{
|
||||||
|
string url = $"{baseUrl}/players/{player.UserId}/rc";
|
||||||
|
using (var req = UnityWebRequest.Get(url))
|
||||||
|
{
|
||||||
|
yield return req.SendWebRequest();
|
||||||
|
|
||||||
|
if (req.responseCode != 200)
|
||||||
|
{
|
||||||
|
Logger.Log($"Player RC fetch HTTP {(int)req.responseCode}: {req.error} {url}");
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
string text = req.downloadHandler != null ? req.downloadHandler.text : "";
|
||||||
|
if (string.IsNullOrEmpty(text))
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
var resp = JsonUtility.FromJson<PlayerRcApiResponse>(text);
|
||||||
|
if (resp != null && resp.ok)
|
||||||
|
player.rc = resp.rc;
|
||||||
|
else if (resp != null && !string.IsNullOrEmpty(resp.error))
|
||||||
|
Logger.Log($"Player RC fetch: {resp.error} ({url})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
class PlayerRcApiResponse
|
||||||
|
{
|
||||||
|
public bool ok;
|
||||||
|
public int player_id;
|
||||||
|
public float rc;
|
||||||
|
public string error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,4 +216,67 @@ public class NetPlayer : NetworkBehaviour
|
|||||||
void RpcOnPointerUp(){
|
void RpcOnPointerUp(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Request a rematch with the opponent.
|
||||||
|
/// </summary>
|
||||||
|
public void RequestRematch(){
|
||||||
|
if(isServer){
|
||||||
|
GameOverCanvas.instance.OnRematchRequested();
|
||||||
|
RpcRequestRematch();
|
||||||
|
}else{
|
||||||
|
CmdRequestRematch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdRequestRematch(){
|
||||||
|
Logger.Log("Rematch requested");
|
||||||
|
|
||||||
|
if(isServerOnly){
|
||||||
|
//server
|
||||||
|
}else{
|
||||||
|
GameOverCanvas.instance.OnRematchRequested();
|
||||||
|
}
|
||||||
|
RpcRequestRematch();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ClientRpc]
|
||||||
|
void RpcRequestRematch(){
|
||||||
|
GameOverCanvas.instance.OnRematchRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void AcceptRematch(float betRc){
|
||||||
|
if(isServer){
|
||||||
|
OnRematchAccepted(betRc);
|
||||||
|
RpcAcceptRematch(betRc);
|
||||||
|
}else{
|
||||||
|
CmdAcceptRematch(betRc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdAcceptRematch(float betRc){
|
||||||
|
OnRematchAccepted(betRc);
|
||||||
|
RpcAcceptRematch(betRc);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ClientRpc]
|
||||||
|
void RpcAcceptRematch(float betRc){
|
||||||
|
OnRematchAccepted(betRc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnRematchAccepted(float betRc){
|
||||||
|
//Implement here
|
||||||
|
|
||||||
|
if(betRc == 0){
|
||||||
|
//Cancel signal
|
||||||
|
GameOverCanvas.instance.OnRematchCancelled();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public class LevelLoadManager : MonoBehaviour
|
|||||||
public TMP_Text p1_l10, p2_l10;
|
public TMP_Text p1_l10, p2_l10;
|
||||||
public Sprite redIcon, blueIcon;
|
public Sprite redIcon, blueIcon;
|
||||||
public TMP_Text txtMiddle;
|
public TMP_Text txtMiddle;
|
||||||
|
public TMP_Text txtRcPrize;
|
||||||
[Header("Game Over UI")]
|
[Header("Game Over UI")]
|
||||||
public GameObject p1_winner;
|
public GameObject p1_winner;
|
||||||
public GameObject p2_winner;
|
public GameObject p2_winner;
|
||||||
@@ -84,7 +85,7 @@ public class LevelLoadManager : MonoBehaviour
|
|||||||
}
|
}
|
||||||
|
|
||||||
Team myTeam = Team.Red;
|
Team myTeam = Team.Red;
|
||||||
public void SetupMatchMade(Team myTeam_, string opponentName, string myName, string myL10, string opponentL10){
|
public void SetupMatchMade(Team myTeam_, string opponentName, string myName, string myL10, string opponentL10, string rcPrize){
|
||||||
myTeam = myTeam_;
|
myTeam = myTeam_;
|
||||||
matchmadeUI.SetActive(true);
|
matchmadeUI.SetActive(true);
|
||||||
p1_winner.SetActive(false);
|
p1_winner.SetActive(false);
|
||||||
@@ -113,23 +114,24 @@ public class LevelLoadManager : MonoBehaviour
|
|||||||
p2_name.text = myName;
|
p2_name.text = myName;
|
||||||
p1_l10.text = myL10;
|
p1_l10.text = myL10;
|
||||||
p2_l10.text = opponentL10;
|
p2_l10.text = opponentL10;
|
||||||
|
|
||||||
|
txtRcPrize.text = rcPrize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MatchmadePlayer myPlayer;
|
public static MatchmadePlayer myPlayer;
|
||||||
public static MatchmadePlayer opponentPlayer;
|
public static MatchmadePlayer opponentPlayer;
|
||||||
|
|
||||||
public void SetupMatchMade(Team myTeam_, MatchmadePlayer myPlayer_, MatchmadePlayer opponentPlayer_){
|
public void SetupMatchMade(Team myTeam_, MatchmadePlayer myPlayer_, MatchmadePlayer opponentPlayer_, string rcPrize){
|
||||||
myTeam = myTeam_;
|
myTeam = myTeam_;
|
||||||
myPlayer = myPlayer_;
|
myPlayer = myPlayer_;
|
||||||
opponentPlayer = opponentPlayer_;
|
opponentPlayer = opponentPlayer_;
|
||||||
|
|
||||||
string opponentName = opponentPlayer_.Name;
|
string opponentName = opponentPlayer_.Name;
|
||||||
string myName = myPlayer_.Name;
|
string myName = myPlayer_.Name;
|
||||||
|
|
||||||
string myL10 = $"L10 {myPlayer.l10_wins} -{myPlayer.l10_losses}";
|
string myL10 = $"L10 {myPlayer.l10_wins} -{myPlayer.l10_losses}";
|
||||||
string opponentL10 = $"L10 {opponentPlayer.l10_wins} -{opponentPlayer.l10_losses}";
|
string opponentL10 = $"L10 {opponentPlayer.l10_wins} -{opponentPlayer.l10_losses}";
|
||||||
|
|
||||||
SetupMatchMade(myTeam, myName, opponentName, myL10, opponentL10);
|
SetupMatchMade(myTeam, myName, opponentName, myL10, opponentL10, rcPrize);
|
||||||
}
|
}
|
||||||
bool gameOver = false;
|
bool gameOver = false;
|
||||||
public void SetupGameOver(Team winningTeam, int redScore, int blueScore){
|
public void SetupGameOver(Team winningTeam, int redScore, int blueScore){
|
||||||
|
|||||||
@@ -9,15 +9,246 @@ public class MatchmadePlayer
|
|||||||
public int l10_wins;
|
public int l10_wins;
|
||||||
public int l10_losses;
|
public int l10_losses;
|
||||||
public int UserId;
|
public int UserId;
|
||||||
|
/// <summary>Rocket Credits from server (e.g. GET /players/:id/rc). Cached client-side.</summary>
|
||||||
|
public float rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Per-team block from matchmaker GET / when a side is in queue or match is ready.</summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class MatchmadeResponse
|
public class MatchmadeTeamPayload
|
||||||
{
|
{
|
||||||
public MatchmadePlayer[] Players;
|
public MatchmadePlayer[] Players;
|
||||||
public string GameName;
|
public string GameName;
|
||||||
public int Port;
|
public int Port;
|
||||||
public long InitTime;
|
public long InitTime;
|
||||||
|
public bool instance_started;
|
||||||
public int match_id;
|
public int match_id;
|
||||||
|
public int entry_fee;
|
||||||
|
public int rc_prize;
|
||||||
public string your_team;
|
public string your_team;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Envelope from matchmaker fill / rematch success (and in-progress queue state).</summary>
|
||||||
|
[Serializable]
|
||||||
|
public class MatchmadeResponse
|
||||||
|
{
|
||||||
|
public bool ok;
|
||||||
|
public int entry_fee;
|
||||||
|
public int rc_prize;
|
||||||
|
public MatchmadeTeamPayload for_red;
|
||||||
|
public MatchmadeTeamPayload for_blue;
|
||||||
|
/// <summary>Optional root field: which nested block is for this client when both <see cref="for_red"/> and <see cref="for_blue"/> list the same players.</summary>
|
||||||
|
public string your_team;
|
||||||
|
|
||||||
|
public static bool TeamPayloadHasPort(MatchmadeTeamPayload p) =>
|
||||||
|
p != null && p.Port > 0;
|
||||||
|
|
||||||
|
/// <summary>True when both sides are present on the same dedicated instance (2v2-style duplicate rosters).</summary>
|
||||||
|
public static bool IsMatchReadyDuplicateRosters(MatchmadeResponse e)
|
||||||
|
{
|
||||||
|
if (e == null || !e.ok)
|
||||||
|
return false;
|
||||||
|
if (!TeamPayloadHasPort(e.for_red) || !TeamPayloadHasPort(e.for_blue))
|
||||||
|
return false;
|
||||||
|
if (e.for_red.Players == null || e.for_blue.Players == null)
|
||||||
|
return false;
|
||||||
|
if (e.for_red.match_id != e.for_blue.match_id || e.for_red.Port != e.for_blue.Port)
|
||||||
|
return false;
|
||||||
|
return e.for_red.Players.Length >= 2 && e.for_blue.Players.Length >= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>True when each side lists at least one player and together they form a full 1v1 (disjoint user sets, same instance).</summary>
|
||||||
|
public static bool IsMatchReadySplitRosters(MatchmadeResponse e)
|
||||||
|
{
|
||||||
|
if (e == null || !e.ok)
|
||||||
|
return false;
|
||||||
|
if (!TeamPayloadHasPort(e.for_red) || !TeamPayloadHasPort(e.for_blue))
|
||||||
|
return false;
|
||||||
|
if (e.for_red.Players == null || e.for_blue.Players == null)
|
||||||
|
return false;
|
||||||
|
if (e.for_red.match_id != e.for_blue.match_id || e.for_red.Port != e.for_blue.Port)
|
||||||
|
return false;
|
||||||
|
if (e.for_red.Players.Length < 1 || e.for_blue.Players.Length < 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int a = e.for_red.Players[0].UserId;
|
||||||
|
int b = e.for_blue.Players[0].UserId;
|
||||||
|
if (a == b)
|
||||||
|
return false;
|
||||||
|
if (e.for_red.Players.Length == 1 && e.for_blue.Players.Length == 1)
|
||||||
|
return true;
|
||||||
|
// Wider payloads: require no user id appearing on both sides
|
||||||
|
foreach (var pr in e.for_red.Players)
|
||||||
|
{
|
||||||
|
foreach (var pb in e.for_blue.Players)
|
||||||
|
{
|
||||||
|
if (pr.UserId == pb.UserId)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsMatchReady(MatchmadeResponse e) =>
|
||||||
|
IsMatchReadyDuplicateRosters(e) || IsMatchReadySplitRosters(e);
|
||||||
|
|
||||||
|
static bool PayloadContainsUserId(MatchmadeTeamPayload p, int userId)
|
||||||
|
{
|
||||||
|
if (p?.Players == null || userId == 0)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < p.Players.Length; i++)
|
||||||
|
{
|
||||||
|
if (p.Players[i].UserId == userId)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int IndexOfUserId(MatchmadePlayer[] players, int userId)
|
||||||
|
{
|
||||||
|
if (players == null || userId == 0)
|
||||||
|
return -1;
|
||||||
|
for (int i = 0; i < players.Length; i++)
|
||||||
|
{
|
||||||
|
if (players[i].UserId == userId)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Duplicate roster payloads: same users in the same order on red and blue blocks.</summary>
|
||||||
|
static bool SamePlayerOrder(MatchmadePlayer[] a, MatchmadePlayer[] b)
|
||||||
|
{
|
||||||
|
if (a == null || b == null || a.Length != b.Length)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < a.Length; i++)
|
||||||
|
{
|
||||||
|
if (a[i].UserId != b[i].UserId)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When <see cref="for_red"/> and <see cref="for_blue"/> list the same roster in the same order (1v1),
|
||||||
|
/// matchmaker convention: index 0 = red team, index 1 = blue team.
|
||||||
|
/// </summary>
|
||||||
|
static MatchmadeTeamPayload SelectDuplicateRosterBySlot(MatchmadeResponse env, int userId)
|
||||||
|
{
|
||||||
|
MatchmadePlayer[] r = env.for_red?.Players;
|
||||||
|
MatchmadePlayer[] b = env.for_blue?.Players;
|
||||||
|
if (r == null || b == null || r.Length != 2 || b.Length != 2)
|
||||||
|
return null;
|
||||||
|
if (!SamePlayerOrder(r, b))
|
||||||
|
return null;
|
||||||
|
int idx = IndexOfUserId(r, userId);
|
||||||
|
if (idx == 0)
|
||||||
|
return env.for_red;
|
||||||
|
if (idx == 1)
|
||||||
|
return env.for_blue;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Pick the nested block for this client (port, your_team, players for UI).</summary>
|
||||||
|
public static MatchmadeTeamPayload SelectTeamPayload(MatchmadeResponse env, int userId, Team? teamDisambiguation = null)
|
||||||
|
{
|
||||||
|
if (env == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(env.your_team))
|
||||||
|
{
|
||||||
|
string y = env.your_team.Trim().ToLowerInvariant();
|
||||||
|
if (y == "red")
|
||||||
|
return env.for_red;
|
||||||
|
if (y == "blue")
|
||||||
|
return env.for_blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onRed = PayloadContainsUserId(env.for_red, userId);
|
||||||
|
bool onBlue = PayloadContainsUserId(env.for_blue, userId);
|
||||||
|
if (onRed && !onBlue)
|
||||||
|
return env.for_red;
|
||||||
|
if (onBlue && !onRed)
|
||||||
|
return env.for_blue;
|
||||||
|
|
||||||
|
if (onRed && onBlue)
|
||||||
|
{
|
||||||
|
MatchmadeTeamPayload bySlot = SelectDuplicateRosterBySlot(env, userId);
|
||||||
|
if (bySlot != null)
|
||||||
|
return bySlot;
|
||||||
|
|
||||||
|
if (teamDisambiguation.HasValue)
|
||||||
|
{
|
||||||
|
if (teamDisambiguation.Value == Team.Red)
|
||||||
|
return env.for_red;
|
||||||
|
if (teamDisambiguation.Value == Team.Blue)
|
||||||
|
return env.for_blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.LogWarning("MatchmadeResponse: both sides list this user but roster is not 1v1 duplicate order; set root your_team on the server or pass team disambiguation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return env.for_red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Resolve self and opponent from the selected branch (duplicate full roster) or from both sides (split 1v1 rosters).</summary>
|
||||||
|
public static bool TryResolveMyAndOpponent(MatchmadeResponse env, MatchmadeTeamPayload branch, int userId, out MatchmadePlayer myPlayer, out MatchmadePlayer opponentPlayer)
|
||||||
|
{
|
||||||
|
myPlayer = null;
|
||||||
|
opponentPlayer = null;
|
||||||
|
if (env == null || branch == null || branch.Players == null || userId == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MatchmadeTeamPayload other = ReferenceEquals(branch, env.for_blue) ? env.for_red : env.for_blue;
|
||||||
|
|
||||||
|
if (branch.Players.Length >= 2)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < branch.Players.Length; i++)
|
||||||
|
{
|
||||||
|
if (branch.Players[i].UserId == userId)
|
||||||
|
{
|
||||||
|
myPlayer = branch.Players[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (myPlayer == null)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < branch.Players.Length; i++)
|
||||||
|
{
|
||||||
|
if (branch.Players[i].UserId != myPlayer.UserId)
|
||||||
|
{
|
||||||
|
opponentPlayer = branch.Players[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return opponentPlayer != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < branch.Players.Length; i++)
|
||||||
|
{
|
||||||
|
if (branch.Players[i].UserId == userId)
|
||||||
|
{
|
||||||
|
myPlayer = branch.Players[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (myPlayer == null && branch.Players.Length == 1 && branch.Players[0].UserId == userId)
|
||||||
|
myPlayer = branch.Players[0];
|
||||||
|
|
||||||
|
if (other?.Players == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < other.Players.Length; i++)
|
||||||
|
{
|
||||||
|
if (other.Players[i].UserId != userId)
|
||||||
|
{
|
||||||
|
opponentPlayer = other.Players[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opponentPlayer == null && other.Players.Length == 1)
|
||||||
|
opponentPlayer = other.Players[0];
|
||||||
|
|
||||||
|
return myPlayer != null && opponentPlayer != null && myPlayer.UserId != opponentPlayer.UserId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user