Co-locate the two cockpit-pod projects into a single repository:
- Console/ : TeslaConsole, the net48 WinForms operator console (decompiled
reconstruction) plus its differential + catalog test suite.
- Launcher/ : TeslaLauncher, the net6 pod-side Service + Agent rewrite.
Adds a combined TeslaSuite.sln, root README documenting the shared wire
contract (and its current duplication, the main follow-up), and a root
.gitignore. Histories were not preserved per request; this is a fresh start
from the current working state of both projects.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
205 lines
5.5 KiB
C#
205 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing.Printing;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
|
|
namespace TeslaConsole.RedPlanet;
|
|
|
|
[Serializable]
|
|
internal class RPMissionResults
|
|
{
|
|
private RPMission mMission;
|
|
|
|
internal DateTime mMissionStart;
|
|
|
|
internal TimeSpan mActuallMissionTime;
|
|
|
|
internal readonly List<MissionEvent> mEvents = new List<MissionEvent>();
|
|
|
|
internal readonly Dictionary<RPPlayer, int> mFinalScores = new Dictionary<RPPlayer, int>();
|
|
|
|
public RPMission Mission => mMission;
|
|
|
|
public DateTime MissionStart => mMissionStart;
|
|
|
|
public TimeSpan ActuallMissionTime => mActuallMissionTime;
|
|
|
|
public IEnumerable<MissionEvent> Events => mEvents;
|
|
|
|
internal RPMissionResults(RPMission mission)
|
|
{
|
|
mMission = mission;
|
|
}
|
|
|
|
public static string GetRPMissionsDirectory()
|
|
{
|
|
string text = Path.Combine(Program.GetCommonAppDataDirectory(), "RP Missions");
|
|
if (!Directory.Exists(text))
|
|
{
|
|
Directory.CreateDirectory(text);
|
|
}
|
|
return text;
|
|
}
|
|
|
|
public static RPMissionResults Load(string file)
|
|
{
|
|
using GZipStream gZipStream = new GZipStream(File.OpenRead(file), CompressionMode.Decompress);
|
|
BinaryFormatter binaryFormatter = new BinaryFormatter();
|
|
RPMissionResults result = (RPMissionResults)binaryFormatter.Deserialize(gZipStream);
|
|
gZipStream.Close();
|
|
return result;
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
string path = Path.Combine(GetRPMissionsDirectory(), mMissionStart.ToString("yyyy-MM-dd HH-mm-ss.ffff") + ".rpm");
|
|
using GZipStream gZipStream = new GZipStream(File.OpenWrite(path), CompressionMode.Compress);
|
|
BinaryFormatter binaryFormatter = new BinaryFormatter();
|
|
binaryFormatter.Serialize(gZipStream, this);
|
|
gZipStream.Close();
|
|
}
|
|
|
|
private RPPlayer GetScoreReportingPlayer(RPPlayer player)
|
|
{
|
|
if (player is RPFootballPlayer)
|
|
{
|
|
RPFootballPlayer rPFootballPlayer = (RPFootballPlayer)player;
|
|
if (rPFootballPlayer.PositionKey != "runner")
|
|
{
|
|
RPFootballMission rPFootballMission = (RPFootballMission)mMission;
|
|
{
|
|
foreach (RPFootballPlayer footballPlayer in rPFootballMission.FootballPlayers)
|
|
{
|
|
if (footballPlayer.PositionKey == "runner" && footballPlayer.TeamKey == rPFootballPlayer.TeamKey)
|
|
{
|
|
return footballPlayer;
|
|
}
|
|
}
|
|
return player;
|
|
}
|
|
}
|
|
}
|
|
return player;
|
|
}
|
|
|
|
public int GetScore(RPPlayer player)
|
|
{
|
|
return GetScore(player, TimeSpan.MaxValue);
|
|
}
|
|
|
|
public int GetScore(RPPlayer player, TimeSpan gameTime)
|
|
{
|
|
RPPlayer scoreReportingPlayer = GetScoreReportingPlayer(player);
|
|
if (gameTime == TimeSpan.MaxValue && mFinalScores.ContainsKey(scoreReportingPlayer))
|
|
{
|
|
return mFinalScores[scoreReportingPlayer];
|
|
}
|
|
int result = 1000;
|
|
TimeSpan timeSpan = TimeSpan.MinValue;
|
|
foreach (MissionEvent mEvent in mEvents)
|
|
{
|
|
if (mEvent is ScoreUpdateEvent && mEvent.ReportingPilot == scoreReportingPlayer && mEvent.GameTime > timeSpan && mEvent.GameTime <= gameTime)
|
|
{
|
|
result = ((ScoreUpdateEvent)mEvent).Score;
|
|
timeSpan = mEvent.GameTime;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public int GetFinalPlace(RPPlayer player)
|
|
{
|
|
int num = 1;
|
|
int score = GetScore(player, TimeSpan.MaxValue);
|
|
if (mMission is RPFootballMission)
|
|
{
|
|
RPFootballMission rPFootballMission = (RPFootballMission)mMission;
|
|
RPFootballPlayer rPFootballPlayer = (RPFootballPlayer)player;
|
|
{
|
|
foreach (RPFootballPlayer footballPlayer in rPFootballMission.FootballPlayers)
|
|
{
|
|
if (footballPlayer.PositionKey == "runner" && footballPlayer.TeamKey != rPFootballPlayer.TeamKey && GetScore(footballPlayer, TimeSpan.MaxValue) > score)
|
|
{
|
|
num++;
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
}
|
|
foreach (RPPlayer player2 in mMission.Players)
|
|
{
|
|
if (player2 != player && GetScore(player2, TimeSpan.MaxValue) > score)
|
|
{
|
|
num++;
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
|
|
public RPPlayer[][] GetChartOrder()
|
|
{
|
|
return GetChartOrder(TimeSpan.MaxValue);
|
|
}
|
|
|
|
public RPPlayer[][] GetChartOrder(TimeSpan gameTime)
|
|
{
|
|
List<Tuple<RPPlayer[], int>> list = new List<Tuple<RPPlayer[], int>>();
|
|
if (mMission is RPFootballMission)
|
|
{
|
|
RPFootballMission rPFootballMission = (RPFootballMission)mMission;
|
|
Dictionary<string, List<RPPlayer>> dictionary = new Dictionary<string, List<RPPlayer>>();
|
|
foreach (RPFootballPlayer footballPlayer in rPFootballMission.FootballPlayers)
|
|
{
|
|
if (!dictionary.ContainsKey(footballPlayer.TeamKey))
|
|
{
|
|
dictionary.Add(footballPlayer.TeamKey, new List<RPPlayer>());
|
|
}
|
|
if (footballPlayer.PositionKey == "runner")
|
|
{
|
|
dictionary[footballPlayer.TeamKey].Insert(0, footballPlayer);
|
|
}
|
|
else
|
|
{
|
|
dictionary[footballPlayer.TeamKey].Add(footballPlayer);
|
|
}
|
|
}
|
|
foreach (List<RPPlayer> value2 in dictionary.Values)
|
|
{
|
|
list.Add(new Tuple<RPPlayer[], int>(value2.ToArray(), GetScore(value2[0], gameTime)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (RPPlayer player in Mission.Players)
|
|
{
|
|
list.Add(new Tuple<RPPlayer[], int>(new RPPlayer[1] { player }, GetScore(player, gameTime)));
|
|
}
|
|
}
|
|
for (int i = 0; i < list.Count - 1; i++)
|
|
{
|
|
for (int j = i + 1; j < list.Count; j++)
|
|
{
|
|
if (list[i].B < list[j].B || (list[i].B == list[j].B && string.CompareOrdinal(list[i].A[0].Name, list[j].A[0].Name) > 0))
|
|
{
|
|
Tuple<RPPlayer[], int> value = list[i];
|
|
list[i] = list[j];
|
|
list[j] = value;
|
|
}
|
|
}
|
|
}
|
|
List<RPPlayer[]> list2 = new List<RPPlayer[]>();
|
|
foreach (Tuple<RPPlayer[], int> item in list)
|
|
{
|
|
list2.Add(item.A);
|
|
}
|
|
return list2.ToArray();
|
|
}
|
|
|
|
public PrintDocument GetPrintDocument()
|
|
{
|
|
return new RPPrintDocument(this);
|
|
}
|
|
}
|