major update

This commit is contained in:
2023-03-06 10:06:43 +04:00
parent e84511e1ae
commit cbda5e9974
174 changed files with 7441 additions and 1975 deletions
@@ -0,0 +1,35 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class AuthorizeFailedHandler: Handler
{
private readonly RagonListenerList _listenerList;
public AuthorizeFailedHandler(RagonListenerList list)
{
_listenerList = list;
}
public void Handle(RagonBuffer buffer)
{
var message = buffer.ReadString();
_listenerList.OnAuthorizationFailed(message);
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class AuthorizeSuccessHandler: Handler
{
private readonly RagonListenerList _listenerList;
public AuthorizeSuccessHandler(RagonListenerList listenerList)
{
_listenerList = listenerList;
}
public void Handle(RagonBuffer buffer)
{
var playerId = buffer.ReadString();
var playerName = buffer.ReadString();
_listenerList.OnAuthorizationSuccess(playerId, playerName);
}
}
@@ -0,0 +1,58 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class EntityCreateHandler : Handler
{
private readonly RagonClient _client;
private readonly RagonPlayerCache _playerCache;
private readonly RagonEntityCache _entityCache;
public EntityCreateHandler(
RagonClient client,
RagonPlayerCache playerCache,
RagonEntityCache entityCache
)
{
_client = client;
_entityCache = entityCache;
_playerCache = playerCache;
}
public void Handle(RagonBuffer buffer)
{
var attachId = buffer.ReadUShort();
var entityType = buffer.ReadUShort();
var entityId = buffer.ReadUShort();
var ownerId = buffer.ReadUShort();
var player = _playerCache.GetPlayerByPeer(ownerId);
var payload = new RagonPayload(buffer.Capacity);
payload.Read(buffer);
if (player == null)
{
RagonLog.Warn($"Owner {ownerId}|{player.Name} not found in players");
return;
}
var hasAuthority = _playerCache.LocalPlayer.Id == player.Id;
var entity = _entityCache.OnCreate(attachId, entityType, 0, entityId, hasAuthority);
entity.Attach(_client, entityId, entityType, hasAuthority, player, payload);
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class EntityDestroyHandler: Handler
{
private readonly RagonEntityCache _entityCache;
public EntityDestroyHandler(RagonEntityCache entityCache)
{
_entityCache = entityCache;
}
public void Handle(RagonBuffer buffer)
{
var entityId = buffer.ReadUShort();
var payload = new RagonPayload(buffer.Capacity);
payload.Read(buffer);
_entityCache.OnDestroy(entityId, payload);
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class EntityEventHandler : Handler
{
private readonly RagonClient _client;
private readonly RagonPlayerCache _playerCache;
private readonly RagonEntityCache _entityCache;
public EntityEventHandler(
RagonClient client,
RagonPlayerCache playerCache,
RagonEntityCache entityCache
)
{
_client = client;
_playerCache = playerCache;
_entityCache = entityCache;
}
public void Handle(RagonBuffer buffer)
{
var eventCode = buffer.ReadUShort();
var peerId = buffer.ReadUShort();
var executionMode = (RagonReplicationMode)buffer.ReadByte();
var entityId = buffer.ReadUShort();
var player = _playerCache.GetPlayerByPeer(peerId);
if (player == null)
{
RagonLog.Warn($"Player not found for event {eventCode}");
return;
}
if (player.IsMe && executionMode == RagonReplicationMode.LocalAndServer)
return;
_entityCache.OnEvent(player, entityId, eventCode, buffer);
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class StateEntityHandler: Handler
{
private readonly RagonEntityCache _entityCache;
public StateEntityHandler(RagonEntityCache entityCache)
{
_entityCache = entityCache;
}
public void Handle(RagonBuffer buffer)
{
var entitiesCount = buffer.ReadUShort();
for (var i = 0; i < entitiesCount; i++)
{
var entityId = buffer.ReadUShort();
_entityCache.OnState(entityId, buffer);
}
}
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
public interface Handler
{
public void Handle(RagonBuffer buffer);
}
@@ -0,0 +1,36 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class JoinFailedHandler: Handler
{
private readonly RagonListenerList _listenerList;
public JoinFailedHandler(RagonListenerList listenerList)
{
_listenerList = listenerList;
}
public void Handle(RagonBuffer buffer)
{
var message = buffer.ReadString();
_listenerList.OnFailed(message);
}
}
@@ -0,0 +1,80 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
public struct RagonRoomInformation
{
public RagonRoomInformation(string roomId, string playerId, string ownerId, ushort min, ushort max)
{
RoomId = roomId;
PlayerId = playerId;
OwnerId = ownerId;
Min = min;
Max = max;
}
public string RoomId { get; private set; }
public string PlayerId { get; private set; }
public string OwnerId { get; private set; }
public ushort Min { get; private set; }
public ushort Max { get; private set; }
}
internal class JoinSuccessHandler : Handler
{
private readonly RagonListenerList _listenerList;
private readonly RagonPlayerCache _playerCache;
private readonly RagonEntityCache _entityCache;
private readonly RagonClient _client;
private readonly RagonBuffer _buffer;
public JoinSuccessHandler(
RagonClient client,
RagonBuffer buffer,
RagonListenerList listenerList,
RagonPlayerCache playerCache,
RagonEntityCache entityCache
)
{
_buffer = buffer;
_client = client;
_listenerList = listenerList;
_entityCache = entityCache;
_playerCache = playerCache;
}
public void Handle(RagonBuffer buffer)
{
var roomId = buffer.ReadString();
var localId = buffer.ReadString();
var ownerId = buffer.ReadString();
var min = buffer.ReadUShort();
var max = buffer.ReadUShort();
var map = buffer.ReadString();
var scene = new RagonScene(_client, _playerCache, _entityCache);
var roomInfo = new RagonRoomInformation(roomId, localId, ownerId, min, max);
var room = new RagonRoom(_client, _entityCache, _playerCache, roomInfo, scene);
_playerCache.SetOwnerAndLocal(ownerId, localId);
_client.AssignRoom(room);
_listenerList.OnLevel(map);
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class LeaveRoomHandler : Handler
{
private readonly RagonClient _client;
private readonly RagonListenerList _listenerList;
private readonly RagonEntityCache _entityCache;
public LeaveRoomHandler(
RagonClient client,
RagonListenerList listenerList,
RagonEntityCache entityCache)
{
_client = client;
_listenerList = listenerList;
_entityCache = entityCache;
}
public void Handle(RagonBuffer buffer)
{
_listenerList.OnLeft();
_entityCache.Cleanup();
_client.Room.Cleanup();
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class SceneLoadHandler: Handler
{
private readonly RagonClient _client;
private readonly RagonListenerList _listenerList;
public SceneLoadHandler(
RagonClient ragonClient,
RagonListenerList listenerList
)
{
_client = ragonClient;
_listenerList = listenerList;
}
public void Handle(RagonBuffer buffer)
{
var sceneName = buffer.ReadString();
var room = _client.Room;
room.Cleanup();
_listenerList.OnLevel(sceneName);
}
}
@@ -0,0 +1,53 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class OwnershipHandler: Handler
{
private readonly RagonListenerList _listenerList;
private readonly RagonPlayerCache _playerCache;
private readonly RagonEntityCache _entityCache;
public OwnershipHandler(
RagonListenerList listenerList,
RagonPlayerCache playerCache,
RagonEntityCache entityCache)
{
_listenerList = listenerList;
_playerCache = playerCache;
_entityCache = entityCache;
}
public void Handle(RagonBuffer buffer)
{
var newOwnerId = buffer.ReadString();
var player = _playerCache.GetPlayerById(newOwnerId);
_playerCache.OnOwnershipChanged(newOwnerId);
_listenerList.OnOwnershipChanged(player);
var entities = buffer.ReadUShort();
for (var i = 0; i < entities; i++)
{
var entityId = buffer.ReadUShort();
_entityCache.OnOwnershipChanged(player, entityId);
}
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class PlayerJoinHandler : Handler
{
private RagonPlayerCache _playerCache;
private RagonListenerList _listenerList;
public PlayerJoinHandler(
RagonPlayerCache playerCache,
RagonListenerList listenerList
)
{
_playerCache = playerCache;
_listenerList = listenerList;
}
public void Handle(RagonBuffer buffer)
{
var playerPeerId = buffer.ReadUShort();
var playerId = buffer.ReadString();
var playerName = buffer.ReadString();
_playerCache.AddPlayer(playerPeerId, playerId, playerName);
var player = _playerCache.GetPlayerById(playerId);
if (player != null)
_listenerList.OnPlayerJoined(player);
else
RagonLog.Trace($"[Joined] {playerId}");
}
}
@@ -0,0 +1,60 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class PlayerLeftHandler : Handler
{
private RagonPlayerCache _playerCache;
private RagonEntityCache _entityCache;
private RagonListenerList _listenerList;
public PlayerLeftHandler(
RagonEntityCache entityCache,
RagonPlayerCache playerCache,
RagonListenerList listenerList
)
{
_entityCache = entityCache;
_playerCache = playerCache;
_listenerList = listenerList;
}
public void Handle(RagonBuffer buffer)
{
var playerId = buffer.ReadString();
var player = _playerCache.GetPlayerById(playerId);
if (player != null)
{
_playerCache.RemovePlayer(playerId);
_listenerList.OnPlayerLeft(player);
var entities = buffer.ReadUShort();
var toDeleteIds = new ushort[entities];
for (var i = 0; i < entities; i++)
{
var entityId = buffer.ReadUShort();
toDeleteIds[i] = entityId;
}
foreach (var id in toDeleteIds)
_entityCache.OnDestroy(id, new RagonPayload());
}
}
}
@@ -0,0 +1,97 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol;
namespace Ragon.Client;
internal class SnapshotHandler : Handler
{
private RagonClient _client;
private RagonListenerList _listenerList;
private RagonEntityCache _entityCache;
private RagonPlayerCache _playerCache;
public SnapshotHandler(
RagonClient ragonClient,
RagonListenerList listenerList,
RagonEntityCache entityCache,
RagonPlayerCache playerCache
)
{
_client = ragonClient;
_listenerList = listenerList;
_entityCache = entityCache;
_playerCache = playerCache;
}
public void Handle(RagonBuffer buffer)
{
var playersCount = buffer.ReadUShort();
RagonLog.Trace("Players: " + playersCount);
for (var i = 0; i < playersCount; i++)
{
var playerPeerId = buffer.ReadUShort();
var playerId = buffer.ReadString();
var playerName = buffer.ReadString();
_playerCache.AddPlayer(playerPeerId, playerId, playerName);
}
var dynamicEntities = buffer.ReadUShort();
RagonLog.Trace("Dynamic Entities: " + dynamicEntities);
for (var i = 0; i < dynamicEntities; i++)
{
var entityType = buffer.ReadUShort();
var entityId = buffer.ReadUShort();
var ownerPeerId = buffer.ReadUShort();
var payloadSize = buffer.ReadUShort();
var player = _playerCache.GetPlayerByPeer(ownerPeerId);
var payload = new RagonPayload(payloadSize);
payload.Read(buffer);
var hasAuthority = _playerCache.LocalPlayer.Id == player.Id;
var entity = _entityCache.OnCreate(0, entityType, 0, entityId, hasAuthority);
entity.Read(buffer);
entity.Attach(_client, entityId, entityType, hasAuthority, player, payload);
}
var staticEntities = buffer.ReadUShort();
RagonLog.Trace("Scene Entities: " + staticEntities);
for (var i = 0; i < staticEntities; i++)
{
var entityType = buffer.ReadUShort();
var entityId = buffer.ReadUShort();
var staticId = buffer.ReadUShort();
var ownerPeerId = buffer.ReadUShort();
var payloadSize = buffer.ReadUShort();
var player = _playerCache.GetPlayerByPeer(ownerPeerId);
var payload = new RagonPayload(payloadSize);
payload.Read(buffer);
var hasAuthority = _playerCache.LocalPlayer.Id == player.Id;
var entity = _entityCache.OnCreate(0, entityType, staticId, entityId, hasAuthority);
entity.Read(buffer);
entity.Attach(_client, entityId, entityType, hasAuthority, player, payload);
}
_listenerList.OnJoined();
}
}