public void Execute(ServerCore server, ClientConnection connection, string[] arguments) { try { if (arguments == null || arguments.Length == 0) { return; } var time = UtopiaTimeSpan.Parse(arguments[0]); server.Clock.SetCurrentTimeOfDay(time); server.ConnectionManager.Broadcast(new DateTimeMessage { DateTime = server.Clock.Now, TimeFactor = server.Clock.TimeFactor }); server.ChatManager.Broadcast("Time updated by " + connection.DisplayName); } catch (Exception ex) { if (ex is OverflowException || ex is FormatException) { connection.Send(new ChatMessage { IsServerMessage = true, DisplayName = "server", Message = "wrong time value, try 9:00 or 21:00" }); } else { throw; } } }
public void CheckGrowing() { var entityGrowingManager = new EntityGrowingManager(null); var random = new Random(1); var entity = new PlantGrowingEntity(); entity.GrowLevels.Add(new GrowLevel { GrowTime = UtopiaTimeSpan.FromHours(1) }); entity.GrowLevels.Add(new GrowLevel { GrowTime = UtopiaTimeSpan.FromHours(1) }); entity.GrowLevels.Add(new GrowLevel { GrowTime = UtopiaTimeSpan.FromHours(1) }); entity.GrowLevels.Add(new GrowLevel { GrowTime = UtopiaTimeSpan.FromHours(1) }); entity.LastGrowUpdate = new UtopiaTime() + UtopiaTimeSpan.FromMinutes(1); var now = new UtopiaTime() + UtopiaTimeSpan.FromHours(2.5); entityGrowingManager.EntityGrowCheck(now, entity, null, random); Assert.AreEqual(2, entity.CurrentGrowLevelIndex); entity = new PlantGrowingEntity(); entity.GrowingSeasons.Add(UtopiaTime.TimeConfiguration.Seasons[0].Name); entity.GrowingSeasons.Add(UtopiaTime.TimeConfiguration.Seasons[2].Name); entity.GrowLevels.Add(new GrowLevel { GrowTime = UtopiaTimeSpan.FromDays(10) }); entity.GrowLevels.Add(new GrowLevel { GrowTime = UtopiaTimeSpan.FromDays(10) }); entity.GrowLevels.Add(new GrowLevel { GrowTime = UtopiaTimeSpan.FromDays(10) }); entity.GrowLevels.Add(new GrowLevel { GrowTime = UtopiaTimeSpan.FromDays(10) }); entity.LastGrowUpdate = new UtopiaTime() + UtopiaTimeSpan.FromMinutes(1); now = new UtopiaTime() + UtopiaTimeSpan.FromMinutes(50); entityGrowingManager.EntityGrowCheck(now, entity, null, random); entity.LastGrowUpdate = now; Assert.AreEqual(0, entity.CurrentGrowLevelIndex); now = new UtopiaTime() + UtopiaTimeSpan.FromYears(1); entityGrowingManager.EntityGrowCheck(now, entity, null, random); entity.LastGrowUpdate = now; Assert.AreEqual(1, entity.CurrentGrowLevelIndex); now = new UtopiaTime() + UtopiaTimeSpan.FromYears(1) + UtopiaTimeSpan.FromMinutes(1); entityGrowingManager.EntityGrowCheck(now, entity, null, random); entity.LastGrowUpdate = now; Assert.AreEqual(2, entity.CurrentGrowLevelIndex); }
public void Execute(ServerCore server, ClientConnection connection, string[] arguments) { if (connection.SelectedNpc == null) { connection.SendChat("No npc is selected"); return; } if (arguments == null || arguments.Length != 2) { connection.SendChat("Wrong parameters"); return; } try { var time = UtopiaTimeSpan.Parse(arguments[1]); var activity = new Activity { Name = arguments[0], StartAt = time }; ServerDynamicEntity serverEntity; if (!server.AreaManager.TryFind(connection.SelectedNpc.DynamicId, out serverEntity)) { connection.SendChat("Can't find the server entity"); return; } var serverNpc = serverEntity as ServerNpc; if (serverNpc == null) { connection.SendChat("Invalid type of the server entity"); return; } var humanAi = serverNpc.GeneralAI as HumanAI; if (humanAi == null) { connection.SendChat("Invalid type of the AI"); return; } humanAi.Activities.Add(activity); serverNpc.Character.OnNeedSave(); connection.SendChat("New activity was added"); } catch (Exception x) { connection.SendChat("Error: " + x); } }
public EntityGrowingManager(ServerCore server) { _server = server; if (_server != null) { _server.Clock.CreateNewTimer(new Clock.GameClockTimer(UtopiaTimeSpan.FromMinutes(15), server.Clock, GrowingLookup)); } }
public override void Initialize(ServerCore server) { _server = server; _server.LoginManager.PlayerAuthorized += LoginManager_PlayerAuthorized; server.Clock.CreateNewTimer(new Clock.GameClockTimer(UtopiaTimeSpan.FromDays(1), server.Clock, PerDayTrigger)); _lastMessage = UpdateWeather(); }
// Overrides the ConvertFrom method of TypeConverter. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string) { return(UtopiaTimeSpan.Parse((string)value)); } return(base.ConvertFrom(context, culture, value)); }
private void TreeIntegrity(ServerChunk chunk, TreeSoul soul) { if (!soul.IsDamaged) { return; } // the tree will regenerate or die after one day if ((_server.Clock.Now - soul.LastUpdate) < UtopiaTimeSpan.FromDays(1)) { return; } var config = _server.EntityFactory.Config; var treeBp = config.TreeBluePrintsDico[soul.TreeTypeId]; var treeBlocks = _treeLSystem.Generate(soul.TreeRndSeed, new Vector3I(), treeBp); var cursor = _server.LandscapeManager.GetCursor(soul.Position); if (soul.IsDying) { // remove the tree using (cursor.TransactionScope()) { foreach (var blockWithPosition in treeBlocks) { cursor.GlobalPosition = (Vector3I)soul.Position + blockWithPosition.WorldPosition; if (cursor.Read() == blockWithPosition.BlockId) { cursor.Write(WorldConfiguration.CubeId.Air); } } } chunk.Entities.Remove(soul); } else { // restore the tree using (cursor.TransactionScope()) { foreach (var blockWithPosition in treeBlocks) { cursor.GlobalPosition = (Vector3I)soul.Position + blockWithPosition.WorldPosition; if (cursor.Read() == WorldConfiguration.CubeId.Air) { cursor.Write(blockWithPosition.BlockId); } } } soul.IsDamaged = false; } }
public EntitySpawningManager(ServerCore server, IEntitySpawningControler entitySpawningControler) { _server = server; _entitySpawningControler = entitySpawningControler; _configuration = _server.WorldParameters.Configuration as UtopiaWorldConfiguration; _landscapeManager = server.LandscapeManager; _fastRandom = new FastRandom(); //This spawn logic can only be down on UtopiaWorldConfiguration and associated processor. if (_configuration != null) { _server.Clock.CreateNewTimer(new Clock.GameClockTimer(UtopiaTimeSpan.FromMinutes(30), server.Clock, UtopiaSpawningLookup)); } }
public void EntityGrowCheck(UtopiaTime now, GrowingEntity entity, ServerChunk chunk, Random random) { if (entity.LastGrowUpdate.IsZero) { return; } var checkTimeSpan = now - entity.LastGrowUpdate; bool updated; bool rotten; // grow time left at the current season var tillTheEndOfSeason = UtopiaTimeSpan.FromSeasons(1d - entity.LastGrowUpdate.TotalSeasons % 1d); if (checkTimeSpan <= tillTheEndOfSeason) { // small grow update updated = GrowSeasonLogic(entity, now.Season, checkTimeSpan, random, chunk, out rotten); if (rotten) { return; } } else { // grow at the end of the first season updated = GrowSeasonLogic(entity, now.Season, tillTheEndOfSeason, random, chunk, out rotten); if (rotten) { return; } // align time to the beginning of next season checkTimeSpan -= tillTheEndOfSeason; while (checkTimeSpan.TotalSeconds > 0) { var seasonCheckSpan = checkTimeSpan.TotalSeasons > 0 ? UtopiaTimeSpan.FromSeasons(1) : checkTimeSpan; updated = GrowSeasonLogic(entity, (now - checkTimeSpan).Season, seasonCheckSpan, random, chunk, out rotten) || updated; if (rotten) { return; } checkTimeSpan -= seasonCheckSpan; } } if (updated) { if (entity is PlantGrowingEntity) { if (chunk != null) { chunk.Entities.RemoveById(entity.StaticId); chunk.Entities.Add(entity); } } var tree = entity as TreeGrowingEntity; if (tree != null) { var treeBlueprint = _server.EntityFactory.Config.TreeBluePrintsDico[tree.TreeTypeId]; if (tree.CurrentGrowTime > treeBlueprint.GrowTime) { // the tree is ready var model = VoxelModel.GenerateTreeModel(tree.TreeRndSeed, treeBlueprint); // create tree blocks var rootOffset = model.States[0].PartsStates[0].Translation; var cursor = _server.LandscapeManager.GetCursor(tree.Position); var frame = model.Frames[0]; var range = new Range3I(new Vector3I(), frame.BlockData.ChunkSize); using (cursor.TransactionScope()) { foreach (var position in range) { var value = frame.BlockData.GetBlock(position); if (value == 0) { continue; } var blockType = value == 1 ? treeBlueprint.TrunkBlock : treeBlueprint.FoliageBlock; var worldPos = (Vector3I)(tree.Position + rootOffset) + position; cursor.GlobalPosition = worldPos; if (cursor.Read() == WorldConfiguration.CubeId.Air) { cursor.Write(blockType); } } } // create tree soul var soul = _server.EntityFactory.CreateEntity <TreeSoul>(); soul.Position = tree.Position; soul.TreeRndSeed = tree.TreeRndSeed; soul.TreeTypeId = tree.TreeTypeId; chunk.Entities.Add(soul); // remove the growing tree chunk.Entities.RemoveById(tree.StaticId); } else { // just make the model bigger tree.Scale = (float)tree.CurrentGrowTime.TotalSeconds / treeBlueprint.GrowTime.TotalSeconds; chunk.Entities.RemoveById(tree.StaticId); chunk.Entities.Add(tree); } } } }
/// <summary> /// Grow at a season /// </summary> private bool GrowSeasonLogic(GrowingEntity entity, Season season, UtopiaTimeSpan passedTime, Random random, ServerChunk chunk, out bool rotten) { bool updated = false; rotten = false; // constranits check if (entity.GrowingSeasons.Count > 0 && !entity.GrowingSeasons.Contains(season.Name)) { return(false); } if (entity.GrowingBlocks.Count > 0 && _server != null) { if (entity.Linked) { var cursor = _server.LandscapeManager.GetCursor(entity.LinkedCube); if (!entity.GrowingBlocks.Contains(cursor.Read())) { return(false); } } else { var cursor = _server.LandscapeManager.GetCursor(entity.Position); if (!entity.GrowingBlocks.Contains(cursor.PeekValue(Vector3I.Down))) { return(false); } } } // TODO: check light constraint when implemented entity.CurrentGrowTime += passedTime; var plant = entity as PlantGrowingEntity; if (plant != null) { // update entity to the actual state while (!plant.IsLastGrowLevel) { var currentLevel = plant.CurrentGrowLevel; if (plant.CurrentGrowTime < currentLevel.GrowTime) { break; } if (plant.CurrentGrowLevelIndex == 0 && plant.RottenChance != 0f) { if (random.NextDouble() < plant.RottenChance) { if (chunk != null) { chunk.Entities.RemoveById(plant.StaticId); } rotten = true; return(true); } } plant.CurrentGrowTime -= currentLevel.GrowTime; plant.CurrentGrowLevelIndex++; updated = true; } } var tree = entity as TreeGrowingEntity; if (tree != null) { // the seed will not grow if there is a tree nearby foreach (var checkChunk in _server.LandscapeManager.AroundChunks(tree.Position)) { if (checkChunk.Entities.OfType <TreeSoul>().Any(s => Vector3D.Distance(s.Position, tree.Position) < 16)) { return(false); } if (checkChunk.Entities.OfType <TreeGrowingEntity>().Any(t => t != tree && t.Scale > 0.1 && Vector3D.Distance(t.Position, tree.Position) < 16)) { return(false); } } updated = true; } return(updated); }
private void SpawnBiomeEntities(UtopiaTime gametime, ServerChunk chunk) { var chunkBiome = _configuration.ProcessorParam.Biomes[chunk.BlockData.ChunkMetaData.ChunkMasterBiomeType]; foreach (var spawnableEntity in chunkBiome.SpawnableEntities) { bool isStaticEntity = _configuration.BluePrints[spawnableEntity.BluePrintId] is IStaticEntity; //Remark : isChunkGenerationSpawning is set to true for static entities, and false for dynamic entities, maybe worth renaming the properties //The aim of it is to avoid dynamic entity creation at chunk generation time (Pure chunk). //Apply creation constaint : //1) if static entity with is isWildChunkNeeded and chunk is not wild => Do nothing if (spawnableEntity.IsWildChunkNeeded && chunk.BlockData.ChunkMetaData.IsWild == false) { continue; } if (chunk.PureGenerated && isStaticEntity) { continue; } var isDayTime = gametime.TimeOfDay > UtopiaTimeSpan.FromHours(8) && gametime.TimeOfDay < UtopiaTimeSpan.FromHours(20); // check daytime constraints if (!spawnableEntity.SpawningDayTime.HasFlag(ChunkSpawningDayTime.Day) && isDayTime) { continue; } if (!spawnableEntity.SpawningDayTime.HasFlag(ChunkSpawningDayTime.Night) && !isDayTime) { continue; } // check season constraint var weatherService = _server.Services.GetService <WeatherService>(); if (weatherService != null && weatherService.CurrentSeason != null && spawnableEntity.SpawningSeasons.Count > 0 && !spawnableEntity.SpawningSeasons.Contains(weatherService.CurrentSeason.Name)) { continue; } ByteChunkCursor chunkCursor = new ByteChunkCursor(chunk.BlockData.GetBlocksBytes(), chunk.BlockData.ColumnsInfo); // ==> Maybe worth to automaticaly create this specialize cursor at server chunk creation ? Multithreading problem ? //It is only use for reading chunk block data in fast way Vector3D entityLocation; if (_entitySpawningControler.TryGetSpawnLocation(spawnableEntity, chunk, chunkCursor, _fastRandom, out entityLocation)) { var entity = _server.EntityFactory.CreateFromBluePrint(spawnableEntity.BluePrintId); var staticEntity = entity as IStaticEntity; if (staticEntity != null) { //Check the maximum amount of static entities; int maxEntityAmount; chunk.BlockData.ChunkMetaData.InitialSpawnableEntitiesAmount.TryGetValue(spawnableEntity.BluePrintId, out maxEntityAmount); if (maxEntityAmount == 0) { continue; } if (chunk.Entities.Where(e => e.BluePrintId == spawnableEntity.BluePrintId) .CountAtLeast(maxEntityAmount)) { continue; } staticEntity.Position = entityLocation; var cursor = _server.LandscapeManager.GetCursor(entityLocation); logger.Debug("Spawning new static entity : {0} at location {1}", staticEntity.Name, entityLocation); var blockLinkedItem = staticEntity as IBlockLinkedEntity; if (blockLinkedItem != null) { blockLinkedItem.LinkedCube = (Vector3I)entityLocation + Vector3I.Down; } cursor.AddEntity(staticEntity); } var charEntity = entity as CharacterEntity; if (charEntity != null) { if (DisableNPCSpawn) { continue; } var radius = Math.Max(8, spawnableEntity.DynamicEntitySpawnRadius); if ( _server.AreaManager.EnumerateAround(entityLocation, radius) .CountAtLeast(spawnableEntity.MaxEntityAmount)) { continue; } charEntity.Position = entityLocation; logger.Debug("Spawning new dynamic entity : {0} at location {1}", charEntity.Name, entityLocation); _server.EntityManager.AddNpc(charEntity); } } } }
public void InitSinglePlayerServer(WorldParameters worldParam) { if (Server != null) { throw new InvalidOperationException("Already initialized"); } _worldParam = worldParam; _serverFactory = new EntityFactory(); _serverFactory.Config = _worldParam.Configuration; var dbPath = Path.Combine(_vars.ApplicationDataPath, "Server", "Singleplayer", worldParam.WorldName, "ServerWorld.db"); logger.Info("Local world db path is {0}", dbPath); _serverSqliteStorageSinglePlayer = new SqliteStorageManager(dbPath, _serverFactory, worldParam); _serverSqliteStorageSinglePlayer.Register("local", "qwe123".GetSHA1Hash(), UserRole.Administrator); var settings = new XmlSettingsManager <ServerSettings>(@"Server\localServer.config"); settings.Load(); settings.Save(); //Utopia New Landscape Test IWorldProcessor processor = null; IEntitySpawningControler entitySpawningControler = null; switch (worldParam.Configuration.WorldProcessor) { case WorldConfiguration.WorldProcessors.Flat: processor = new FlatWorldProcessor(); break; case WorldConfiguration.WorldProcessors.Utopia: processor = new UtopiaProcessor(worldParam, _serverFactory, _landscapeEntityManager); entitySpawningControler = new UtopiaEntitySpawningControler((UtopiaWorldConfiguration)worldParam.Configuration); break; default: break; } var worldGenerator = new WorldGenerator(worldParam, processor); worldGenerator.EntitySpawningControler = entitySpawningControler; //Old s33m3 landscape //IWorldProcessor processor1 = new s33m3WorldProcessor(worldParam); //IWorldProcessor processor2 = new LandscapeLayersProcessor(worldParam, _serverFactory); //var worldGenerator = new WorldGenerator(worldParam, processor1, processor2); //Vlad Generator //var planProcessor = new PlanWorldProcessor(wp, _serverFactory); //var worldGenerator = new WorldGenerator(wp, planProcessor); settings.Settings.ChunksCountLimit = 1024 * 3; // better use viewRange * viewRange * 3 var port = 4815; while (!TcpConnectionListener.IsPortFree(port)) { port++; } settings.Settings.ServerPort = port; _server = new ServerCore(settings, worldGenerator, _serverSqliteStorageSinglePlayer, _serverSqliteStorageSinglePlayer, _serverSqliteStorageSinglePlayer, _serverSqliteStorageSinglePlayer, _serverFactory, worldParam); _serverFactory.LandscapeManager = Server.LandscapeManager; _serverFactory.DynamicEntityManager = Server.AreaManager; _serverFactory.GlobalStateManager = Server.GlobalStateManager; _serverFactory.ScheduleManager = Server.Scheduler; _serverFactory.ServerSide = true; _server.Initialize(); Server.ConnectionManager.LocalMode = true; Server.ConnectionManager.Listen(); Server.LoginManager.PlayerEntityNeeded += LoginManagerPlayerEntityNeeded; Server.LoginManager.GenerationParameters = default(Utopia.Shared.World.PlanGenerator.GenerationParameters); // planProcessor.WorldPlan.Parameters; Server.Clock.SetCurrentTimeOfDay(UtopiaTimeSpan.FromHours(12)); }