Files
Ragon/Ragon.Server/Sources/Entity/RagonEntity.cs
T

242 lines
6.1 KiB
C#
Raw Normal View History

2023-03-06 10:06:43 +04:00
/*
* 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;
2023-04-09 10:52:18 +04:00
using Ragon.Server.Room;
2023-03-06 10:06:43 +04:00
2023-04-09 10:52:18 +04:00
namespace Ragon.Server.Entity;
2023-03-06 10:06:43 +04:00
2023-07-01 07:47:57 +03:00
public class RagonEntity : IRagonEntity
2023-03-06 10:06:43 +04:00
{
private static ushort _idGenerator = 100;
public ushort Id { get; private set; }
public ushort Type { get; private set; }
public ushort StaticId { get; private set; }
public ushort AttachId { get; private set; }
public RagonRoomPlayer Owner { get; private set; }
public RagonAuthority Authority { get; private set; }
public RagonPayload Payload { get; private set; }
2023-04-14 14:32:04 +04:00
public IRagonEntityState State => _state;
2023-07-01 07:47:57 +03:00
2023-03-06 10:06:43 +04:00
private readonly List<RagonEvent> _bufferedEvents;
2023-07-01 07:47:57 +03:00
private readonly int _limitBufferedEvents;
2023-04-14 14:32:04 +04:00
private readonly RagonEntityState _state;
2023-07-01 07:47:57 +03:00
2023-04-09 10:52:18 +04:00
public RagonEntity(RagonEntityParameters parameters)
2023-03-06 10:06:43 +04:00
{
Id = _idGenerator++;
2023-07-01 07:47:57 +03:00
2023-04-09 10:52:18 +04:00
StaticId = parameters.StaticId;
Type = parameters.Type;
AttachId = parameters.AttachId;
Authority = parameters.Authority;
2023-03-06 10:06:43 +04:00
Payload = new RagonPayload();
2023-07-01 07:47:57 +03:00
2023-04-14 14:32:04 +04:00
_state = new RagonEntityState(this);
2023-03-06 10:06:43 +04:00
_bufferedEvents = new List<RagonEvent>();
2023-07-01 07:47:57 +03:00
_limitBufferedEvents = parameters.BufferedEvents;
2023-03-06 10:06:43 +04:00
}
2023-07-01 07:47:57 +03:00
2023-04-09 10:52:18 +04:00
public void Attach(RagonRoomPlayer owner)
2023-03-06 10:06:43 +04:00
{
Owner = owner;
}
2023-04-09 10:52:18 +04:00
public void Detach()
{
2023-07-01 07:47:57 +03:00
}
2023-04-09 10:52:18 +04:00
2023-03-06 10:06:43 +04:00
public void RestoreBufferedEvents(RagonRoomPlayer roomPlayer, RagonBuffer writer)
{
foreach (var evnt in _bufferedEvents)
{
writer.Clear();
writer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT);
writer.WriteUShort(evnt.EventCode);
writer.WriteUShort(evnt.Invoker.Connection.Id);
writer.WriteByte((byte)RagonReplicationMode.Server);
writer.WriteUShort(Id);
evnt.Write(writer);
var sendData = writer.ToArray();
roomPlayer.Connection.Reliable.Send(sendData);
}
}
public void Create()
{
var room = Owner.Room;
var buffer = room.Writer;
buffer.Clear();
buffer.WriteOperation(RagonOperation.CREATE_ENTITY);
buffer.WriteUShort(AttachId);
buffer.WriteUShort(Type);
buffer.WriteUShort(Id);
buffer.WriteUShort(Owner.Connection.Id);
2023-07-01 07:47:57 +03:00
2023-03-06 10:06:43 +04:00
Payload.Write(buffer);
var sendData = buffer.ToArray();
foreach (var player in room.ReadyPlayersList)
player.Connection.Reliable.Send(sendData);
}
public void Destroy()
{
var room = Owner.Room;
var buffer = room.Writer;
buffer.Clear();
2023-04-09 10:52:18 +04:00
buffer.WriteOperation(RagonOperation.REMOVE_ENTITY);
2023-03-06 10:06:43 +04:00
buffer.WriteUShort(Id);
Payload.Write(buffer);
var sendData = buffer.ToArray();
foreach (var player in room.ReadyPlayersList)
player.Connection.Reliable.Send(sendData);
}
public void Snapshot(RagonBuffer buffer)
{
buffer.WriteUShort(Type);
buffer.WriteUShort(Id);
if (StaticId != 0)
buffer.WriteUShort(StaticId);
buffer.WriteUShort(Owner.Connection.Id);
buffer.WriteUShort(Payload.Size);
Payload.Write(buffer);
2023-07-01 07:47:57 +03:00
2023-04-14 14:32:04 +04:00
_state.Snapshot(buffer);
2023-03-06 10:06:43 +04:00
}
public void ReplicateEvent(
RagonRoomPlayer caller,
RagonEvent evnt,
RagonReplicationMode eventMode,
RagonRoomPlayer targetPlayer
)
{
var room = Owner.Room;
var buffer = room.Writer;
buffer.Clear();
buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT);
buffer.WriteUShort(evnt.EventCode);
buffer.WriteUShort(caller.Connection.Id);
buffer.WriteByte((byte)eventMode);
buffer.WriteUShort(Id);
evnt.Write(buffer);
var sendData = buffer.ToArray();
targetPlayer.Connection.Reliable.Send(sendData);
}
public void ReplicateEvent(
RagonRoomPlayer caller,
RagonEvent evnt,
RagonReplicationMode eventMode,
RagonTarget targetMode
)
{
if (Authority == RagonAuthority.OwnerOnly &&
Owner.Connection.Id != caller.Connection.Id)
{
Console.WriteLine($"Player have not enough authority for event with Id {evnt.EventCode}");
return;
}
2023-07-01 07:47:57 +03:00
if (eventMode == RagonReplicationMode.Buffered &&
targetMode != RagonTarget.Owner &&
_bufferedEvents.Count < _limitBufferedEvents)
2023-03-06 10:06:43 +04:00
{
_bufferedEvents.Add(evnt);
}
var room = Owner.Room;
var buffer = room.Writer;
buffer.Clear();
buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT);
buffer.WriteUShort(evnt.EventCode);
buffer.WriteUShort(caller.Connection.Id);
buffer.WriteByte((byte)eventMode);
buffer.WriteUShort(Id);
evnt.Write(buffer);
var sendData = buffer.ToArray();
switch (targetMode)
{
case RagonTarget.Owner:
{
Owner.Connection.Reliable.Send(sendData);
break;
}
case RagonTarget.ExceptOwner:
{
foreach (var roomPlayer in room.ReadyPlayersList)
{
if (roomPlayer.Connection.Id != Owner.Connection.Id)
roomPlayer.Connection.Reliable.Send(sendData);
}
break;
}
case RagonTarget.ExceptInvoker:
{
foreach (var roomPlayer in room.ReadyPlayersList)
{
if (roomPlayer.Connection.Id != caller.Connection.Id)
roomPlayer.Connection.Reliable.Send(sendData);
}
break;
}
case RagonTarget.All:
{
foreach (var roomPlayer in room.ReadyPlayersList)
roomPlayer.Connection.Reliable.Send(sendData);
break;
}
}
}
2023-04-09 10:52:18 +04:00
2023-04-14 14:32:04 +04:00
public void AddProperty(RagonProperty property)
{
_state.AddProperty(property);
}
2023-07-01 07:47:57 +03:00
2023-04-14 14:32:04 +04:00
public void WriteState(RagonBuffer writer)
2023-04-09 10:52:18 +04:00
{
2023-04-14 14:32:04 +04:00
_state.Write(writer);
2023-04-09 10:52:18 +04:00
}
2023-04-14 14:32:04 +04:00
public bool TryReadState(RagonRoomPlayer player, RagonBuffer reader)
2023-04-09 10:52:18 +04:00
{
if (Owner.Connection.Id != player.Connection.Id)
2023-04-14 14:32:04 +04:00
return false;
2023-07-01 07:47:57 +03:00
2023-04-14 14:32:04 +04:00
_state.Read(reader);
2023-07-01 07:47:57 +03:00
2023-04-14 14:32:04 +04:00
return true;
2023-04-09 10:52:18 +04:00
}
2023-03-06 10:06:43 +04:00
}