public void DestroyCactus(BlockDescriptor descriptor, IMultiplayerServer server, IWorld world) { var toDrop = 0; // Search upwards for (int y = descriptor.Coordinates.Y; y < 127; y++) { var coordinates = new Coordinates3D(descriptor.Coordinates.X, y, descriptor.Coordinates.Z); if (world.GetBlockID(coordinates) == CactusBlock.BlockID) { world.SetBlockID(coordinates, AirBlock.BlockID); toDrop++; } } // Search downwards. for (int y = descriptor.Coordinates.Y - 1; y > 0; y--) { var coordinates = new Coordinates3D(descriptor.Coordinates.X, y, descriptor.Coordinates.Z); if (world.GetBlockID(coordinates) == CactusBlock.BlockID) { world.SetBlockID(coordinates, AirBlock.BlockID); toDrop++; } } var manager = server.GetEntityManagerForWorld(world); manager.SpawnEntity( new ItemEntity(descriptor.Coordinates + Coordinates3D.Up, new ItemStack(CactusBlock.BlockID, (sbyte)toDrop))); }
public void DoSpread(IMultiplayerServer server, IWorld world, BlockDescriptor descriptor) { foreach (var coord in SpreadableBlocks) { var check = descriptor.Coordinates + coord; if (world.GetBlockID(check) == AirBlock.BlockID) { // Check if this is adjacent to a flammable block foreach (var adj in AdjacentBlocks) { var provider = BlockRepository.GetBlockProvider( world.GetBlockID(check + adj)); if (provider.Flammable) { if (provider.Hardness == 0) { check = check + adj; } // Spread to this block world.SetBlockID(check, FireBlock.BlockID); ScheduleUpdate(server, world, world.GetBlockData(check)); break; } } } } }
public void DoSpread(IMultiplayerServer server, IWorld world, BlockDescriptor descriptor) { foreach (var coord in SpreadableBlocks) { var check = descriptor.Coordinates + coord; if (world.GetBlockID(check) == AirBlock.BlockID) { // Check if this is adjacent to a flammable block foreach (var adj in AdjacentBlocks) { var provider = BlockRepository.GetBlockProvider( world.GetBlockID(check + adj)); if (provider.Flammable) { if (provider.Hardness == 0) check = check + adj; // Spread to this block world.SetBlockID(check, FireBlock.BlockID); ScheduleUpdate(server, world, world.GetBlockData(check)); break; } } } } }
public void GenerateDropEntity(BlockDescriptor descriptor, IWorld world, IMultiplayerServer server, ItemStack item) { var entityManager = server.GetEntityManagerForWorld(world); var items = new ItemStack[0]; var type = ToolType.None; var material = ToolMaterial.None; var held = ItemRepository.GetItemProvider(item.ID); if (held is ToolItem) { var tool = held as ToolItem; material = tool.Material; type = tool.ToolType; } if ((EffectiveTools & type) > 0) { if ((EffectiveToolMaterials & material) > 0) { items = GetDrop(descriptor, item); } } foreach (var i in items) { if (i.Empty) { continue; } var entity = new ItemEntity(new Vector3(descriptor.Coordinates) + new Vector3(0.5), i); entityManager.SpawnEntity(entity); } }
private void TryGrowth(IMultiplayerServer server, Coordinates3D coords, IWorld world) { if (world.GetBlockID(coords) != BlockID) return; // Find current height of stalk int height = 0; for (int y = -MaxGrowHeight; y <= MaxGrowHeight; y++) { if (world.GetBlockID(coords + (Coordinates3D.Down * y)) == BlockID) height++; } if (height < MaxGrowHeight) { var meta = world.GetMetadata(coords); meta++; world.SetMetadata(coords, meta); var chunk = world.FindChunk(coords); if (meta == 15) { if (world.GetBlockID(coords + Coordinates3D.Up) == 0) { world.SetBlockID(coords + Coordinates3D.Up, BlockID); server.Scheduler.ScheduleEvent("cactus", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), (_server) => TryGrowth(_server, coords + Coordinates3D.Up, world)); } } else { server.Scheduler.ScheduleEvent("cactus", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), (_server) => TryGrowth(_server, coords, world)); } } }
public override void BlockLoadedFromChunk(Coordinates3D coords, IMultiplayerServer server, IWorld world) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("crops", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(30, 60)), (s) => GrowBlock(s, world, coords)); }
void HydrationCheckEvent(IMultiplayerServer server, Coordinates3D coords, IWorld world) { if (world.GetBlockID(coords) != BlockID) return; if (MathHelper.Random.Next(3) == 0) { var meta = world.GetMetadata(coords); if (IsHydrated(coords, world) && meta != 15) meta++; else { meta--; if (meta == 0) { world.SetBlockID(coords, BlockID); return; } } world.SetMetadata(coords, meta); } var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("farmland", chunk, TimeSpan.FromSeconds(UpdateIntervalSeconds), _server => HydrationCheckEvent(_server, coords, world)); }
void HydrationCheckEvent(IMultiplayerServer server, Coordinates3D coords, IWorld world) { if (world.GetBlockID(coords) != BlockID) { return; } if (MathHelper.Random.Next(3) == 0) { var meta = world.GetMetadata(coords); if (IsHydrated(coords, world) && meta != 15) { meta++; } else { meta--; if (meta == 0) { world.SetBlockID(coords, BlockID); return; } } world.SetMetadata(coords, meta); } var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("farmland", chunk, TimeSpan.FromSeconds(UpdateIntervalSeconds), _server => HydrationCheckEvent(_server, coords, world)); }
public static void HandleLoginRequestPacket(IPacket packet, IRemoteClient client, IMultiplayerServer server) { var loginRequestPacket = (LoginRequestPacket)packet; var remoteClient = (RemoteClient)client; if (loginRequestPacket.ProtocolVersion < server.PacketReader.ProtocolVersion) remoteClient.QueuePacket(new DisconnectPacket("Client outdated! Use beta 1.7.3.")); else if (loginRequestPacket.ProtocolVersion > server.PacketReader.ProtocolVersion) remoteClient.QueuePacket(new DisconnectPacket("Server outdated! Use beta 1.7.3.")); else if (server.Worlds.Count == 0) remoteClient.QueuePacket(new DisconnectPacket("Server has no worlds configured.")); else if (!server.PlayerIsWhitelisted(remoteClient.Username) && server.PlayerIsBlacklisted(remoteClient.Username)) remoteClient.QueuePacket(new DisconnectPacket("You're banned from this server")); else if (server.Clients.Count(c => c.Username == client.Username) > 1) remoteClient.QueuePacket(new DisconnectPacket("The player with this username is already logged in")); else { remoteClient.LoggedIn = true; remoteClient.Entity = new PlayerEntity(remoteClient.Username); remoteClient.World = server.Worlds[0]; remoteClient.ChunkRadius = 2; if (!remoteClient.Load()) remoteClient.Entity.Position = remoteClient.World.SpawnPoint; // Make sure they don't spawn in the ground var collision = new Func<bool>(() => { var feet = client.World.GetBlockID((Coordinates3D)client.Entity.Position); var head = client.World.GetBlockID((Coordinates3D)(client.Entity.Position + Vector3.Up)); var feetBox = server.BlockRepository.GetBlockProvider(feet).BoundingBox; var headBox = server.BlockRepository.GetBlockProvider(head).BoundingBox; return feetBox != null || headBox != null; }); while (collision()) client.Entity.Position += Vector3.Up; // Send setup packets remoteClient.QueuePacket(new LoginResponsePacket(0, 0, Dimension.Overworld)); remoteClient.UpdateChunks(); remoteClient.QueuePacket(new WindowItemsPacket(0, remoteClient.Inventory.GetSlots())); remoteClient.QueuePacket(new SpawnPositionPacket((int)remoteClient.Entity.Position.X, (int)remoteClient.Entity.Position.Y, (int)remoteClient.Entity.Position.Z)); remoteClient.QueuePacket(new SetPlayerPositionPacket(remoteClient.Entity.Position.X, remoteClient.Entity.Position.Y + 1, remoteClient.Entity.Position.Y + remoteClient.Entity.Size.Height + 1, remoteClient.Entity.Position.Z, remoteClient.Entity.Yaw, remoteClient.Entity.Pitch, true)); remoteClient.QueuePacket(new TimeUpdatePacket(remoteClient.World.Time)); // Start housekeeping for this client var entityManager = server.GetEntityManagerForWorld(remoteClient.World); entityManager.SpawnEntity(remoteClient.Entity); entityManager.SendEntitiesToClient(remoteClient); server.Scheduler.ScheduleEvent("remote.keepalive", remoteClient, TimeSpan.FromSeconds(10), remoteClient.SendKeepAlive); server.Scheduler.ScheduleEvent("remote.chunks", remoteClient, TimeSpan.FromSeconds(1), remoteClient.ExpandChunkRadius); if (!string.IsNullOrEmpty(Program.ServerConfiguration.MOTD)) remoteClient.SendMessage(Program.ServerConfiguration.MOTD); if (!Program.ServerConfiguration.Singleplayer) server.SendMessage(ChatColor.Yellow + "{0} joined the server.", remoteClient.Username); } }
public void GenerateDropEntity(BlockDescriptor descriptor, IWorld world, IMultiplayerServer server, ItemStack item) { var entityManager = server.GetEntityManagerForWorld(world); var items = new ItemStack[0]; var type = ToolType.None; var material = ToolMaterial.None; var held = ItemRepository.GetItemProvider(item.ID); if (held is ToolItem) { var tool = held as ToolItem; material = tool.Material; type = tool.ToolType; } if ((EffectiveTools & type) > 0) { if ((EffectiveToolMaterials & material) > 0) items = GetDrop(descriptor, item); } foreach (var i in items) { if (i.Empty) continue; var entity = new ItemEntity(new Vector3(descriptor.Coordinates) + new Vector3(0.5), i); entityManager.SpawnEntity(entity); } }
public override void BlockLoadedFromChunk(Coordinates3D coords, IMultiplayerServer server, IWorld world) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent(chunk, DateTime.UtcNow.AddSeconds(MathHelper.Random.Next(30, 60)), (s) => GrowBlock(s, world, coords)); }
public override void BlockLoadedFromChunk(Coordinates3D coords, IMultiplayerServer server, IWorld world) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("cactus", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), s => TryGrowth(s, coords, world)); }
public override void BlockLoadedFromChunk(Coordinates3D coords, IMultiplayerServer server, IWorld world) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent(chunk, DateTime.UtcNow.AddSeconds(MathHelper.Random.Next(MinGrowthTime, MaxGrowthTime)), s => TrySpread(coords, world, server)); }
public override void BlockLoadedFromChunk(Coordinates3D coords, IMultiplayerServer server, IWorld world) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("farmland", chunk, TimeSpan.FromSeconds(UpdateIntervalSeconds), s => HydrationCheckEvent(s, coords, world)); }
void HydrationCheckEvent(IMultiplayerServer server, Coordinates3D coords, IWorld world) { if (world.GetBlockID(coords) != BlockID) { return; } if (MathHelper.Random.Next(3) == 0) { var meta = world.GetMetadata(coords); if (IsHydrated(coords, world) && meta != 15) { meta++; } else { meta--; if (meta == 0) { world.SetBlockID(coords, BlockID); return; } } world.SetMetadata(coords, meta); } server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(UpdateIntervalSeconds), (_server) => HydrationCheckEvent(_server, coords, world)); }
public static void HandleHandshakePacket(IPacket packet, IRemoteClient client, IMultiplayerServer server) { var handshakePacket = (HandshakePacket) packet; var remoteClient = (RemoteClient)client; remoteClient.Username = handshakePacket.Username; remoteClient.QueuePacket(new HandshakeResponsePacket("-")); // TODO: Implement some form of authentication }
public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world) { bool upper = ((DoorItem.DoorFlags)descriptor.Metadata & DoorItem.DoorFlags.Upper) == DoorItem.DoorFlags.Upper; var other = upper ? Coordinates3D.Down : Coordinates3D.Up; if (world.GetBlockID(descriptor.Coordinates + other) != ID) world.SetBlockID(descriptor.Coordinates, 0); }
private void TryGrowth(IMultiplayerServer server, Coordinates3D coords, IWorld world) { if (world.GetBlockID(coords) != BlockID) { return; } // Find current height of stalk int height = 0; for (int y = -3; y <= 3; y++) { if (world.GetBlockID(coords + (Coordinates3D.Down * y)) == BlockID) { height++; } } if (height < 3) { var meta = world.GetMetadata(coords); meta++; world.SetMetadata(coords, meta); if (meta == 15) { world.SetBlockID(coords + Coordinates3D.Up, BlockID); server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), (_server) => TryGrowth(_server, coords + Coordinates3D.Up, world)); } else { server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), (_server) => TryGrowth(_server, coords, world)); } } }
public void ScheduleUpdate(IMultiplayerServer server, IWorld world, BlockDescriptor descriptor) { var chunk = world.FindChunk(descriptor.Coordinates); server.Scheduler.ScheduleEvent("fire.spread", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinSpreadTime, MaxSpreadTime)), s => DoUpdate(s, world, descriptor)); }
public override void BlockLoadedFromChunk(Coordinates3D coords, IMultiplayerServer server, IWorld world) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("grass", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinGrowthTime, MaxGrowthTime)), s => TrySpread(coords, world, server)); }
public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world) { if (world.GetBlockID(descriptor.Coordinates + Coordinates3D.Down) != FarmlandBlock.BlockID) { GenerateDropEntity(descriptor, world, server); world.SetBlockID(descriptor.Coordinates, 0); } }
public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world) { if (world.GetBlockID(descriptor.Coordinates + Coordinates3D.Down) == AirBlock.BlockID) { world.SetBlockID(descriptor.Coordinates, AirBlock.BlockID); server.GetEntityManagerForWorld(world).SpawnEntity(new FallingGravelEntity(descriptor.Coordinates)); } }
public EventScheduler(IMultiplayerServer server) { Events = new List <ScheduledEvent>(); Server = server; Subjects = new HashSet <IEventSubject>(); Stopwatch = new Stopwatch(); Stopwatch.Start(); }
public void ScheduleNextEvent(Coordinates3D coords, IWorld world, IMultiplayerServer server) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent(chunk, DateTime.UtcNow.AddSeconds(SecondsBetweenUpdates), (_server) => AutomataUpdate(_server, world, coords)); }
public EventScheduler(IMultiplayerServer server) { Events = new List<ScheduledEvent>(); Server = server; Subjects = new HashSet<IEventSubject>(); Stopwatch = new Stopwatch(); Stopwatch.Start(); }
public void ScheduleNextEvent(Coordinates3D coords, IWorld world, IMultiplayerServer server) { if (world.GetBlockID(coords) == StillID) return; var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("fluid", chunk, TimeSpan.FromSeconds(SecondsBetweenUpdates), (_server) => AutomataUpdate(_server, world, coords)); }
internal static void HandleChatMessage(IPacket _packet, IRemoteClient _client, IMultiplayerServer _server) { // TODO: Abstract this to support things like commands // TODO: Sanitize messages var packet = (ChatMessagePacket)_packet; var server = (MultiplayerServer)_server; var args = new ChatMessageEventArgs(_client, packet.Message); server.OnChatMessageReceived(args); }
public static void HandleChangeHeldItem(IPacket _packet, IRemoteClient _client, IMultiplayerServer server) { var packet = (ChangeHeldItemPacket)_packet; var client = (RemoteClient)_client; client.SelectedSlot = (short)(packet.Slot + InventoryWindow.HotbarIndex); var notified = server.GetEntityManagerForWorld(client.World).ClientsForEntity(client.Entity); foreach (var c in notified) c.QueuePacket(new EntityEquipmentPacket(client.Entity.EntityID, 0, client.SelectedItem.ID, client.SelectedItem.Metadata)); }
public virtual bool IsSupported(BlockDescriptor descriptor, IMultiplayerServer server, IWorld world) { var support = GetSupportDirection(descriptor); if (support != Coordinates3D.Zero) { var supportingBlock = server.BlockRepository.GetBlockProvider(world.GetBlockID(descriptor.Coordinates + support)); if (!supportingBlock.Opaque) return false; } return true; }
public EntityManager(IMultiplayerServer server, IWorld world) { Server = server; World = world; PhysicsEngine = new PhysicsEngine(world, (BlockRepository)server.BlockRepository); PendingDespawns = new ConcurrentBag<IEntity>(); Entities = new List<IEntity>(); // TODO: Handle loading worlds that already have entities // Note: probably not the concern of EntityManager. The server could manually set this? NextEntityID = 1; }
public EntityManager(IMultiplayerServer server, IWorld world) { Server = server; World = world; PhysicsEngine = new PhysicsEngine(world, (BlockRepository)server.BlockRepository); PendingDespawns = new ConcurrentBag <IEntity>(); Entities = new List <IEntity>(); // TODO: Handle loading worlds that already have entities // Note: probably not the concern of EntityManager. The server could manually set this? NextEntityID = 1; }
static void SaveWorlds(IMultiplayerServer server) { Server.Log(LogCategory.Notice, "Saving world..."); foreach (var w in Server.Worlds) { w.Save(); } Server.Log(LogCategory.Notice, "Done."); server.Scheduler.ScheduleEvent("world.save", null, TimeSpan.FromSeconds(ServerConfiguration.WorldSaveInterval), SaveWorlds); }
public void TrySpread(Coordinates3D coords, IWorld world, IMultiplayerServer server) { if (!world.IsValidPosition(coords + Coordinates3D.Up)) { return; } var sky = world.GetSkyLight(coords + Coordinates3D.Up); var block = world.GetBlockLight(coords + Coordinates3D.Up); if (sky < 9 && block < 9) { return; } for (int i = 0, j = MathHelper.Random.Next(GrowthCandidates.Length); i < GrowthCandidates.Length; i++, j++) { var candidate = GrowthCandidates[j % GrowthCandidates.Length] + coords; if (!world.IsValidPosition(candidate) || !world.IsValidPosition(candidate + Coordinates3D.Up)) { continue; } var id = world.GetBlockID(candidate); if (id == DirtBlock.BlockID) { var _sky = world.GetSkyLight(candidate + Coordinates3D.Up); var _block = world.GetBlockLight(candidate + Coordinates3D.Up); if (_sky < 4 && _block < 4) { continue; } IChunk chunk; var _candidate = world.FindBlockPosition(candidate, out chunk); bool grow = true; for (int y = candidate.Y; y < chunk.GetHeight((byte)_candidate.X, (byte)_candidate.Z); y++) { var b = world.GetBlockID(new Coordinates3D(candidate.X, y, candidate.Z)); var p = world.BlockRepository.GetBlockProvider(b); if (p.LightOpacity >= 2) { grow = false; break; } } if (grow) { world.SetBlockID(candidate, GrassBlock.BlockID); server.Scheduler.ScheduleEvent("grass", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinGrowthTime, MaxGrowthTime)), s => TrySpread(candidate, world, server)); } break; } } }
public EventScheduler(IMultiplayerServer server) { Events = new List <ScheduledEvent>(); ImmediateEventQueue = new ConcurrentQueue <ScheduledEvent>(); LaterEventQueue = new ConcurrentQueue <ScheduledEvent>(); DisposedSubjects = new ConcurrentQueue <IEventSubject>(); Server = server; Subjects = new HashSet <IEventSubject>(); Stopwatch = new Stopwatch(); DisabledEvents = new HashSet <string>(); Stopwatch.Start(); }
public void ScheduleNextEvent(Coordinates3D coords, IWorld world, IMultiplayerServer server) { if (world.GetBlockID(coords) == StillID) { return; } var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("fluid", chunk, TimeSpan.FromSeconds(SecondsBetweenUpdates), (_server) => AutomataUpdate(_server, world, coords)); }
private void FlowOutward(IWorld world, LiquidFlow target, IMultiplayerServer server) { // For each block we can flow into, generate an item entity if appropriate var provider = world.BlockRepository.GetBlockProvider(world.GetBlockID(target.TargetBlock)); provider.GenerateDropEntity(new BlockDescriptor { Coordinates = target.TargetBlock, ID = provider.ID }, world, server); // And overwrite the block with a new fluid block. world.SetBlockID(target.TargetBlock, FlowingID); world.SetMetadata(target.TargetBlock, target.Level); server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(SecondsBetweenUpdates), s => AutomataUpdate(s, world, target.TargetBlock)); }
public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world) { if (ID == StillID) { var outward = DetermineOutwardFlow(world, descriptor.Coordinates); var inward = DetermineInwardFlow(world, descriptor.Coordinates); if (outward.Length != 0 || inward != descriptor.Metadata) { world.SetBlockID(descriptor.Coordinates, FlowingID); ScheduleNextEvent(descriptor.Coordinates, world, server); } } }
public virtual bool IsSupported(BlockDescriptor descriptor, IMultiplayerServer server, IWorld world) { var support = GetSupportDirection(descriptor); if (support != Coordinates3D.Zero) { var supportingBlock = server.BlockRepository.GetBlockProvider(world.GetBlockID(descriptor.Coordinates + support)); if (!supportingBlock.Opaque) { return(false); } } return(true); }
public static void HandleAnimation(IPacket _packet, IRemoteClient _client, IMultiplayerServer server) { var packet = (AnimationPacket)_packet; var client = (RemoteClient)_client; if (packet.EntityID == client.Entity.EntityID) { var nearby = server.GetEntityManagerForWorld(client.World) .ClientsForEntity(client.Entity); foreach (var player in nearby) { player.QueuePacket(packet); } } }
private void GrowBlock(IMultiplayerServer server, IWorld world, Coordinates3D coords) { if (world.GetBlockID(coords) != BlockID) return; var meta = world.GetMetadata(coords); meta++; world.SetMetadata(coords, meta); if (meta < 7) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("crops", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(30, 60)), (_server) => GrowBlock(_server, world, coords)); } }
public void GenerateDropEntity(BlockDescriptor descriptor, IWorld world, IMultiplayerServer server) { var entityManager = server.GetEntityManagerForWorld(world); var items = GetDrop(descriptor); foreach (var item in items) { if (item.Empty) { continue; } var entity = new ItemEntity(new Vector3(descriptor.Coordinates) + new Vector3(0.5), item); entityManager.SpawnEntity(entity); } }
public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world) { if (source.Coordinates == descriptor.Coordinates + Coordinates3D.Up) { var provider = world.BlockRepository.GetBlockProvider(source.ID); if (provider.Opaque) { var chunk = world.FindChunk(descriptor.Coordinates, generate: false); server.Scheduler.ScheduleEvent("grass", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinDecayTime, MaxDecayTime)), s => { ScheduledUpdate(world, descriptor.Coordinates); }); } } }
private void AutomataUpdate(IMultiplayerServer server, IWorld world, Coordinates3D coords) { if (world.GetBlockID(coords) != FlowingID && world.GetBlockID(coords) != StillID) { return; } server.BlockUpdatesEnabled = false; var again = DoAutomata(server, world, coords); server.BlockUpdatesEnabled = true; if (again) { server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(SecondsBetweenUpdates), (_server) => AutomataUpdate(_server, world, coords)); } }
private void GrowBlock(IMultiplayerServer server, IWorld world, Coordinates3D coords) { if (world.GetBlockID(coords) != BlockID) { return; } var meta = world.GetMetadata(coords); meta++; world.SetMetadata(coords, meta); if (meta < 7) { server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(MathHelper.Random.Next(30, 60)), (_server) => GrowBlock(_server, world, coords)); } }
internal void ExpandChunkRadius(IMultiplayerServer server) { if (this.Disconnected) { return; } Task.Factory.StartNew(() => { if (ChunkRadius < 8) // TODO: Allow customization of this number { ChunkRadius++; UpdateChunks(); server.Scheduler.ScheduleEvent("remote.chunks", this, TimeSpan.FromSeconds(1), ExpandChunkRadius); } }); }
public RemoteClient(IMultiplayerServer server, NetworkStream stream) { NetworkStream = stream; MinecraftStream = new MinecraftStream(new TrueCraft.Core.Networking.BufferedStream(NetworkStream)); PacketQueue = new ConcurrentQueue <IPacket>(); LoadedChunks = new List <Coordinates2D>(); Server = server; Inventory = new InventoryWindow(server.CraftingRepository); InventoryWindow.WindowChange += HandleWindowChange; SelectedSlot = InventoryWindow.HotbarIndex; CurrentWindow = InventoryWindow; ItemStaging = ItemStack.EmptyStack; KnownEntities = new List <IEntity>(); Disconnected = false; EnableLogging = server.EnableClientLogging; NextWindowID = 1; }
private void GrowBlock(IMultiplayerServer server, IWorld world, Coordinates3D coords) { if (world.GetBlockID(coords) != BlockID) { return; } var meta = world.GetMetadata(coords); meta++; world.SetMetadata(coords, meta); if (meta < 7) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("crops", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(30, 60)), (_server) => GrowBlock(_server, world, coords)); } }
private void AutomataUpdate(IMultiplayerServer server, IWorld world, Coordinates3D coords) { if (world.GetBlockID(coords) != FlowingID && world.GetBlockID(coords) != StillID) { return; } server.BlockUpdatesEnabled = false; var again = DoAutomata(server, world, coords); server.BlockUpdatesEnabled = true; if (again) { var chunk = world.FindChunk(coords); server.Scheduler.ScheduleEvent("fluid", chunk, TimeSpan.FromSeconds(SecondsBetweenUpdates), (_server) => AutomataUpdate(_server, world, coords)); } }
public bool DoAutomata(IMultiplayerServer server, IWorld world, Coordinates3D coords) { var previousLevel = world.GetMetadata(coords); var inward = DetermineInwardFlow(world, coords); var outward = DetermineOutwardFlow(world, coords); if (outward.Length == 1 && outward[0].TargetBlock == coords + Coordinates3D.Down) { // Exit early if we have placed a fluid block beneath us (and we aren't a source block) FlowOutward(world, outward[0], server); if (previousLevel != 0) { return(true); } } // Process inward flow if (inward > MaximumFluidDepletion) { world.SetBlockID(coords, 0); return(true); } world.SetMetadata(coords, inward); if (inward == 0 && previousLevel != 0) { // Exit early if we have become a source block return(true); } // Process outward flow for (int i = 0; i < outward.Length; i++) { FlowOutward(world, outward[i], server); } // Set our block to still fluid if we are done spreading. if (outward.Length == 0 && inward == previousLevel) { world.SetBlockID(coords, StillID); return(false); } return(true); }
public void DoUpdate(IMultiplayerServer server, IWorld world, BlockDescriptor descriptor) { var down = descriptor.Coordinates + Coordinates3D.Down; var current = world.GetBlockID(descriptor.Coordinates); if (current != FireBlock.BlockID && current != LavaBlock.BlockID && current != StationaryLavaBlock.BlockID) { return; } // Decay var meta = world.GetMetadata(descriptor.Coordinates); meta++; if (meta == 0xE) { if (!world.IsValidPosition(down) || world.GetBlockID(down) != NetherrackBlock.BlockID) { world.SetBlockID(descriptor.Coordinates, AirBlock.BlockID); return; } } world.SetMetadata(descriptor.Coordinates, meta); if (meta > 9) { var pick = AdjacentBlocks[meta % AdjacentBlocks.Length]; var provider = BlockRepository .GetBlockProvider(world.GetBlockID(pick + descriptor.Coordinates)); if (provider.Flammable) { world.SetBlockID(pick + descriptor.Coordinates, AirBlock.BlockID); } } // Spread DoSpread(server, world, descriptor); // Schedule next event ScheduleUpdate(server, world, descriptor); }
private void TryGrowth(IMultiplayerServer server, Coordinates3D coords, IWorld world) { if (world.GetBlockID(coords) != BlockID) { return; } // Find current height of stalk int height = 0; for (int y = -MaxGrowHeight; y <= MaxGrowHeight; y++) { if (world.GetBlockID(coords + (Coordinates3D.Down * y)) == BlockID) { height++; } } if (height < MaxGrowHeight) { var meta = world.GetMetadata(coords); meta++; world.SetMetadata(coords, meta); var chunk = world.FindChunk(coords); if (meta == 15) { if (world.GetBlockID(coords + Coordinates3D.Up) == 0) { world.SetBlockID(coords + Coordinates3D.Up, BlockID); server.Scheduler.ScheduleEvent("sugarcane", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), (_server) => TryGrowth(_server, coords + Coordinates3D.Up, world)); } } else { server.Scheduler.ScheduleEvent("sugarcane", chunk, TimeSpan.FromSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), (_server) => TryGrowth(_server, coords, world)); } } }
public static void RegisterHandlers(IMultiplayerServer server) { server.RegisterPacketHandler(new KeepAlivePacket().ID, HandleKeepAlive); server.RegisterPacketHandler(new ChatMessagePacket().ID, HandleChatMessage); server.RegisterPacketHandler(new DisconnectPacket().ID, HandleDisconnect); server.RegisterPacketHandler(new HandshakePacket().ID, LoginHandlers.HandleHandshakePacket); server.RegisterPacketHandler(new LoginRequestPacket().ID, LoginHandlers.HandleLoginRequestPacket); server.RegisterPacketHandler(new PlayerGroundedPacket().ID, (a, b, c) => { /* no-op */ }); server.RegisterPacketHandler(new PlayerPositionPacket().ID, EntityHandlers.HandlePlayerPositionPacket); server.RegisterPacketHandler(new PlayerLookPacket().ID, EntityHandlers.HandlePlayerLookPacket); server.RegisterPacketHandler(new PlayerPositionAndLookPacket().ID, EntityHandlers.HandlePlayerPositionAndLookPacket); server.RegisterPacketHandler(new PlayerDiggingPacket().ID, InteractionHandlers.HandlePlayerDiggingPacket); server.RegisterPacketHandler(new PlayerBlockPlacementPacket().ID, InteractionHandlers.HandlePlayerBlockPlacementPacket); server.RegisterPacketHandler(new ChangeHeldItemPacket().ID, InteractionHandlers.HandleChangeHeldItem); server.RegisterPacketHandler(new PlayerActionPacket().ID, InteractionHandlers.HandlePlayerAction); server.RegisterPacketHandler(new ClickWindowPacket().ID, InteractionHandlers.HandleClickWindowPacket); server.RegisterPacketHandler(new CloseWindowPacket().ID, InteractionHandlers.HandleCloseWindowPacket); server.RegisterPacketHandler(new UpdateSignPacket().ID, InteractionHandlers.HandleUpdateSignPacket); }
public RemoteClient(IMultiplayerServer server, IPacketReader packetReader, PacketHandler[] packetHandlers, Socket connection) { LoadedChunks = new List<Coordinates2D>(); Server = server; Inventory = new InventoryWindow(server.CraftingRepository); InventoryWindow.WindowChange += HandleWindowChange; SelectedSlot = InventoryWindow.HotbarIndex; CurrentWindow = InventoryWindow; ItemStaging = ItemStack.EmptyStack; KnownEntities = new List<IEntity>(); Disconnected = false; EnableLogging = server.EnableClientLogging; NextWindowID = 1; Connection = connection; SocketPool = new SocketAsyncEventArgsPool(100, 200, 65536); PacketReader = packetReader; PacketHandlers = packetHandlers; cancel = new CancellationTokenSource(); StartReceive(); }
public void DoUpdate(IMultiplayerServer server, IWorld world, BlockDescriptor descriptor) { var down = descriptor.Coordinates + Coordinates3D.Down; var current = world.GetBlockID(descriptor.Coordinates); if (current != FireBlock.BlockID && current != LavaBlock.BlockID && current != StationaryLavaBlock.BlockID) return; // Decay var meta = world.GetMetadata(descriptor.Coordinates); meta++; if (meta == 0xE) { if (!world.IsValidPosition(down) || world.GetBlockID(down) != NetherrackBlock.BlockID) { world.SetBlockID(descriptor.Coordinates, AirBlock.BlockID); return; } } world.SetMetadata(descriptor.Coordinates, meta); if (meta > 9) { var pick = AdjacentBlocks[meta % AdjacentBlocks.Length]; var provider = BlockRepository .GetBlockProvider(world.GetBlockID(pick + descriptor.Coordinates)); if (provider.Flammable) world.SetBlockID(pick + descriptor.Coordinates, AirBlock.BlockID); } // Spread DoSpread(server, world, descriptor); // Schedule next event ScheduleUpdate(server, world, descriptor); }
void HydrationCheckEvent(IMultiplayerServer server, Coordinates3D coords, IWorld world) { if (world.GetBlockID(coords) != BlockID) return; if (MathHelper.Random.Next(3) == 0) { var meta = world.GetMetadata(coords); if (IsHydrated(coords, world) && meta != 15) meta++; else { meta--; if (meta == 0) { world.SetBlockID(coords, BlockID); return; } } world.SetMetadata(coords, meta); } server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(UpdateIntervalSeconds), (_server) => HydrationCheckEvent(_server, coords, world)); }
private void TryGrowth(IMultiplayerServer server, Coordinates3D coords, IWorld world) { if (world.GetBlockID(coords) != BlockID) return; // Find current height of stalk int height = 0; for (int y = -3; y <= 3; y++) { if (world.GetBlockID(coords + (Coordinates3D.Down * y)) == BlockID) height++; } if (height < 3) { var meta = world.GetMetadata(coords); meta++; world.SetMetadata(coords, meta); if (meta == 15) { world.SetBlockID(coords + Coordinates3D.Up, BlockID); server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), (_server) => TryGrowth(_server, coords + Coordinates3D.Up, world)); } else { server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(MathHelper.Random.Next(MinGrowthSeconds, MaxGrowthSeconds)), (_server) => TryGrowth(_server, coords, world)); } } }
public override void BlockLoadedFromChunk(Coordinates3D coords, IMultiplayerServer server, IWorld world) { var state = GetState(world, coords); TryInitializeFurnace(state, server.Scheduler, world, coords, server.ItemRepository); }
public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world) { if (!ValidPlacement(descriptor, world)) { // Destroy self world.SetBlockID(descriptor.Coordinates, 0); GenerateDropEntity(descriptor, world, server); } }