MSCO 2.9.1: fixes without MSCLoader, admin teleport, MSCO branding

- Own JSON reader (MiniJson) instead of Newtonsoft.Json - the server browser failed with
  "Could not load System.Runtime.Serialization" once MSCLoader was gone
- Mouse cursor visible in admin menu/chat/console (PlayerInMenu)
- Intro "Press any key" screen replaced by an MSCO loading screen; hook PlayMakerFSM.Awake too
- Join links while the game runs: picked up from MSCO\join.txt (written by the launcher)
- Admin menu: TELEPORT tab (home, shop, repair shop, inspection, villages, events, Satsuma)
- Window title/icon "MSCO - My Summer Car Online", MSCO logo in the main menu
- In-game UI restyled like the keymaster website (rounded cards, pills, glow, slim scrollbars)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 00:34:03 +02:00
co-authored by Claude Opus 5.5
parent 166f873669
commit 027296d27c
17 changed files with 747 additions and 74 deletions
+34 -7
View File
@@ -6,7 +6,6 @@ using System.IO;
using System.Net.Sockets;
using System.Threading;
// (Unitys WWW wird nicht mehr benutzt - siehe WinHttp)
using Newtonsoft.Json;
using UnityEngine;
namespace MSCO
@@ -26,11 +25,11 @@ namespace MSCO
public bool Featured; // vom Keymaster-Admin hervorgehoben (steht in der Liste oben)
public List<string> Tags = new List<string>(); // Admin-Tags (z.B. "official") und eigene Tags des Servers (Web-Panel)
[JsonIgnore] public int UptimeSeconds = -1;
[JsonIgnore] public List<string> PlayerNames = new List<string>();
[JsonIgnore] public int Ping = -1; // -1 = noch nicht abgefragt
[JsonIgnore] public bool Offline;
[JsonIgnore] public bool IsLocal; // Server auf diesem PC (localhost)
public int UptimeSeconds = -1;
public List<string> PlayerNames = new List<string>();
public int Ping = -1; // -1 = noch nicht abgefragt
public bool Offline;
public bool IsLocal; // Server auf diesem PC (localhost)
}
/// <summary>
@@ -104,7 +103,7 @@ namespace MSCO
}
List<ServerListEntry> list;
try { list = JsonConvert.DeserializeObject<List<ServerListEntry>>(text) ?? new List<ServerListEntry>(); }
try { list = ParseList(text); }
catch (Exception e)
{
Error = "Invalid server list: " + e.Message;
@@ -115,6 +114,34 @@ namespace MSCO
foreach (ServerListEntry entry in list) QueryAsync(entry);
}
/// <summary>Antwort von /api/servers lesen (eigener JSON-Leser, siehe MiniJson).</summary>
static List<ServerListEntry> ParseList(string text)
{
var list = new List<ServerListEntry>();
var items = MiniJson.Parse(text) as List<object>;
if (items == null) throw new FormatException("Expected a list");
foreach (object item in items)
{
var o = item as Dictionary<string, object>;
if (o == null) continue;
list.Add(new ServerListEntry
{
Name = MiniJson.Str(o, "name", ""),
Description = MiniJson.Str(o, "description", ""),
Address = MiniJson.Str(o, "address", ""),
Port = MiniJson.Int(o, "port", 7777),
Players = MiniJson.Int(o, "players"),
MaxPlayers = MiniJson.Int(o, "maxPlayers"),
Version = MiniJson.Str(o, "version", ""),
RequireSteam = MiniJson.Bool(o, "requireSteam", true),
Owner = MiniJson.Str(o, "owner"),
Featured = MiniJson.Bool(o, "featured"),
Tags = MiniJson.Strings(o, "tags"),
});
}
return list;
}
/// <summary>Server auf diesem PC suchen (127.0.0.1, übliche Ports); nur antwortende werden gezeigt.</summary>
void ProbeLocalServers()
{