| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using MineCase.Protocol.Play;
- using MineCase.Server.Network.Play;
- using MineCase.Server.User;
- using MineCase.Server.World;
- using Orleans;
- namespace MineCase.Server.Game
- {
- internal class GameSession : Grain, IGameSession
- {
- private IWorld _world;
- private IChunkSender _chunkSender;
- private readonly Dictionary<IUser, UserContext> _users = new Dictionary<IUser, UserContext>();
- private IDisposable _gameTick;
- private DateTime _lastGameTickTime;
- private HashSet<ITickable> _tickables;
- public override async Task OnActivateAsync()
- {
- _world = await GrainFactory.GetGrain<IWorldAccessor>(0).GetWorld(this.GetPrimaryKeyString());
- _chunkSender = GrainFactory.GetGrain<IChunkSender>(this.GetPrimaryKeyString());
- _lastGameTickTime = DateTime.UtcNow;
- _tickables = new HashSet<ITickable>();
- _gameTick = RegisterTimer(OnGameTick, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(50));
- }
- public async Task JoinGame(IUser user)
- {
- var sink = await user.GetClientPacketSink();
- var generator = new ClientPlayPacketGenerator(sink);
- _users[user] = new UserContext
- {
- Generator = generator
- };
- await user.JoinGame();
- await generator.JoinGame(
- (await user.GetPlayer()).GetEntityId(),
- new GameMode { ModeClass = GameMode.Class.Survival },
- Dimension.Overworld,
- Difficulty.Easy,
- 10,
- LevelTypes.Default,
- false);
- await user.NotifyLoggedIn();
- }
- public Task LeaveGame(IUser player)
- {
- _users.Remove(player);
- return Task.CompletedTask;
- }
- public async Task SendChatMessage(IUser sender, string message)
- {
- var senderName = await sender.GetName();
- // TODO command parser
- // construct name
- Chat jsonData = await CreateStandardChatMessage(senderName, message);
- byte position = 0; // It represents user message in chat box
- foreach (var item in _users.Keys)
- {
- await item.SendChatMessage(jsonData, position);
- }
- }
- public async Task SendChatMessage(IUser sender, IUser receiver, string message)
- {
- var senderName = await sender.GetName();
- var receiverName = await receiver.GetName();
- Chat jsonData = await CreateStandardChatMessage(senderName, message);
- byte position = 0; // It represents user message in chat box
- foreach (var item in _users.Keys)
- {
- if (await item.GetName() == receiverName ||
- await item.GetName() == senderName)
- await item.SendChatMessage(jsonData, position);
- }
- }
- private async Task OnGameTick(object state)
- {
- var now = DateTime.UtcNow;
- var deltaTime = now - _lastGameTickTime;
- _lastGameTickTime = now;
- var worldAge = await _world.GetAge();
- await _world.OnGameTick(deltaTime);
- await Task.WhenAll(from u in _users.Keys
- select u.OnGameTick(deltaTime));
- await Task.WhenAll(from u in _tickables
- select u.OnGameTick(deltaTime, worldAge));
- }
- private Task<Chat> CreateStandardChatMessage(string name, string message)
- {
- StringComponent nameComponent = new StringComponent(name);
- nameComponent.ClickEvent = new ChatClickEvent(ClickEventType.SuggestCommand, "/msg " + name);
- nameComponent.HoverEvent = new ChatHoverEvent(HoverEventType.ShowEntity, name);
- nameComponent.Insertion = name;
- // construct message
- StringComponent messageComponent = new StringComponent(message);
- // list
- List<ChatComponent> list = new List<ChatComponent>();
- list.Add(nameComponent);
- list.Add(messageComponent);
- Chat jsonData = new Chat(new TranslationComponent("chat.type.text", list));
- return Task.FromResult(jsonData);
- }
- public Task Subscribe(ITickable tickable)
- {
- _tickables.Add(tickable);
- return Task.CompletedTask;
- }
- public Task Unsubscribe(ITickable tickable)
- {
- _tickables.Remove(tickable);
- return Task.CompletedTask;
- }
- private class UserContext
- {
- public ClientPlayPacketGenerator Generator { get; set; }
- }
- }
- }
|