// /home/cato/ctf/2025/lake/rev/real_ctf/a_real_ctf_linux/a_real_ctf_Data/Managed/Assembly-CSharp.dll // Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null // Global type: // Architecture: AnyCPU (64-bit preferred) // Runtime: v4.0.30319 // Hash algorithm: SHA1 using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading.Tasks; using SFB; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] public class CursorController : Singleton { private bool cursorLocked = true; private void Start() { LockCursor(); } private void Update() { if (Input.GetKeyDown(KeyCode.Escape)) { UnlockCursor(); } if (!cursorLocked && Input.GetMouseButtonDown(0)) { LockCursor(); } } public void LockCursor() { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; cursorLocked = true; } public void UnlockCursor() { Cursor.lockState = CursorLockMode.None; Cursor.visible = true; cursorLocked = false; } } public class GameManager : Singleton { public Level level; private bool hasFlag; public PlayMode playMode { get; private set; } public bool HasFlag { get { return hasFlag; } set { hasFlag = value; if (hasFlag) { level.spawnArea.gameObject.SetActive(value: true); level.flagArea.gameObject.SetActive(value: false); } else { level.spawnArea.gameObject.SetActive(value: false); level.flagArea.gameObject.SetActive(value: true); } } } private void Start() { StartGame(); } public void StartGame() { playMode = PlayMode.NORMAL; HasFlag = false; Singleton.Instance.transform.SetPositionAndRotation(level.spawnArea.transform.position, level.spawnArea.transform.rotation); Singleton.Instance.EnableControls(); Singleton.Instance.Reset(); Singleton.Instance.StartRecording(); Singleton.Instance.Pause(); Singleton.Instance.Reset(); } public void EndGame() { List list = Singleton.Instance.EndRecording(); if (list != null) { Replay replay = default(Replay); replay.levelId = level.levelId; replay.frames = list; Replay replay2 = replay; ReplayWriter.SaveReplay(replay2); ReplayWriter.UploadReplay(replay2); StartGame(); } } public void PlayReplay() { Singleton.Instance.EndRecording(); Replay replay = ReplayReader.LoadReplay(); if (replay.frames.Count != 0) { playMode = PlayMode.REPLAY; Singleton.Instance.DisableControls(); UnityEngine.Debug.Log(replay.frames.Count); Singleton.Instance.PlayReplay(replay); Singleton.Instance.Resume(); Singleton.Instance.Reset(); } } } public enum PlayMode { NORMAL, REPLAY } public class HUD : Singleton { private float deltaTime; private long startTime; private string notification = ""; public void Reset() { startTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); } private void Update() { deltaTime += (Time.deltaTime - deltaTime) * 0.1f; } private void OnGUI() { int width = Screen.width; int height = Screen.height; GUIStyle gUIStyle = new GUIStyle(); Rect position = new Rect(10f, 10f, width, height * 2 / 100); gUIStyle.alignment = TextAnchor.UpperLeft; gUIStyle.fontSize = height * 3 / 100; gUIStyle.normal.textColor = Color.white; float num = 1f / deltaTime; string text = $"{num:0.} FPS"; long num2 = DateTimeOffset.Now.ToUnixTimeMilliseconds() - startTime; string text2 = $"Time elapsed {(double)num2 / 1000.0:0.}s"; string text3 = "Keys:"; text3 += "\n\t'ESCAPE' - UNLOCK CURSOR"; text3 += "\n\t'ENTER' - START NEW RUN"; text3 += "\n\t'BACKSPACE' - PLAY REPLAY"; text3 += "\n\t'U' - UPLOAD REPLAY"; string text4; if (Singleton.Instance.playMode == PlayMode.REPLAY) { text4 = "REPLAY MODE"; text3 += "\n\t'SPACE' - PLAY/PAUSE REPLAY"; } else { text4 = ((!Singleton.Instance.HasFlag) ? "OBJECTIVE : CAPTURE THE FLAG" : "OBJECTIVE : RETURN TO SPAWN"); text3 += "\n\t'TAB' - END RUN"; } string text5 = text + "\n" + text2 + "\n" + text4 + "\n\n" + text3 + "\n\n" + notification; GUI.Label(position, text5, gUIStyle); } public void SendNotification(string message) { notification = message; } } public class Keys : MonoBehaviour { private void Update() { if (Input.GetKeyDown(KeyCode.Return)) { Singleton.Instance.StartGame(); } if (Input.GetKeyDown(KeyCode.Backspace)) { Singleton.Instance.PlayReplay(); } if (Input.GetKeyDown(KeyCode.U)) { ReplayWriter.UploadReplay(ReplayReader.LoadReplay()); } if (Singleton.Instance.playMode == PlayMode.NORMAL) { if (Input.GetKeyDown(KeyCode.Tab)) { Singleton.Instance.EndGame(); } } else if (Singleton.Instance.playMode == PlayMode.REPLAY && Input.GetKeyDown(KeyCode.Space)) { Singleton.Instance.Toggle(); } } } public class Level : MonoBehaviour { public ushort levelId; public BoxCollider spawnArea; public BoxCollider flagArea; } public class Player : Singleton { private PlayerActions playerActions; public void Reset() { playerActions = PlayerActions.None; } public void EnableControls() { GetComponent().enabled = true; } public void DisableControls() { GetComponent().enabled = false; } public void PerformAction(PlayerActions action) { playerActions |= action; } public PlayerRecord Record() { PlayerRecord playerRecord = default(PlayerRecord); playerRecord.position = base.transform.position; playerRecord.rotation = base.transform.rotation; playerRecord.playerActions = playerActions; PlayerRecord result = playerRecord; playerActions = PlayerActions.None; return result; } public void ApplyRecord(PlayerRecord playerRecord) { base.transform.position = playerRecord.position; base.transform.rotation = playerRecord.rotation; } } public struct PlayerRecord { public Vector3 position; public Quaternion rotation; public PlayerActions playerActions; } [Flags] public enum PlayerActions : byte { None = 0, Jump = 1, Forward = 2, Backward = 4, Left = 8, Right = 0x10, TakeFlag = 0x20, Collision = 0x80 } [RequireComponent(typeof(BoxCollider))] public class PlayerController : Singleton { [Header("Mouse Settings")] public float mouseSensitivity = 100f; public Transform playerCamera; [Header("Movement Settings")] public float speed = 5f; public float gravity = -9.81f; public float jumpHeight = 2f; [SerializeField] private LayerMask triggerAreaMask; private BoxCollider boxCollider; private Vector3 velocity; [SerializeField] private bool isGrounded; private float xRotation; private Player player; private const float skinWidth = 0.01f; private void Start() { boxCollider = GetComponent(); player = GetComponent(); } public void UpdatePlayerController(float deltaTime) { HandleMouseLook(deltaTime); HandleMovement(deltaTime); } private void HandleMouseLook(float deltaTime) { float num = Input.GetAxis("Mouse X") * mouseSensitivity * deltaTime; float num2 = Input.GetAxis("Mouse Y") * mouseSensitivity * deltaTime; xRotation -= num2; xRotation = Mathf.Clamp(xRotation, -90f, 90f); playerCamera.localRotation = Quaternion.Euler(xRotation, 0f, 0f); base.transform.Rotate(Vector3.up * num); } private void HandleMovement(float deltaTime) { isGrounded = CheckGrounded(); float num = Input.GetAxisRaw("Horizontal"); float num2 = Input.GetAxisRaw("Vertical"); if (num < 0f) { player.PerformAction(PlayerActions.Left); num = -1f; } else if (num > 0f) { player.PerformAction(PlayerActions.Right); num = 1f; } if (num2 < 0f) { player.PerformAction(PlayerActions.Backward); num2 = -1f; } else if (num2 > 0f) { player.PerformAction(PlayerActions.Forward); num2 = 1f; } Vector3 vector = (base.transform.right * num + base.transform.forward * num2).normalized * speed * deltaTime; if (isGrounded) { if (Input.GetButtonDown("Jump")) { velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity); player.PerformAction(PlayerActions.Jump); } else { velocity.y = 0f; } } else { velocity.y += gravity * deltaTime; } Vector3 vector2 = Vector3.up * velocity.y * deltaTime; MoveAndCollide(vector + vector2); } private void MoveAndCollide(Vector3 move) { Vector3 position = base.transform.position; position += Vector3.right * move.x; position = ResolveCollisions(position); position += Vector3.up * move.y; position = ResolveCollisions(position); position += Vector3.forward * move.z; position = ResolveCollisions(position); base.transform.position = position; } private Vector3 ResolveCollisions(Vector3 targetPos) { Collider[] array = Physics.OverlapBox(targetPos + boxCollider.center, boxCollider.size * 0.5f, base.transform.rotation); foreach (Collider collider in array) { if (collider == boxCollider) { continue; } if (collider.isTrigger) { OnTriggerEnter(collider); continue; } player.PerformAction(PlayerActions.Collision); if (Physics.ComputePenetration(boxCollider, targetPos + boxCollider.center, base.transform.rotation, collider, collider.transform.position, collider.transform.rotation, out var direction, out var distance) && distance > 0.0005f) { targetPos += direction * (distance + 0.01f); } } return targetPos; } private bool CheckGrounded() { float num = 0.05f; Vector3 vector = base.transform.position + boxCollider.center; Vector3 vector2 = boxCollider.size * 0.5f - Vector3.up * 0.01f; int layer = base.gameObject.layer; return Physics.CheckBox(layerMask: ~((1 << layer) | (int)triggerAreaMask), center: vector + Vector3.down * (vector2.y + num), halfExtents: new Vector3(vector2.x, 0.05f, vector2.z), orientation: base.transform.rotation); } private void OnDrawGizmosSelected() { if (!(boxCollider == null)) { Gizmos.color = Color.yellow; Gizmos.matrix = base.transform.localToWorldMatrix; Gizmos.DrawWireCube(boxCollider.center, boxCollider.size); } } private void OnTriggerEnter(Collider other) { if (!base.enabled) { return; } if (other == Singleton.Instance.level.spawnArea) { if (Singleton.Instance.HasFlag) { Singleton.Instance.FinishRun(); } } else if (other == Singleton.Instance.level.flagArea) { player.PerformAction(PlayerActions.TakeFlag); Singleton.Instance.HasFlag = true; } } } public struct Replay { public const ulong MAGIC = 72848253210177uL; public const ushort VERSION = 1; public ushort levelId; public List frames; } public struct FrameRecord { public PlayerRecord playerRecord; } public class ReplayPlayer : Singleton { private LinkedList frames; private bool running; public void PlayReplay(Replay replay) { frames = new LinkedList(replay.frames); } public void Resume() { running = true; } public void Pause() { running = false; } public void Toggle() { running = !running; } private void FixedUpdate() { if (running) { if (frames.Count == 0) { Singleton.Instance.StartGame(); return; } FrameRecord value = frames.First.Value; frames.RemoveFirst(); Singleton.Instance.ApplyRecord(value.playerRecord); } } } public class ReplayReader { private ushort levelId; private ushort frameCount; private List frames; public static Replay LoadReplay() { Singleton.Instance.UnlockCursor(); string[] array = StandaloneFileBrowser.OpenFilePanel("Open Replay File", "", "", multiselect: false); Singleton.Instance.LockCursor(); if (array.Length == 0 || string.IsNullOrEmpty(array[0])) { Replay result = default(Replay); result.frames = new List(); return result; } string path = array[0]; ReplayReader replayReader = new ReplayReader(); using FileStream input = new FileStream(path, FileMode.Open, FileAccess.Read); using BinaryReader reader = new BinaryReader(input); replayReader.readHeader(reader); replayReader.readFrames(reader); Replay result = default(Replay); result.levelId = replayReader.levelId; result.frames = new List(replayReader.frames); return result; } private void readHeader(BinaryReader reader) { if (reader.ReadUInt64() != 72848253210177L) { throw new Exception("Invalid replay file: MAGIC mismatch."); } ushort num = reader.ReadUInt16(); if (num != 1) { throw new Exception($"Unsupported replay version: {num} (expected {(ushort)1})"); } levelId = reader.ReadUInt16(); frameCount = reader.ReadUInt16(); } private void readFrames(BinaryReader reader) { frames = new List(); for (ushort num = 0; num < frameCount; num = (ushort)(num + 1)) { frames.Add(readFrame(reader)); } } private static FrameRecord readFrame(BinaryReader reader) { PlayerRecord playerRecord = readPlayer(reader); FrameRecord result = default(FrameRecord); result.playerRecord = playerRecord; return result; } private static PlayerRecord readPlayer(BinaryReader reader) { PlayerRecord result = default(PlayerRecord); result.position.x = reader.ReadSingle(); result.position.y = reader.ReadSingle(); result.position.z = reader.ReadSingle(); result.rotation.x = reader.ReadSingle(); result.rotation.y = reader.ReadSingle(); result.rotation.z = reader.ReadSingle(); result.rotation.w = reader.ReadSingle(); result.playerActions = (PlayerActions)reader.ReadByte(); return result; } } public class ReplayRecorder : Singleton { private List frames; private bool runFinished; public void StartRecording() { frames = new List(); } public List EndRecording() { if (frames == null) { return null; } List result = new List(frames); frames = null; return result; } private void FixedUpdate() { if (frames != null) { runFinished = false; Singleton.Instance.UpdatePlayerController(Time.fixedDeltaTime); FrameRecord item = default(FrameRecord); item.playerRecord = Singleton.Instance.Record(); frames.Add(item); if (runFinished) { Singleton.Instance.EndGame(); } } } public void FinishRun() { runFinished = true; } } internal class ReplayWriter { private Replay replay; public static string serverURL; private ReplayWriter(Replay replay) { this.replay = replay; } public static void SaveReplay(Replay replay) { Singleton.Instance.UnlockCursor(); string text = StandaloneFileBrowser.SaveFilePanel("Save Binary File", "", "data", "bin"); Singleton.Instance.LockCursor(); if (text.Length != 0 && !string.IsNullOrEmpty(text)) { File.WriteAllBytes(text, replayToBytes(replay)); } } public static async void SendReplay(byte[] bodyRaw) { if (string.IsNullOrEmpty(serverURL)) { string text = Path.Combine(Application.dataPath, "../server.txt"); if (!File.Exists(text)) { UnityEngine.Debug.LogError("server.txt file not found at " + text); Singleton.Instance.SendNotification("server.txt file not found at " + text); return; } serverURL = File.ReadAllText(text).Trim(); } UnityEngine.Debug.Log("Uploading replay to " + serverURL); Singleton.Instance.SendNotification("Uploading replay..."); try { string text2 = await PostRequest.SendAsync(serverURL, bodyRaw); UnityEngine.Debug.Log("Response from server: \n" + text2); Singleton.Instance.SendNotification("Response from server: \n" + text2); } catch (Exception ex) { UnityEngine.Debug.LogError("Error: " + ex.Message); } } public static void UploadReplay(Replay replay) { SendReplay(replayToBytes(replay)); } private static byte[] replayToBytes(Replay replay) { ReplayWriter replayWriter = new ReplayWriter(replay); using MemoryStream memoryStream = new MemoryStream(); using (BinaryWriter writer = new BinaryWriter(memoryStream)) { replayWriter.writeHeader(writer); replayWriter.writeFrames(writer); } return memoryStream.ToArray(); } private void writeHeader(BinaryWriter writer) { if (replay.frames.Count > 65535) { throw new Exception("Too many frames in replay to save!"); } writer.Write(72848253210177uL); writer.Write((ushort)1); writer.Write(replay.levelId); writer.Write((ushort)replay.frames.Count); } private void writeFrames(BinaryWriter writer) { foreach (FrameRecord frame in replay.frames) { writeFrame(writer, frame); } } private void writeFrame(BinaryWriter writer, FrameRecord frame) { writePlayer(writer, frame.playerRecord); } private void writePlayer(BinaryWriter writer, PlayerRecord player) { writer.Write(player.position.x); writer.Write(player.position.y); writer.Write(player.position.z); writer.Write(player.rotation.x); writer.Write(player.rotation.y); writer.Write(player.rotation.z); writer.Write(player.rotation.w); writer.Write((byte)player.playerActions); } } public class PostRequest { public static async Task SendAsync(string url, byte[] bodyRaw) { using UnityWebRequest request = new UnityWebRequest(url, "POST"); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); UnityWebRequestAsyncOperation operation = request.SendWebRequest(); while (!operation.isDone) { await Task.Yield(); } if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError) { throw new Exception(request.error); } return request.downloadHandler.text; } } public abstract class Singleton : MonoBehaviour where T : MonoBehaviour { private static T _instance; public static T Instance { get { if ((UnityEngine.Object)_instance == (UnityEngine.Object)null) { _instance = UnityEngine.Object.FindFirstObjectByType(); if ((UnityEngine.Object)_instance == (UnityEngine.Object)null) { throw new Exception("No instance of " + typeof(T).Name + " found in the scene."); } } return _instance; } } protected virtual void Awake() { if ((UnityEngine.Object)_instance != (UnityEngine.Object)null && _instance != this) { UnityEngine.Object.Destroy(base.gameObject); } else { _instance = this as T; } } } public class BasicSample : MonoBehaviour { private string _path; private void OnGUI() { GUI.matrix = Matrix4x4.TRS(s: new Vector3((float)Screen.width / 800f, (float)Screen.height / 600f, 1f), pos: Vector3.zero, q: Quaternion.identity); GUILayout.Space(20f); GUILayout.BeginHorizontal(); GUILayout.Space(20f); GUILayout.BeginVertical(); if (GUILayout.Button("Open File")) { WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "", multiselect: false)); } GUILayout.Space(5f); if (GUILayout.Button("Open File Async")) { StandaloneFileBrowser.OpenFilePanelAsync("Open File", "", "", multiselect: false, delegate(string[] paths) { WriteResult(paths); }); } GUILayout.Space(5f); if (GUILayout.Button("Open File Multiple")) { WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "", multiselect: true)); } GUILayout.Space(5f); if (GUILayout.Button("Open File Extension")) { WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "txt", multiselect: true)); } GUILayout.Space(5f); if (GUILayout.Button("Open File Directory")) { WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", Application.dataPath, "", multiselect: true)); } GUILayout.Space(5f); if (GUILayout.Button("Open File Filter")) { ExtensionFilter[] extensions = new ExtensionFilter[3] { new ExtensionFilter("Image Files", "png", "jpg", "jpeg"), new ExtensionFilter("Sound Files", "mp3", "wav"), new ExtensionFilter("All Files", "*") }; WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", extensions, multiselect: true)); } GUILayout.Space(15f); if (GUILayout.Button("Open Folder")) { string[] paths2 = StandaloneFileBrowser.OpenFolderPanel("Select Folder", "", multiselect: true); WriteResult(paths2); } GUILayout.Space(5f); if (GUILayout.Button("Open Folder Async")) { StandaloneFileBrowser.OpenFolderPanelAsync("Select Folder", "", multiselect: true, delegate(string[] paths) { WriteResult(paths); }); } GUILayout.Space(5f); if (GUILayout.Button("Open Folder Directory")) { string[] paths3 = StandaloneFileBrowser.OpenFolderPanel("Select Folder", Application.dataPath, multiselect: true); WriteResult(paths3); } GUILayout.Space(15f); if (GUILayout.Button("Save File")) { _path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "", ""); } GUILayout.Space(5f); if (GUILayout.Button("Save File Async")) { StandaloneFileBrowser.SaveFilePanelAsync("Save File", "", "", "", delegate(string path) { WriteResult(path); }); } GUILayout.Space(5f); if (GUILayout.Button("Save File Default Name")) { _path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", ""); } GUILayout.Space(5f); if (GUILayout.Button("Save File Default Name Ext")) { _path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", "dat"); } GUILayout.Space(5f); if (GUILayout.Button("Save File Directory")) { _path = StandaloneFileBrowser.SaveFilePanel("Save File", Application.dataPath, "", ""); } GUILayout.Space(5f); if (GUILayout.Button("Save File Filter")) { ExtensionFilter[] extensions2 = new ExtensionFilter[2] { new ExtensionFilter("Binary", "bin"), new ExtensionFilter("Text", "txt") }; _path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", extensions2); } GUILayout.EndVertical(); GUILayout.Space(20f); GUILayout.Label(_path); GUILayout.EndHorizontal(); } public void WriteResult(string[] paths) { if (paths.Length != 0) { _path = ""; foreach (string text in paths) { _path = _path + text + "\n"; } } } public void WriteResult(string path) { _path = path; } } [RequireComponent(typeof(Button))] public class CanvasSampleOpenFileImage : MonoBehaviour, IPointerDownHandler, IEventSystemHandler { public RawImage output; public void OnPointerDown(PointerEventData eventData) { } private void Start() { GetComponent