1515 lines
42 KiB
Plaintext
1515 lines
42 KiB
Plaintext
|
|
// /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: <Module>
|
|
// 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<CursorController>
|
|
{
|
|
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<GameManager>
|
|
{
|
|
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<Player>.Instance.transform.SetPositionAndRotation(level.spawnArea.transform.position, level.spawnArea.transform.rotation);
|
|
Singleton<Player>.Instance.EnableControls();
|
|
Singleton<Player>.Instance.Reset();
|
|
Singleton<ReplayRecorder>.Instance.StartRecording();
|
|
Singleton<ReplayPlayer>.Instance.Pause();
|
|
Singleton<HUD>.Instance.Reset();
|
|
}
|
|
|
|
public void EndGame()
|
|
{
|
|
List<FrameRecord> list = Singleton<ReplayRecorder>.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<ReplayRecorder>.Instance.EndRecording();
|
|
Replay replay = ReplayReader.LoadReplay();
|
|
if (replay.frames.Count != 0)
|
|
{
|
|
playMode = PlayMode.REPLAY;
|
|
Singleton<Player>.Instance.DisableControls();
|
|
UnityEngine.Debug.Log(replay.frames.Count);
|
|
Singleton<ReplayPlayer>.Instance.PlayReplay(replay);
|
|
Singleton<ReplayPlayer>.Instance.Resume();
|
|
Singleton<HUD>.Instance.Reset();
|
|
}
|
|
}
|
|
}
|
|
public enum PlayMode
|
|
{
|
|
NORMAL,
|
|
REPLAY
|
|
}
|
|
public class HUD : Singleton<HUD>
|
|
{
|
|
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<GameManager>.Instance.playMode == PlayMode.REPLAY)
|
|
{
|
|
text4 = "REPLAY MODE";
|
|
text3 += "\n\t'SPACE' - PLAY/PAUSE REPLAY";
|
|
}
|
|
else
|
|
{
|
|
text4 = ((!Singleton<GameManager>.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<GameManager>.Instance.StartGame();
|
|
}
|
|
if (Input.GetKeyDown(KeyCode.Backspace))
|
|
{
|
|
Singleton<GameManager>.Instance.PlayReplay();
|
|
}
|
|
if (Input.GetKeyDown(KeyCode.U))
|
|
{
|
|
ReplayWriter.UploadReplay(ReplayReader.LoadReplay());
|
|
}
|
|
if (Singleton<GameManager>.Instance.playMode == PlayMode.NORMAL)
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.Tab))
|
|
{
|
|
Singleton<GameManager>.Instance.EndGame();
|
|
}
|
|
}
|
|
else if (Singleton<GameManager>.Instance.playMode == PlayMode.REPLAY && Input.GetKeyDown(KeyCode.Space))
|
|
{
|
|
Singleton<ReplayPlayer>.Instance.Toggle();
|
|
}
|
|
}
|
|
}
|
|
public class Level : MonoBehaviour
|
|
{
|
|
public ushort levelId;
|
|
|
|
public BoxCollider spawnArea;
|
|
|
|
public BoxCollider flagArea;
|
|
}
|
|
public class Player : Singleton<Player>
|
|
{
|
|
private PlayerActions playerActions;
|
|
|
|
public void Reset()
|
|
{
|
|
playerActions = PlayerActions.None;
|
|
}
|
|
|
|
public void EnableControls()
|
|
{
|
|
GetComponent<PlayerController>().enabled = true;
|
|
}
|
|
|
|
public void DisableControls()
|
|
{
|
|
GetComponent<PlayerController>().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<PlayerController>
|
|
{
|
|
[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<BoxCollider>();
|
|
player = GetComponent<Player>();
|
|
}
|
|
|
|
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<GameManager>.Instance.level.spawnArea)
|
|
{
|
|
if (Singleton<GameManager>.Instance.HasFlag)
|
|
{
|
|
Singleton<ReplayRecorder>.Instance.FinishRun();
|
|
}
|
|
}
|
|
else if (other == Singleton<GameManager>.Instance.level.flagArea)
|
|
{
|
|
player.PerformAction(PlayerActions.TakeFlag);
|
|
Singleton<GameManager>.Instance.HasFlag = true;
|
|
}
|
|
}
|
|
}
|
|
public struct Replay
|
|
{
|
|
public const ulong MAGIC = 72848253210177uL;
|
|
|
|
public const ushort VERSION = 1;
|
|
|
|
public ushort levelId;
|
|
|
|
public List<FrameRecord> frames;
|
|
}
|
|
public struct FrameRecord
|
|
{
|
|
public PlayerRecord playerRecord;
|
|
}
|
|
public class ReplayPlayer : Singleton<ReplayPlayer>
|
|
{
|
|
private LinkedList<FrameRecord> frames;
|
|
|
|
private bool running;
|
|
|
|
public void PlayReplay(Replay replay)
|
|
{
|
|
frames = new LinkedList<FrameRecord>(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<GameManager>.Instance.StartGame();
|
|
return;
|
|
}
|
|
FrameRecord value = frames.First.Value;
|
|
frames.RemoveFirst();
|
|
Singleton<Player>.Instance.ApplyRecord(value.playerRecord);
|
|
}
|
|
}
|
|
}
|
|
public class ReplayReader
|
|
{
|
|
private ushort levelId;
|
|
|
|
private ushort frameCount;
|
|
|
|
private List<FrameRecord> frames;
|
|
|
|
public static Replay LoadReplay()
|
|
{
|
|
Singleton<CursorController>.Instance.UnlockCursor();
|
|
string[] array = StandaloneFileBrowser.OpenFilePanel("Open Replay File", "", "", multiselect: false);
|
|
Singleton<CursorController>.Instance.LockCursor();
|
|
if (array.Length == 0 || string.IsNullOrEmpty(array[0]))
|
|
{
|
|
Replay result = default(Replay);
|
|
result.frames = new List<FrameRecord>();
|
|
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<FrameRecord>(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<FrameRecord>();
|
|
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<ReplayRecorder>
|
|
{
|
|
private List<FrameRecord> frames;
|
|
|
|
private bool runFinished;
|
|
|
|
public void StartRecording()
|
|
{
|
|
frames = new List<FrameRecord>();
|
|
}
|
|
|
|
public List<FrameRecord> EndRecording()
|
|
{
|
|
if (frames == null)
|
|
{
|
|
return null;
|
|
}
|
|
List<FrameRecord> result = new List<FrameRecord>(frames);
|
|
frames = null;
|
|
return result;
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (frames != null)
|
|
{
|
|
runFinished = false;
|
|
Singleton<PlayerController>.Instance.UpdatePlayerController(Time.fixedDeltaTime);
|
|
FrameRecord item = default(FrameRecord);
|
|
item.playerRecord = Singleton<Player>.Instance.Record();
|
|
frames.Add(item);
|
|
if (runFinished)
|
|
{
|
|
Singleton<GameManager>.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<CursorController>.Instance.UnlockCursor();
|
|
string text = StandaloneFileBrowser.SaveFilePanel("Save Binary File", "", "data", "bin");
|
|
Singleton<CursorController>.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<HUD>.Instance.SendNotification("server.txt file not found at " + text);
|
|
return;
|
|
}
|
|
serverURL = File.ReadAllText(text).Trim();
|
|
}
|
|
UnityEngine.Debug.Log("Uploading replay to " + serverURL);
|
|
Singleton<HUD>.Instance.SendNotification("Uploading replay...");
|
|
try
|
|
{
|
|
string text2 = await PostRequest.SendAsync(serverURL, bodyRaw);
|
|
UnityEngine.Debug.Log("Response from server: \n" + text2);
|
|
Singleton<HUD>.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<string> 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<T> : MonoBehaviour where T : MonoBehaviour
|
|
{
|
|
private static T _instance;
|
|
|
|
public static T Instance
|
|
{
|
|
get
|
|
{
|
|
if ((UnityEngine.Object)_instance == (UnityEngine.Object)null)
|
|
{
|
|
_instance = UnityEngine.Object.FindFirstObjectByType<T>();
|
|
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<Button>().onClick.AddListener(OnClick);
|
|
}
|
|
|
|
private void OnClick()
|
|
{
|
|
string[] array = StandaloneFileBrowser.OpenFilePanel("Title", "", ".png", multiselect: false);
|
|
if (array.Length != 0)
|
|
{
|
|
StartCoroutine(OutputRoutine(new Uri(array[0]).AbsoluteUri));
|
|
}
|
|
}
|
|
|
|
private IEnumerator OutputRoutine(string url)
|
|
{
|
|
WWW loader = new WWW(url);
|
|
yield return loader;
|
|
output.texture = loader.texture;
|
|
}
|
|
}
|
|
[RequireComponent(typeof(Button))]
|
|
public class CanvasSampleOpenFileText : MonoBehaviour, IPointerDownHandler, IEventSystemHandler
|
|
{
|
|
public Text output;
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
GetComponent<Button>().onClick.AddListener(OnClick);
|
|
}
|
|
|
|
private void OnClick()
|
|
{
|
|
string[] array = StandaloneFileBrowser.OpenFilePanel("Title", "", "txt", multiselect: false);
|
|
if (array.Length != 0)
|
|
{
|
|
StartCoroutine(OutputRoutine(new Uri(array[0]).AbsoluteUri));
|
|
}
|
|
}
|
|
|
|
private IEnumerator OutputRoutine(string url)
|
|
{
|
|
WWW loader = new WWW(url);
|
|
yield return loader;
|
|
output.text = loader.text;
|
|
}
|
|
}
|
|
[RequireComponent(typeof(Button))]
|
|
public class CanvasSampleOpenFileTextMultiple : MonoBehaviour, IPointerDownHandler, IEventSystemHandler
|
|
{
|
|
public Text output;
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
GetComponent<Button>().onClick.AddListener(OnClick);
|
|
}
|
|
|
|
private void OnClick()
|
|
{
|
|
string[] array = StandaloneFileBrowser.OpenFilePanel("Open File", "", "", multiselect: true);
|
|
if (array.Length != 0)
|
|
{
|
|
List<string> list = new List<string>(array.Length);
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
list.Add(new Uri(array[i]).AbsoluteUri);
|
|
}
|
|
StartCoroutine(OutputRoutine(list.ToArray()));
|
|
}
|
|
}
|
|
|
|
private IEnumerator OutputRoutine(string[] urlArr)
|
|
{
|
|
string outputText = "";
|
|
for (int i = 0; i < urlArr.Length; i++)
|
|
{
|
|
WWW loader = new WWW(urlArr[i]);
|
|
yield return loader;
|
|
outputText += loader.text;
|
|
}
|
|
output.text = outputText;
|
|
}
|
|
}
|
|
[RequireComponent(typeof(Button))]
|
|
public class CanvasSampleSaveFileImage : MonoBehaviour, IPointerDownHandler, IEventSystemHandler
|
|
{
|
|
public Text output;
|
|
|
|
private byte[] _textureBytes;
|
|
|
|
private void Awake()
|
|
{
|
|
int num = 100;
|
|
int num2 = 100;
|
|
Texture2D texture2D = new Texture2D(num, num2, TextureFormat.RGB24, mipChain: false);
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
for (int j = 0; j < num2; j++)
|
|
{
|
|
texture2D.SetPixel(i, j, Color.red);
|
|
}
|
|
}
|
|
texture2D.Apply();
|
|
_textureBytes = texture2D.EncodeToPNG();
|
|
UnityEngine.Object.Destroy(texture2D);
|
|
}
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
GetComponent<Button>().onClick.AddListener(OnClick);
|
|
}
|
|
|
|
public void OnClick()
|
|
{
|
|
string text = StandaloneFileBrowser.SaveFilePanel("Title", "", "sample", "png");
|
|
if (!string.IsNullOrEmpty(text))
|
|
{
|
|
File.WriteAllBytes(text, _textureBytes);
|
|
}
|
|
}
|
|
}
|
|
[RequireComponent(typeof(Button))]
|
|
public class CanvasSampleSaveFileText : MonoBehaviour, IPointerDownHandler, IEventSystemHandler
|
|
{
|
|
public Text output;
|
|
|
|
private string _data = "Example text created by StandaloneFileBrowser";
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
GetComponent<Button>().onClick.AddListener(OnClick);
|
|
}
|
|
|
|
public void OnClick()
|
|
{
|
|
string text = StandaloneFileBrowser.SaveFilePanel("Title", "", "sample", "txt");
|
|
if (!string.IsNullOrEmpty(text))
|
|
{
|
|
File.WriteAllText(text, _data);
|
|
}
|
|
}
|
|
}
|
|
[CompilerGenerated]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
[GeneratedCode("Unity.MonoScriptGenerator.MonoScriptInfoGenerator", null)]
|
|
internal class UnitySourceGeneratedAssemblyMonoScriptTypes_v1
|
|
{
|
|
private struct MonoScriptData
|
|
{
|
|
public byte[] FilePathsData;
|
|
|
|
public byte[] TypesData;
|
|
|
|
public int TotalTypes;
|
|
|
|
public int TotalFiles;
|
|
|
|
public bool IsEditorOnly;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
private static MonoScriptData Get()
|
|
{
|
|
MonoScriptData result = default(MonoScriptData);
|
|
result.FilePathsData = new byte[1197]
|
|
{
|
|
0, 0, 0, 1, 0, 0, 0, 35, 92, 65,
|
|
115, 115, 101, 116, 115, 92, 83, 99, 114, 105,
|
|
112, 116, 115, 92, 67, 117, 114, 115, 111, 114,
|
|
67, 111, 110, 116, 114, 111, 108, 108, 101, 114,
|
|
46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
|
|
30, 92, 65, 115, 115, 101, 116, 115, 92, 83,
|
|
99, 114, 105, 112, 116, 115, 92, 71, 97, 109,
|
|
101, 77, 97, 110, 97, 103, 101, 114, 46, 99,
|
|
115, 0, 0, 0, 1, 0, 0, 0, 22, 92,
|
|
65, 115, 115, 101, 116, 115, 92, 83, 99, 114,
|
|
105, 112, 116, 115, 92, 72, 85, 68, 46, 99,
|
|
115, 0, 0, 0, 1, 0, 0, 0, 23, 92,
|
|
65, 115, 115, 101, 116, 115, 92, 83, 99, 114,
|
|
105, 112, 116, 115, 92, 75, 101, 121, 115, 46,
|
|
99, 115, 0, 0, 0, 1, 0, 0, 0, 24,
|
|
92, 65, 115, 115, 101, 116, 115, 92, 83, 99,
|
|
114, 105, 112, 116, 115, 92, 76, 101, 118, 101,
|
|
108, 46, 99, 115, 0, 0, 0, 2, 0, 0,
|
|
0, 32, 92, 65, 115, 115, 101, 116, 115, 92,
|
|
83, 99, 114, 105, 112, 116, 115, 92, 80, 108,
|
|
97, 121, 101, 114, 92, 80, 108, 97, 121, 101,
|
|
114, 46, 99, 115, 0, 0, 0, 1, 0, 0,
|
|
0, 42, 92, 65, 115, 115, 101, 116, 115, 92,
|
|
83, 99, 114, 105, 112, 116, 115, 92, 80, 108,
|
|
97, 121, 101, 114, 92, 80, 108, 97, 121, 101,
|
|
114, 67, 111, 110, 116, 114, 111, 108, 108, 101,
|
|
114, 46, 99, 115, 0, 0, 0, 2, 0, 0,
|
|
0, 32, 92, 65, 115, 115, 101, 116, 115, 92,
|
|
83, 99, 114, 105, 112, 116, 115, 92, 82, 101,
|
|
112, 108, 97, 121, 92, 82, 101, 112, 108, 97,
|
|
121, 46, 99, 115, 0, 0, 0, 1, 0, 0,
|
|
0, 38, 92, 65, 115, 115, 101, 116, 115, 92,
|
|
83, 99, 114, 105, 112, 116, 115, 92, 82, 101,
|
|
112, 108, 97, 121, 92, 82, 101, 112, 108, 97,
|
|
121, 80, 108, 97, 121, 101, 114, 46, 99, 115,
|
|
0, 0, 0, 1, 0, 0, 0, 38, 92, 65,
|
|
115, 115, 101, 116, 115, 92, 83, 99, 114, 105,
|
|
112, 116, 115, 92, 82, 101, 112, 108, 97, 121,
|
|
92, 82, 101, 112, 108, 97, 121, 82, 101, 97,
|
|
100, 101, 114, 46, 99, 115, 0, 0, 0, 1,
|
|
0, 0, 0, 40, 92, 65, 115, 115, 101, 116,
|
|
115, 92, 83, 99, 114, 105, 112, 116, 115, 92,
|
|
82, 101, 112, 108, 97, 121, 92, 82, 101, 112,
|
|
108, 97, 121, 82, 101, 99, 111, 114, 100, 101,
|
|
114, 46, 99, 115, 0, 0, 0, 1, 0, 0,
|
|
0, 38, 92, 65, 115, 115, 101, 116, 115, 92,
|
|
83, 99, 114, 105, 112, 116, 115, 92, 82, 101,
|
|
112, 108, 97, 121, 92, 82, 101, 112, 108, 97,
|
|
121, 87, 114, 105, 116, 101, 114, 46, 99, 115,
|
|
0, 0, 0, 1, 0, 0, 0, 36, 92, 65,
|
|
115, 115, 101, 116, 115, 92, 83, 99, 114, 105,
|
|
112, 116, 115, 92, 85, 116, 105, 108, 115, 92,
|
|
80, 111, 115, 116, 82, 101, 113, 117, 101, 115,
|
|
116, 46, 99, 115, 0, 0, 0, 1, 0, 0,
|
|
0, 34, 92, 65, 115, 115, 101, 116, 115, 92,
|
|
83, 99, 114, 105, 112, 116, 115, 92, 85, 116,
|
|
105, 108, 115, 92, 83, 105, 110, 103, 108, 101,
|
|
116, 111, 110, 46, 99, 115, 0, 0, 0, 1,
|
|
0, 0, 0, 55, 92, 65, 115, 115, 101, 116,
|
|
115, 92, 83, 116, 97, 110, 100, 97, 108, 111,
|
|
110, 101, 70, 105, 108, 101, 66, 114, 111, 119,
|
|
115, 101, 114, 92, 73, 83, 116, 97, 110, 100,
|
|
97, 108, 111, 110, 101, 70, 105, 108, 101, 66,
|
|
114, 111, 119, 115, 101, 114, 46, 99, 115, 0,
|
|
0, 0, 1, 0, 0, 0, 51, 92, 65, 115,
|
|
115, 101, 116, 115, 92, 83, 116, 97, 110, 100,
|
|
97, 108, 111, 110, 101, 70, 105, 108, 101, 66,
|
|
114, 111, 119, 115, 101, 114, 92, 83, 97, 109,
|
|
112, 108, 101, 92, 66, 97, 115, 105, 99, 83,
|
|
97, 109, 112, 108, 101, 46, 99, 115, 0, 0,
|
|
0, 1, 0, 0, 0, 65, 92, 65, 115, 115,
|
|
101, 116, 115, 92, 83, 116, 97, 110, 100, 97,
|
|
108, 111, 110, 101, 70, 105, 108, 101, 66, 114,
|
|
111, 119, 115, 101, 114, 92, 83, 97, 109, 112,
|
|
108, 101, 92, 67, 97, 110, 118, 97, 115, 83,
|
|
97, 109, 112, 108, 101, 79, 112, 101, 110, 70,
|
|
105, 108, 101, 73, 109, 97, 103, 101, 46, 99,
|
|
115, 0, 0, 0, 1, 0, 0, 0, 64, 92,
|
|
65, 115, 115, 101, 116, 115, 92, 83, 116, 97,
|
|
110, 100, 97, 108, 111, 110, 101, 70, 105, 108,
|
|
101, 66, 114, 111, 119, 115, 101, 114, 92, 83,
|
|
97, 109, 112, 108, 101, 92, 67, 97, 110, 118,
|
|
97, 115, 83, 97, 109, 112, 108, 101, 79, 112,
|
|
101, 110, 70, 105, 108, 101, 84, 101, 120, 116,
|
|
46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
|
|
72, 92, 65, 115, 115, 101, 116, 115, 92, 83,
|
|
116, 97, 110, 100, 97, 108, 111, 110, 101, 70,
|
|
105, 108, 101, 66, 114, 111, 119, 115, 101, 114,
|
|
92, 83, 97, 109, 112, 108, 101, 92, 67, 97,
|
|
110, 118, 97, 115, 83, 97, 109, 112, 108, 101,
|
|
79, 112, 101, 110, 70, 105, 108, 101, 84, 101,
|
|
120, 116, 77, 117, 108, 116, 105, 112, 108, 101,
|
|
46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
|
|
65, 92, 65, 115, 115, 101, 116, 115, 92, 83,
|
|
116, 97, 110, 100, 97, 108, 111, 110, 101, 70,
|
|
105, 108, 101, 66, 114, 111, 119, 115, 101, 114,
|
|
92, 83, 97, 109, 112, 108, 101, 92, 67, 97,
|
|
110, 118, 97, 115, 83, 97, 109, 112, 108, 101,
|
|
83, 97, 118, 101, 70, 105, 108, 101, 73, 109,
|
|
97, 103, 101, 46, 99, 115, 0, 0, 0, 1,
|
|
0, 0, 0, 64, 92, 65, 115, 115, 101, 116,
|
|
115, 92, 83, 116, 97, 110, 100, 97, 108, 111,
|
|
110, 101, 70, 105, 108, 101, 66, 114, 111, 119,
|
|
115, 101, 114, 92, 83, 97, 109, 112, 108, 101,
|
|
92, 67, 97, 110, 118, 97, 115, 83, 97, 109,
|
|
112, 108, 101, 83, 97, 118, 101, 70, 105, 108,
|
|
101, 84, 101, 120, 116, 46, 99, 115, 0, 0,
|
|
0, 2, 0, 0, 0, 54, 92, 65, 115, 115,
|
|
101, 116, 115, 92, 83, 116, 97, 110, 100, 97,
|
|
108, 111, 110, 101, 70, 105, 108, 101, 66, 114,
|
|
111, 119, 115, 101, 114, 92, 83, 116, 97, 110,
|
|
100, 97, 108, 111, 110, 101, 70, 105, 108, 101,
|
|
66, 114, 111, 119, 115, 101, 114, 46, 99, 115,
|
|
0, 0, 0, 1, 0, 0, 0, 59, 92, 65,
|
|
115, 115, 101, 116, 115, 92, 83, 116, 97, 110,
|
|
100, 97, 108, 111, 110, 101, 70, 105, 108, 101,
|
|
66, 114, 111, 119, 115, 101, 114, 92, 83, 116,
|
|
97, 110, 100, 97, 108, 111, 110, 101, 70, 105,
|
|
108, 101, 66, 114, 111, 119, 115, 101, 114, 76,
|
|
105, 110, 117, 120, 46, 99, 115
|
|
};
|
|
result.TypesData = new byte[553]
|
|
{
|
|
0, 0, 0, 0, 17, 124, 67, 117, 114, 115,
|
|
111, 114, 67, 111, 110, 116, 114, 111, 108, 108,
|
|
101, 114, 0, 0, 0, 0, 12, 124, 71, 97,
|
|
109, 101, 77, 97, 110, 97, 103, 101, 114, 0,
|
|
0, 0, 0, 4, 124, 72, 85, 68, 0, 0,
|
|
0, 0, 5, 124, 75, 101, 121, 115, 0, 0,
|
|
0, 0, 6, 124, 76, 101, 118, 101, 108, 0,
|
|
0, 0, 0, 7, 124, 80, 108, 97, 121, 101,
|
|
114, 0, 0, 0, 0, 13, 124, 80, 108, 97,
|
|
121, 101, 114, 82, 101, 99, 111, 114, 100, 0,
|
|
0, 0, 0, 17, 124, 80, 108, 97, 121, 101,
|
|
114, 67, 111, 110, 116, 114, 111, 108, 108, 101,
|
|
114, 0, 0, 0, 0, 7, 124, 82, 101, 112,
|
|
108, 97, 121, 0, 0, 0, 0, 12, 124, 70,
|
|
114, 97, 109, 101, 82, 101, 99, 111, 114, 100,
|
|
0, 0, 0, 0, 13, 124, 82, 101, 112, 108,
|
|
97, 121, 80, 108, 97, 121, 101, 114, 0, 0,
|
|
0, 0, 13, 124, 82, 101, 112, 108, 97, 121,
|
|
82, 101, 97, 100, 101, 114, 0, 0, 0, 0,
|
|
15, 124, 82, 101, 112, 108, 97, 121, 82, 101,
|
|
99, 111, 114, 100, 101, 114, 0, 0, 0, 0,
|
|
13, 124, 82, 101, 112, 108, 97, 121, 87, 114,
|
|
105, 116, 101, 114, 0, 0, 0, 0, 12, 124,
|
|
80, 111, 115, 116, 82, 101, 113, 117, 101, 115,
|
|
116, 0, 0, 0, 0, 10, 124, 83, 105, 110,
|
|
103, 108, 101, 116, 111, 110, 0, 0, 0, 0,
|
|
26, 83, 70, 66, 124, 73, 83, 116, 97, 110,
|
|
100, 97, 108, 111, 110, 101, 70, 105, 108, 101,
|
|
66, 114, 111, 119, 115, 101, 114, 0, 0, 0,
|
|
0, 12, 124, 66, 97, 115, 105, 99, 83, 97,
|
|
109, 112, 108, 101, 0, 0, 0, 0, 26, 124,
|
|
67, 97, 110, 118, 97, 115, 83, 97, 109, 112,
|
|
108, 101, 79, 112, 101, 110, 70, 105, 108, 101,
|
|
73, 109, 97, 103, 101, 0, 0, 0, 0, 25,
|
|
124, 67, 97, 110, 118, 97, 115, 83, 97, 109,
|
|
112, 108, 101, 79, 112, 101, 110, 70, 105, 108,
|
|
101, 84, 101, 120, 116, 0, 0, 0, 0, 33,
|
|
124, 67, 97, 110, 118, 97, 115, 83, 97, 109,
|
|
112, 108, 101, 79, 112, 101, 110, 70, 105, 108,
|
|
101, 84, 101, 120, 116, 77, 117, 108, 116, 105,
|
|
112, 108, 101, 0, 0, 0, 0, 26, 124, 67,
|
|
97, 110, 118, 97, 115, 83, 97, 109, 112, 108,
|
|
101, 83, 97, 118, 101, 70, 105, 108, 101, 73,
|
|
109, 97, 103, 101, 0, 0, 0, 0, 25, 124,
|
|
67, 97, 110, 118, 97, 115, 83, 97, 109, 112,
|
|
108, 101, 83, 97, 118, 101, 70, 105, 108, 101,
|
|
84, 101, 120, 116, 0, 0, 0, 0, 19, 83,
|
|
70, 66, 124, 69, 120, 116, 101, 110, 115, 105,
|
|
111, 110, 70, 105, 108, 116, 101, 114, 0, 0,
|
|
0, 0, 25, 83, 70, 66, 124, 83, 116, 97,
|
|
110, 100, 97, 108, 111, 110, 101, 70, 105, 108,
|
|
101, 66, 114, 111, 119, 115, 101, 114, 0, 0,
|
|
0, 0, 30, 83, 70, 66, 124, 83, 116, 97,
|
|
110, 100, 97, 108, 111, 110, 101, 70, 105, 108,
|
|
101, 66, 114, 111, 119, 115, 101, 114, 76, 105,
|
|
110, 117, 120
|
|
};
|
|
result.TotalFiles = 23;
|
|
result.TotalTypes = 26;
|
|
result.IsEditorOnly = false;
|
|
return result;
|
|
}
|
|
}
|
|
namespace SFB
|
|
{
|
|
public interface IStandaloneFileBrowser
|
|
{
|
|
string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect);
|
|
|
|
string[] OpenFolderPanel(string title, string directory, bool multiselect);
|
|
|
|
string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions);
|
|
|
|
void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb);
|
|
|
|
void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb);
|
|
|
|
void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb);
|
|
}
|
|
public struct ExtensionFilter
|
|
{
|
|
public string Name;
|
|
|
|
public string[] Extensions;
|
|
|
|
public ExtensionFilter(string filterName, params string[] filterExtensions)
|
|
{
|
|
Name = filterName;
|
|
Extensions = filterExtensions;
|
|
}
|
|
}
|
|
public class StandaloneFileBrowser
|
|
{
|
|
private static IStandaloneFileBrowser _platformWrapper;
|
|
|
|
static StandaloneFileBrowser()
|
|
{
|
|
_platformWrapper = new StandaloneFileBrowserLinux();
|
|
}
|
|
|
|
public static string[] OpenFilePanel(string title, string directory, string extension, bool multiselect)
|
|
{
|
|
ExtensionFilter[] extensions = (string.IsNullOrEmpty(extension) ? null : new ExtensionFilter[1]
|
|
{
|
|
new ExtensionFilter("", extension)
|
|
});
|
|
return OpenFilePanel(title, directory, extensions, multiselect);
|
|
}
|
|
|
|
public static string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect)
|
|
{
|
|
return _platformWrapper.OpenFilePanel(title, directory, extensions, multiselect);
|
|
}
|
|
|
|
public static void OpenFilePanelAsync(string title, string directory, string extension, bool multiselect, Action<string[]> cb)
|
|
{
|
|
ExtensionFilter[] extensions = (string.IsNullOrEmpty(extension) ? null : new ExtensionFilter[1]
|
|
{
|
|
new ExtensionFilter("", extension)
|
|
});
|
|
OpenFilePanelAsync(title, directory, extensions, multiselect, cb);
|
|
}
|
|
|
|
public static void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb)
|
|
{
|
|
_platformWrapper.OpenFilePanelAsync(title, directory, extensions, multiselect, cb);
|
|
}
|
|
|
|
public static string[] OpenFolderPanel(string title, string directory, bool multiselect)
|
|
{
|
|
return _platformWrapper.OpenFolderPanel(title, directory, multiselect);
|
|
}
|
|
|
|
public static void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb)
|
|
{
|
|
_platformWrapper.OpenFolderPanelAsync(title, directory, multiselect, cb);
|
|
}
|
|
|
|
public static string SaveFilePanel(string title, string directory, string defaultName, string extension)
|
|
{
|
|
ExtensionFilter[] extensions = (string.IsNullOrEmpty(extension) ? null : new ExtensionFilter[1]
|
|
{
|
|
new ExtensionFilter("", extension)
|
|
});
|
|
return SaveFilePanel(title, directory, defaultName, extensions);
|
|
}
|
|
|
|
public static string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions)
|
|
{
|
|
return _platformWrapper.SaveFilePanel(title, directory, defaultName, extensions);
|
|
}
|
|
|
|
public static void SaveFilePanelAsync(string title, string directory, string defaultName, string extension, Action<string> cb)
|
|
{
|
|
ExtensionFilter[] extensions = (string.IsNullOrEmpty(extension) ? null : new ExtensionFilter[1]
|
|
{
|
|
new ExtensionFilter("", extension)
|
|
});
|
|
SaveFilePanelAsync(title, directory, defaultName, extensions, cb);
|
|
}
|
|
|
|
public static void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb)
|
|
{
|
|
_platformWrapper.SaveFilePanelAsync(title, directory, defaultName, extensions, cb);
|
|
}
|
|
}
|
|
public class StandaloneFileBrowserLinux : IStandaloneFileBrowser
|
|
{
|
|
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
|
public delegate void AsyncCallback(string path);
|
|
|
|
private static Action<string[]> _openFileCb;
|
|
|
|
private static Action<string[]> _openFolderCb;
|
|
|
|
private static Action<string> _saveFileCb;
|
|
|
|
[DllImport("StandaloneFileBrowser")]
|
|
private static extern void DialogInit();
|
|
|
|
[DllImport("StandaloneFileBrowser")]
|
|
private static extern IntPtr DialogOpenFilePanel(string title, string directory, string extension, bool multiselect);
|
|
|
|
[DllImport("StandaloneFileBrowser")]
|
|
private static extern void DialogOpenFilePanelAsync(string title, string directory, string extension, bool multiselect, AsyncCallback callback);
|
|
|
|
[DllImport("StandaloneFileBrowser")]
|
|
private static extern IntPtr DialogOpenFolderPanel(string title, string directory, bool multiselect);
|
|
|
|
[DllImport("StandaloneFileBrowser")]
|
|
private static extern void DialogOpenFolderPanelAsync(string title, string directory, bool multiselect, AsyncCallback callback);
|
|
|
|
[DllImport("StandaloneFileBrowser")]
|
|
private static extern IntPtr DialogSaveFilePanel(string title, string directory, string defaultName, string extension);
|
|
|
|
[DllImport("StandaloneFileBrowser")]
|
|
private static extern void DialogSaveFilePanelAsync(string title, string directory, string defaultName, string extension, AsyncCallback callback);
|
|
|
|
public StandaloneFileBrowserLinux()
|
|
{
|
|
DialogInit();
|
|
}
|
|
|
|
public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect)
|
|
{
|
|
return Marshal.PtrToStringAnsi(DialogOpenFilePanel(title, directory, GetFilterFromFileExtensionList(extensions), multiselect)).Split('\u001c');
|
|
}
|
|
|
|
public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb)
|
|
{
|
|
_openFileCb = cb;
|
|
DialogOpenFilePanelAsync(title, directory, GetFilterFromFileExtensionList(extensions), multiselect, delegate(string result)
|
|
{
|
|
_openFileCb(result.Split('\u001c'));
|
|
});
|
|
}
|
|
|
|
public string[] OpenFolderPanel(string title, string directory, bool multiselect)
|
|
{
|
|
return Marshal.PtrToStringAnsi(DialogOpenFolderPanel(title, directory, multiselect)).Split('\u001c');
|
|
}
|
|
|
|
public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb)
|
|
{
|
|
_openFolderCb = cb;
|
|
DialogOpenFolderPanelAsync(title, directory, multiselect, delegate(string result)
|
|
{
|
|
_openFolderCb(result.Split('\u001c'));
|
|
});
|
|
}
|
|
|
|
public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions)
|
|
{
|
|
return Marshal.PtrToStringAnsi(DialogSaveFilePanel(title, directory, defaultName, GetFilterFromFileExtensionList(extensions)));
|
|
}
|
|
|
|
public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb)
|
|
{
|
|
_saveFileCb = cb;
|
|
DialogSaveFilePanelAsync(title, directory, defaultName, GetFilterFromFileExtensionList(extensions), delegate(string result)
|
|
{
|
|
_saveFileCb(result);
|
|
});
|
|
}
|
|
|
|
private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions)
|
|
{
|
|
if (extensions == null)
|
|
{
|
|
return "";
|
|
}
|
|
string text = "";
|
|
for (int i = 0; i < extensions.Length; i++)
|
|
{
|
|
ExtensionFilter extensionFilter = extensions[i];
|
|
text = text + extensionFilter.Name + ";";
|
|
string[] extensions2 = extensionFilter.Extensions;
|
|
foreach (string text2 in extensions2)
|
|
{
|
|
text = text + text2 + ",";
|
|
}
|
|
text = text.Remove(text.Length - 1);
|
|
text += "|";
|
|
}
|
|
return text.Remove(text.Length - 1);
|
|
}
|
|
}
|
|
}
|