Files
GoakeFlax/Source/Game/Player/PlayerInputLocal.cs
2023-12-31 12:15:30 +02:00

150 lines
5.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using FlaxEngine;
using FlaxEngine.Networking;
using Console = Game.Console;
namespace Game
{
public class PlayerInputLocal : PlayerInput
{
protected List<PlayerInputState> buffer = new List<PlayerInputState>();
protected GZipStream demoStream;
protected FileStream demoFileStream;
private PlayerActor playerActor;
public bool IsNetworked => NetworkManager.client != null;
private long flushedFrames = 0;
/*public PlayerInputLocal()
{
}*/
public override bool Predict => true;
public PlayerInputLocal(PlayerActor playerActor, string demoPath = null)
{
this.playerActor = playerActor;
if (demoPath == null)
return;
var demoFolder = Directory.GetParent(demoPath);
if (!demoFolder.Exists)
Directory.CreateDirectory(demoFolder.FullName);
demoFileStream = File.Open(demoPath, FileMode.Create, FileAccess.Write);
demoStream = new GZipStream(demoFileStream, CompressionMode.Compress);
demoStream.WriteByte(DemoVer);
demoStream.WriteByte((byte)Unsafe.SizeOf<PlayerInputState>());
}
public bool IsRecording => demoStream != null;
public override void OnUpdate()
{
// Collect all input here
// All axis values here should be accumulated
float sensitivity = 1.0f / 8.0f;
sensitivity = 1.0f;
//var asf = InputManager.GetAxisRaw("Mouse X");
//if (asf != 0.0f)
// Console.Print(InputManager.GetAxisRaw("Mouse X").ToString("G9", System.Globalization.CultureInfo.InvariantCulture));
currentState.input.viewDeltaX += InputManager.GetAxisRaw("Mouse X") * sensitivity;
currentState.input.viewDeltaY += InputManager.GetAxisRaw("Mouse Y") * sensitivity;
currentState.input.viewDeltaX += InputManager.GetAxisRaw("LookRight") * Time.DeltaTime * 100;
currentState.input.viewDeltaY += -InputManager.GetAxisRaw("LookUp") * Time.DeltaTime * 100;
currentState.input.moveForward = InputManager.GetAxis("Vertical");
currentState.input.moveRight = InputManager.GetAxis("Horizontal");
currentState.input.attacking = InputManager.GetAction("Attack");
currentState.input.jumping = InputManager.GetAction("Jump");
}
public override void OnFixedUpdate()
{
}
public override void OnEndFrame()
{
currentState.input.frame = frame;
if (IsRecording)
{
currentState.input.verificationPosition = currentState.actor.position;
currentState.input.verificationVelocity = currentState.actor.velocity;
currentState.input.verificationViewAngles = currentState.actor.viewAngles;
currentState.input.verificationOrientation = currentState.actor.orientation;
buffer.Add(currentState.input);
}
if (playerActor != null)
{
//playerActor.UpdateNetworkInput(currentState.input.frame, new Float4(currentState.input.viewDeltaX, currentState.input.viewDeltaY, currentState.input.moveForward, currentState.input.moveRight), currentState.input.attacking, currentState.input.jumping);
}
//playerActor.UpdateNetworkInput(currentState.input.frame, currentState.input.viewDeltaX, currentState.input.viewDeltaY, currentState.input.moveForward, currentState.input.moveRight, currentState.input.attacking, currentState.input.jumping, currentState.input.verificationPosition, currentState.input.verificationVelocity, currentState.input.verificationViewAngles, currentState.input.verificationOrientation);
if (IsNetworked)
{
var message = NetworkManager.ClientBeginSendMessage();
message.WriteByte((byte)GameModeMessageType.PlayerInput);
message.WriteUInt64(currentState.input.frame);
message.WriteSingle(currentState.input.viewDeltaX);
message.WriteSingle(currentState.input.viewDeltaY);
message.WriteSingle(currentState.input.moveForward);
message.WriteSingle(currentState.input.moveRight);
message.WriteBoolean(currentState.input.attacking);
message.WriteBoolean(currentState.input.jumping);
NetworkManager.ClientEndSendMessage(ref message);
}
base.OnEndFrame();
// Reset anything accumulatable here
currentState.input.viewDeltaX = 0;
currentState.input.viewDeltaY = 0;
}
public void FlushDemo()
{
if (!IsRecording)
return;
Stopwatch sw = Stopwatch.StartNew();
Span<byte> bytes = stackalloc byte[Unsafe.SizeOf<PlayerInputState>()];
foreach (ref PlayerInputState state in CollectionsMarshal.AsSpan(buffer))
{
MemoryMarshal.Write(bytes, state);
demoStream.Write(bytes);
}
sw.Stop();
flushedFrames += buffer.Count;
buffer.Clear();
FlaxEngine.Debug.Write(LogType.Info, $"Wrote demo in {sw.Elapsed.TotalMilliseconds}ms, frames: {flushedFrames}");
}
public void StopRecording()
{
if (!IsRecording)
return;
FlushDemo();
demoStream.Close();
demoStream = null;
demoFileStream.Close();
demoFileStream = null;
}
}
}