联网代码上传
This commit is contained in:
parent
b31dce5c6b
commit
fd0ac158cb
@ -5,7 +5,7 @@ namespace AxiReplay
|
||||
public class NetReplay
|
||||
{
|
||||
int MaxInFrame = 0;
|
||||
int mCurrPlayFrame = -1;
|
||||
public int mCurrPlayFrame = -1;
|
||||
Queue<ReplayStep> mQueueReplay;
|
||||
ReplayStep mNextReplay;
|
||||
ReplayStep mCurrReplay;
|
||||
|
@ -29,14 +29,14 @@ namespace AxibugEmuOnline.Client.Event
|
||||
}
|
||||
}
|
||||
|
||||
public class EventSystem
|
||||
public class Eventer
|
||||
{
|
||||
private static EventSystem instance = new EventSystem();
|
||||
public static EventSystem Instance { get { return instance; } }
|
||||
private static Eventer instance = new Eventer();
|
||||
public static Eventer Instance { get { return instance; } }
|
||||
|
||||
private Dictionary<EEvent, List<Delegate>> eventDic = new Dictionary<EEvent, List<Delegate>>(128);
|
||||
|
||||
private EventSystem() { }
|
||||
private Eventer() { }
|
||||
|
||||
|
||||
#region RegisterEvent
|
||||
|
@ -26,7 +26,7 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
public void RecvChatMsg(byte[] reqData)
|
||||
{
|
||||
Protobuf_ChatMsg_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_ChatMsg_RESP>(reqData);
|
||||
EventSystem.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg);
|
||||
Eventer.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using Google.Protobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Manager
|
||||
{
|
||||
@ -182,7 +182,7 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
Protobuf_Room_List_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_List_RESP>(reqData);
|
||||
for (int i = 0; i < msg.RoomMiniInfoList.Count; i++)
|
||||
AddOrUpdateRoomList(msg.RoomMiniInfoList[i]);
|
||||
EventSystem.Instance.PostEvent(EEvent.OnRoomListAllUpdate);
|
||||
Eventer.Instance.PostEvent(EEvent.OnRoomListAllUpdate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -194,7 +194,7 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
App.log.Debug("单个房间状态更新");
|
||||
Protobuf_Room_Update_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Update_RESP>(reqData);
|
||||
AddOrUpdateRoomList(msg.RoomMiniInfo);
|
||||
EventSystem.Instance.PostEvent(EEvent.OnRoomListSingleUpdate, msg.RoomMiniInfo.GameRomID);
|
||||
Eventer.Instance.PostEvent(EEvent.OnRoomListSingleUpdate, msg.RoomMiniInfo.GameRomID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -247,7 +247,7 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
Protobuf_Room_Join_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Join_RESP>(reqData);
|
||||
mineRoomMiniInfo = msg.RoomMiniInfo;
|
||||
InitRePlay();
|
||||
EventSystem.Instance.PostEvent(EEvent.OnMineJoinRoom);
|
||||
Eventer.Instance.PostEvent(EEvent.OnMineJoinRoom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -273,7 +273,7 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
Protobuf_Room_Leave_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Leave_RESP>(reqData);
|
||||
ReleaseRePlay();
|
||||
mineRoomMiniInfo = null;
|
||||
EventSystem.Instance.PostEvent(EEvent.OnMineLeavnRoom);
|
||||
Eventer.Instance.PostEvent(EEvent.OnMineLeavnRoom);
|
||||
}
|
||||
|
||||
void RecvRoomMyRoomStateChange(byte[] reqData)
|
||||
@ -291,12 +291,12 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
//位置之前有人,但是离开了
|
||||
if (OldPlayer > 0)
|
||||
{
|
||||
EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer);
|
||||
Eventer.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer);
|
||||
if (NewPlayer > 0)//而且害换了一个玩家
|
||||
EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||
Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||
}
|
||||
else //之前没人
|
||||
EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||
Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,7 +322,7 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
if (WaitStep != msg.WaitStep)
|
||||
{
|
||||
WaitStep = msg.WaitStep;
|
||||
EventSystem.Instance.PostEvent(EEvent.OnRoomWaitStepChange, WaitStep);
|
||||
Eventer.Instance.PostEvent(EEvent.OnRoomWaitStepChange, WaitStep);
|
||||
if (WaitStep == 1)
|
||||
{
|
||||
byte[] decompressRawData = Helper.DecompressByteArray(msg.LoadStateRaw.ToByteArray());
|
||||
@ -378,6 +378,11 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
Protobuf_Screnn_Frame msg = ProtoBufHelper.DeSerizlize<Protobuf_Screnn_Frame>(reqData);
|
||||
//解压
|
||||
byte[] data = Helper.DecompressByteArray(msg.RawBitmap.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
internal void SendHostRaw(byte[] stateRaw)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxiReplay;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using VirtualNes.Core;
|
||||
|
||||
@ -90,10 +92,79 @@ namespace AxibugEmuOnline.Client
|
||||
return db.GetMapperNo(rom.GetPROM_CRC(), out mapperNo);
|
||||
}
|
||||
|
||||
private ControllerState m_sampledState;
|
||||
public ControllerState GetControllerState()
|
||||
{
|
||||
var mapper = NesControllerMapper.Get();
|
||||
return mapper.CreateState();
|
||||
if (!InGameUI.Instance.IsOnline)
|
||||
{
|
||||
return m_sampledState;
|
||||
}
|
||||
else
|
||||
{
|
||||
//todo : 从服务器获取帧输入数据
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public void SampleInput()
|
||||
{
|
||||
if (InGameUI.Instance.IsOnline)
|
||||
{
|
||||
if (App.roomMgr.netReplay.NextFrame(out var replayData, out int _))
|
||||
{
|
||||
m_sampledState = FromNet(replayData);
|
||||
var localState = NesControllerMapper.Get().CreateState();
|
||||
var rawData = ToNet(localState);
|
||||
App.roomMgr.SendRoomSingelPlayerInput((uint)App.roomMgr.netReplay.mCurrPlayFrame, rawData);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampledState = default;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampledState = NesControllerMapper.Get().CreateState();
|
||||
}
|
||||
}
|
||||
|
||||
public ControllerState FromNet(AxiReplay.ReplayStep step)
|
||||
{
|
||||
var temp = new ServerInputSnapShot();
|
||||
var result = new ControllerState();
|
||||
temp.all = step.InPut;
|
||||
result.raw0 = temp.p1;
|
||||
result.raw1 = temp.p2;
|
||||
result.raw2 = temp.p3;
|
||||
result.raw3 = temp.p4;
|
||||
result.valid = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public uint ToNet(ControllerState state)
|
||||
{
|
||||
var temp = new ServerInputSnapShot();
|
||||
temp.p1 = (byte)state.raw0;
|
||||
temp.p2 = (byte)state.raw1;
|
||||
temp.p3 = (byte)state.raw2;
|
||||
temp.p4 = (byte)state.raw3;
|
||||
return (uint)temp.all;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 8)]
|
||||
struct ServerInputSnapShot
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public UInt64 all;
|
||||
[FieldOffset(0)]
|
||||
public byte p1;
|
||||
[FieldOffset(1)]
|
||||
public byte p2;
|
||||
[FieldOffset(2)]
|
||||
public byte p3;
|
||||
[FieldOffset(3)]
|
||||
public byte p4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,8 @@ namespace AxibugEmuOnline.Client
|
||||
public Mapper START = new Mapper(EnumButtonType.START);
|
||||
public Mapper MIC = new Mapper(EnumButtonType.MIC);
|
||||
|
||||
|
||||
|
||||
public EnumButtonType GetButtons()
|
||||
{
|
||||
EnumButtonType res = 0;
|
||||
|
@ -8,14 +8,13 @@ using VirtualNes.Core.Debug;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
|
||||
public class NesEmulator : MonoBehaviour
|
||||
{
|
||||
{
|
||||
public NES NesCore { get; private set; }
|
||||
|
||||
public VideoProvider VideoProvider;
|
||||
public AudioProvider AudioProvider;
|
||||
|
||||
public bool m_bPause;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
@ -50,9 +49,16 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (m_bPause) return;
|
||||
|
||||
if (NesCore != null)
|
||||
{
|
||||
Supporter.SampleInput();
|
||||
var controlState = Supporter.GetControllerState();
|
||||
|
||||
//如果未收到Input数据,核心帧不推进
|
||||
if (!controlState.valid) return;
|
||||
|
||||
NesCore.pad.Sync(controlState);
|
||||
NesCore.EmulateFrame(true);
|
||||
|
||||
@ -62,6 +68,17 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
m_bPause = true;
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
{
|
||||
m_bPause = false;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[ContextMenu("ImportNesDB")]
|
||||
public void ImportNesDB()
|
||||
|
@ -1,7 +1,9 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Manager;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using VirtualNes.Core;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
@ -13,22 +15,26 @@ namespace AxibugEmuOnline.Client
|
||||
public override bool Enable => gameObject.activeInHierarchy;
|
||||
|
||||
/// <summary> 指示该游戏实例是否处于联网模式 </summary>
|
||||
public bool IsOnline => App.roomMgr.RoomState <= AxibugProtobuf.RoomGameState.OnlyHost;
|
||||
public bool IsOnline => App.roomMgr.RoomState > AxibugProtobuf.RoomGameState.OnlyHost;
|
||||
|
||||
private RomFile m_rom;
|
||||
private object m_core;
|
||||
private object m_state;
|
||||
|
||||
private List<OptionMenu> menus = new List<OptionMenu>();
|
||||
|
||||
private StepPerformer m_stepPerformer;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
gameObject.SetActiveEx(false);
|
||||
|
||||
m_stepPerformer = new StepPerformer(this);
|
||||
|
||||
menus.Add(new InGameUI_SaveState(this));
|
||||
menus.Add(new InGameUI_LoadState(this));
|
||||
menus.Add(new InGameUI_QuitGame(this));
|
||||
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
@ -73,15 +79,23 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
m_rom = currentRom;
|
||||
m_core = core;
|
||||
m_stepPerformer.Reset();
|
||||
|
||||
if (App.user.IsLoggedIn)
|
||||
{
|
||||
App.roomMgr.SendCreateRoom(m_rom.ID, 0, m_rom.Hash);
|
||||
}
|
||||
|
||||
Eventer.Instance.RegisterEvent<int>(EEvent.OnRoomWaitStepChange, OnServerStepUpdate);
|
||||
|
||||
gameObject.SetActiveEx(true);
|
||||
}
|
||||
|
||||
private void OnServerStepUpdate(int step)
|
||||
{
|
||||
m_stepPerformer.Perform(step);
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
CommandDispatcher.Instance.UnRegistController(this);
|
||||
@ -96,6 +110,7 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
public void QuitGame()
|
||||
{
|
||||
Eventer.Instance.UnregisterEvent<int>(EEvent.OnRoomWaitStepChange, OnServerStepUpdate);
|
||||
App.roomMgr.SendLeavnRoom();
|
||||
App.emu.StopGame();
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using VirtualNes.Core;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class StepPerformer
|
||||
{
|
||||
private InGameUI m_inGameUI;
|
||||
private int m_step = -1;
|
||||
|
||||
public StepPerformer(InGameUI inGameUI)
|
||||
{
|
||||
m_inGameUI = inGameUI;
|
||||
}
|
||||
|
||||
public void Perform(int step)
|
||||
{
|
||||
m_step = step;
|
||||
|
||||
|
||||
switch (m_step)
|
||||
{
|
||||
//等待主机上报快照
|
||||
case 0:
|
||||
PauseCore();
|
||||
if (App.roomMgr.IsHost)
|
||||
{
|
||||
if (m_inGameUI.RomFile.Platform == EnumPlatform.NES)
|
||||
{
|
||||
var stateRaw = m_inGameUI.GetCore<NesEmulator>().NesCore.GetState().ToBytes();
|
||||
App.roomMgr.SendHostRaw(stateRaw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
//加载存档并发送Ready通知
|
||||
case 1:
|
||||
PauseCore();
|
||||
var state = new State();
|
||||
state.FromByte(App.roomMgr.RawData);
|
||||
if (m_inGameUI.RomFile.Platform == EnumPlatform.NES)
|
||||
{
|
||||
m_inGameUI.GetCore<NesEmulator>().NesCore.LoadState(state);
|
||||
}
|
||||
App.roomMgr.SendRoomPlayerReady();
|
||||
break;
|
||||
case 2:
|
||||
m_step = -1;
|
||||
ResumeCore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void PauseCore()
|
||||
{
|
||||
if (m_inGameUI.RomFile.Platform == EnumPlatform.NES)
|
||||
{
|
||||
m_inGameUI.GetCore<NesEmulator>().Pause();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResumeCore()
|
||||
{
|
||||
if (m_inGameUI.RomFile.Platform == EnumPlatform.NES)
|
||||
{
|
||||
m_inGameUI.GetCore<NesEmulator>().Resume();
|
||||
}
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
m_step = -1;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e5033cf98f86804bb50f84e3bbc956a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -131,6 +131,7 @@ namespace AxibugEmuOnline.Client
|
||||
if (!m_bPoped)
|
||||
{
|
||||
m_bPoped = true;
|
||||
|
||||
DOTween.To(
|
||||
() => MenuRoot.anchoredPosition.x,
|
||||
(value) =>
|
||||
@ -142,6 +143,7 @@ namespace AxibugEmuOnline.Client
|
||||
0,
|
||||
0.3f
|
||||
).SetEase(Ease.OutCubic);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,10 +151,11 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
if (m_bPoped)
|
||||
{
|
||||
m_runtimeMenuItems.Clear();
|
||||
|
||||
SelectBorder.gameObject.SetActiveEx(false);
|
||||
|
||||
CommandDispatcher.Instance.UnRegistController(this);
|
||||
m_bPoped = false;
|
||||
Canvas.ForceUpdateCanvases();
|
||||
var width = MenuRoot.rect.width;
|
||||
DOTween.To(
|
||||
@ -166,6 +169,8 @@ namespace AxibugEmuOnline.Client
|
||||
width,
|
||||
0.3f
|
||||
).SetEase(Ease.OutCubic);
|
||||
|
||||
m_bPoped = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,12 @@ namespace VirtualNes.Core
|
||||
{
|
||||
public struct ControllerState
|
||||
{
|
||||
private uint raw0;
|
||||
private uint raw1;
|
||||
private uint raw2;
|
||||
private uint raw3;
|
||||
public uint raw0;
|
||||
public uint raw1;
|
||||
public uint raw2;
|
||||
public uint raw3;
|
||||
|
||||
public bool valid;
|
||||
|
||||
public ControllerState(
|
||||
EnumButtonType player0_buttons,
|
||||
@ -19,6 +21,7 @@ namespace VirtualNes.Core
|
||||
raw1 = (uint)player1_buttons;
|
||||
raw2 = (uint)player2_buttons;
|
||||
raw3 = (uint)player3_buttons;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
public bool HasButton(int player, EnumButtonType button)
|
||||
|
@ -59,6 +59,11 @@ namespace VirtualNes.Core
|
||||
return s_support.GetControllerState();
|
||||
}
|
||||
|
||||
public static void SampleInput()
|
||||
{
|
||||
s_support.SampleInput();
|
||||
}
|
||||
|
||||
public static EmulatorConfig Config => s_support.Config;
|
||||
}
|
||||
|
||||
@ -76,5 +81,6 @@ namespace VirtualNes.Core
|
||||
Stream OpenFile(string directPath, string fileName);
|
||||
bool TryGetMapperNo(ROM rom, out int mapperNo);
|
||||
ControllerState GetControllerState();
|
||||
void SampleInput();
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ enum CommandID
|
||||
// 主机玩家 上行 CMD_Room_HostPlayer_UpdateStateRaw消息,上传即时存档
|
||||
// 主机玩家上传完毕之后,服务器会通知进入Step1
|
||||
//
|
||||
// Step1:服务器广播"等待-全员加载即时存档" CMD_Room_WaitStep WaitStep=[1] 附带即时存档 ---> 客户端:全员等待(主机玩家一人上传)
|
||||
// Step1:服务器广播"等待-全员加载即时存档" CMD_Room_WaitStep WaitStep=[1] 附带即时存档 ---> 客户端:全员等待
|
||||
// 所有玩家确保加载ROM和即时存档,并保持模拟器暂停,准备完毕后 发送 CMD_Room_Player_Ready
|
||||
// 所有玩家Ready之后,服务器会根据所有玩家延迟提前跑若干Frame,通知进入Step2
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user