rematch complete
This commit is contained in:
@@ -33,6 +33,109 @@ public class GameManager : NetworkBehaviour
|
||||
Logger.Log($"Configured dedicated match reporting for match id {matchId} with secret {DedicatedMatchSecret} and internal api base {DedicatedInternalApiBase}");
|
||||
}
|
||||
|
||||
/// <summary>Outcome of <see cref="RequestDedicatedRematch"/> (POST <c>/internal/rematch</c>).</summary>
|
||||
public readonly struct DedicatedRematchResult
|
||||
{
|
||||
public readonly bool Success;
|
||||
public readonly long HttpStatusCode;
|
||||
public readonly MatchmadeResponse Response;
|
||||
public readonly string ErrorMessage;
|
||||
|
||||
public DedicatedRematchResult(bool success, long httpStatusCode, MatchmadeResponse response, string errorMessage)
|
||||
{
|
||||
Success = success;
|
||||
HttpStatusCode = httpStatusCode;
|
||||
Response = response;
|
||||
ErrorMessage = errorMessage ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dedicated server only: POST <c>/internal/rematch</c> with <c>X-Dedicated-Server-Secret</c>.
|
||||
/// Blocks until the request finishes (same pattern as <see cref="ReportDedicatedMatchRoomClosed"/>).
|
||||
/// On HTTP 200, returns the same JSON envelope as a successful matchmaker GET room fill: <see cref="MatchmadeResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="userRedId"><c>users.id</c> for red.</param>
|
||||
/// <param name="userBlueId"><c>users.id</c> for blue; must differ from red.</param>
|
||||
/// <param name="entryFee">RC stake per player (non-negative).</param>
|
||||
/// <param name="secret">Overrides <see cref="DedicatedMatchSecret"/> when non-empty.</param>
|
||||
/// <param name="internalApiBaseUrl">Overrides <see cref="DedicatedInternalApiBase"/> when non-empty.</param>
|
||||
public static DedicatedRematchResult RequestDedicatedRematch(int userRedId, int userBlueId, int entryFee, string secret = null, string internalApiBaseUrl = null)
|
||||
{
|
||||
string s = string.IsNullOrEmpty(secret) ? DedicatedMatchSecret : secret;
|
||||
string baseUrl = string.IsNullOrEmpty(internalApiBaseUrl) ? DedicatedInternalApiBase : internalApiBaseUrl.TrimEnd('/');
|
||||
if (string.IsNullOrEmpty(s))
|
||||
return new DedicatedRematchResult(false, 0, null, "Missing dedicated server secret");
|
||||
if (string.IsNullOrEmpty(baseUrl))
|
||||
return new DedicatedRematchResult(false, 0, null, "Missing internal API base URL");
|
||||
|
||||
string json = JsonUtility.ToJson(new DedicatedRematchRequestBody
|
||||
{
|
||||
user_red_id = userRedId,
|
||||
user_blue_id = userBlueId,
|
||||
entry_fee = entryFee
|
||||
});
|
||||
|
||||
using (var req = DedicatedMatschInternalApi.BuildRematchRequest(baseUrl, s, json))
|
||||
{
|
||||
var op = req.SendWebRequest();
|
||||
while (!op.isDone)
|
||||
System.Threading.Thread.Sleep(16);
|
||||
|
||||
string text = req.downloadHandler != null ? req.downloadHandler.text : "";
|
||||
long code = req.responseCode;
|
||||
|
||||
if (req.result != UnityWebRequest.Result.Success &&
|
||||
req.result != UnityWebRequest.Result.ProtocolError)
|
||||
{
|
||||
string netErr = string.IsNullOrEmpty(req.error) ? "Network error" : req.error;
|
||||
Logger.Log("Dedicated rematch POST failed (transport): " + netErr + " " + req.url);
|
||||
return new DedicatedRematchResult(false, code, null, netErr);
|
||||
}
|
||||
|
||||
if (code == 200)
|
||||
{
|
||||
try
|
||||
{
|
||||
var env = JsonUtility.FromJson<MatchmadeResponse>(text);
|
||||
if (env != null && env.ok)
|
||||
return new DedicatedRematchResult(true, code, env, "");
|
||||
string apiErr = TryParseRematchErrorMessage(text);
|
||||
Logger.Log("Dedicated rematch POST 200 but ok=false or parse issue: " + text);
|
||||
return new DedicatedRematchResult(false, code, env, string.IsNullOrEmpty(apiErr) ? "Unexpected response" : apiErr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log("Dedicated rematch POST: could not parse success body: " + e.Message + " body=" + text);
|
||||
return new DedicatedRematchResult(false, code, null, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
string err = TryParseRematchErrorMessage(text);
|
||||
if (string.IsNullOrEmpty(err))
|
||||
err = string.IsNullOrEmpty(text) ? "HTTP " + code : text;
|
||||
Logger.Log("Dedicated rematch POST failed: " + code + " " + err);
|
||||
return new DedicatedRematchResult(false, code, null, err);
|
||||
}
|
||||
}
|
||||
|
||||
static string TryParseRematchErrorMessage(string json)
|
||||
{
|
||||
if (string.IsNullOrEmpty(json))
|
||||
return "";
|
||||
try
|
||||
{
|
||||
var err = JsonUtility.FromJson<DedicatedRematchErrorEnvelope>(json);
|
||||
if (err != null && !string.IsNullOrEmpty(err.error))
|
||||
return err.error;
|
||||
}
|
||||
catch
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>Sets match <c>status</c> to <c>-1</c> (room closed). Safe to call from shutdown paths; runs synchronously so it completes before <c>Application.Quit</c>.</summary>
|
||||
public static void ReportDedicatedMatchRoomClosed()
|
||||
{
|
||||
@@ -704,7 +807,7 @@ public class GameManager : NetworkBehaviour
|
||||
}
|
||||
|
||||
|
||||
void StopClient(){
|
||||
public void StopClient(){
|
||||
try{
|
||||
NetworkManager.singleton.StopClient();
|
||||
}catch(Exception e){
|
||||
@@ -833,6 +936,20 @@ static class DedicatedMatschInternalApi
|
||||
return BuildPatchJson(url, secret, jsonBody);
|
||||
}
|
||||
|
||||
public static UnityWebRequest BuildRematchRequest(string baseUrl, string secret, string jsonBody)
|
||||
{
|
||||
string url = baseUrl.TrimEnd('/') + "/internal/rematch";
|
||||
byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonBody);
|
||||
var req = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST)
|
||||
{
|
||||
uploadHandler = new UploadHandlerRaw(bodyRaw),
|
||||
downloadHandler = new DownloadHandlerBuffer()
|
||||
};
|
||||
req.SetRequestHeader("Content-Type", "application/json");
|
||||
req.SetRequestHeader("X-Dedicated-Server-Secret", secret);
|
||||
return req;
|
||||
}
|
||||
|
||||
static UnityWebRequest BuildPatchJson(string url, string secret, string jsonBody)
|
||||
{
|
||||
byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonBody);
|
||||
@@ -906,3 +1023,18 @@ class DedicatedWinnerPatchResponse
|
||||
public int winner_id;
|
||||
public DedicatedWinnerPatchEconomy economy;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class DedicatedRematchRequestBody
|
||||
{
|
||||
public int user_red_id;
|
||||
public int user_blue_id;
|
||||
public int entry_fee;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class DedicatedRematchErrorEnvelope
|
||||
{
|
||||
public bool ok;
|
||||
public string error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user