/// <summary> /// Attempts to create a <see cref="IDbController"/> from a <see cref="DbConnectionSettings"/>. If the /// <see cref="IDbController"/> failed to be created, a prompt will be presented to edit the values and retry. /// </summary> /// <param name="s">The <see cref="DbConnectionSettings"/>.</param> /// <param name="createController">The <see cref="Func{T,TResult}"/> describing how to create the /// <see cref="IDbController"/> instance.</param> /// <param name="createPrompt">The <see cref="Func{T,U}"/> to create the prompt asking to change the values.</param> /// <returns> /// The <see cref="IDbController"/> instance, or null if the user aborted before making /// a successful connection. /// </returns> public static IDbController CreateDbControllerPromptEditWhenInvalid(this DbConnectionSettings s, Func <DbConnectionSettings, IDbController> createController, Func <string, bool> createPrompt) { IDbController ret = null; while (true) { string msg = null; try { ret = createController(s); } catch (DatabaseConnectionException ex) { msg = ex.Message; } catch (Exception ex) { msg = ex.Message; } if (ret != null) { break; } if (!createPrompt(msg)) { return(null); } } return(ret); }
/// <summary> /// Initializes a new instance of the <see cref="GlobalState"/> class. /// </summary> GlobalState() { ThreadAsserts.IsMainThread(); // Load all sorts of stuff _contentManager = NetGore.Content.ContentManager.Create(); var dbConnSettings = new DbConnectionSettings(); _dbController = dbConnSettings.CreateDbControllerPromptEditWhenInvalid(x => new ServerDbController(x.GetMySqlConnectionString()), x => dbConnSettings.PromptEditFileMessageBox(x)); _defaultRenderFont = ContentManager.LoadFont("Font/Arial", 16, ContentLevel.Global); Character.NameFont = DefaultRenderFont; GrhInfo.Load(ContentPaths.Dev, ContentManager); AutomaticGrhDataSizeUpdater.Instance.UpdateSizes(); _mapGrhWalls = new MapGrhWalls(ContentPaths.Dev, x => new WallEntity(x)); // Load the child classes _mapState = new MapState(this); // Grab the audio manager instances, which will ensure that they are property initialized // before something that can't pass it an ContentManager tries to get an instance AudioManager.GetInstance(ContentManager); // Set the custom UITypeEditors CustomUITypeEditors.AddEditors(DbController); // Set up the timer _timer = new Timer { Interval = 1000 / 60 }; _timer.Tick += _timer_Tick; }
/// <summary> /// Saves the schema to file. /// </summary> /// <param name="path">The file path to save to. If null, the default path will be used.</param> public static void Save(string path = null) { if (string.IsNullOrEmpty(path)) path = Paths.Root + MySqlHelper.DbSchemaFile; // Load the database settings var dbSettings = new DbConnectionSettings(Paths.Root + MySqlHelper.DbSettingsFile, true); // Get the schema var schema = new SchemaReader(dbSettings); // Save schema.Save(path); }
/// <summary> /// Initializes the <see cref="EventCounterManager"/> class. /// </summary> static EventCounterManager() { // Create a dedicated dbController for the EventCounters since they are all executed in non-blocking mode, // none of the queries touch the normal game tables, and none of the queries do not rely on order of execution var dbConnSettings = new DbConnectionSettings(); var dbController = new ServerDbController(dbConnSettings.GetMySqlConnectionString()); // Create the query objects var pool = dbController.ConnectionPool; var userECQuery = EventCounterHelper.CreateQuery<CharacterID, UserEventCounterType>(pool, EventCountersUserTable.TableName, "user_id", "user_event_counter_id"); var guildECQuery = EventCounterHelper.CreateQuery<GuildID, GuildEventCounterType>(pool, EventCountersGuildTable.TableName, "guild_id", "guild_event_counter_id"); var shopECQuery = EventCounterHelper.CreateQuery<ShopID, ShopEventCounterType>(pool, EventCountersShopTable.TableName, "shop_id", "shop_event_counter_id"); var mapECQuery = EventCounterHelper.CreateQuery<MapID, MapEventCounterType>(pool, EventCountersMapTable.TableName, "map_id", "map_event_counter_id"); var questECQuery = EventCounterHelper.CreateQuery<QuestID, QuestEventCounterType>(pool, EventCountersQuestTable.TableName, "quest_id", "quest_event_counter_id"); var itemTemplateECQuery = EventCounterHelper.CreateQuery<ItemTemplateID, ItemTemplateEventCounterType>(pool, EventCountersItemTemplateTable.TableName, "item_template_id", "item_template_event_counter_id"); var npcECQuery = EventCounterHelper.CreateQuery<CharacterTemplateID, NPCEventCounterType>(pool, EventCountersNpcTable.TableName, "npc_template_id", "npc_event_counter_id"); // Create the event counters _userEventCounter = new EventCounter<CharacterID, UserEventCounterType>(userECQuery); _guildEventCounter = new EventCounter<GuildID, GuildEventCounterType>(guildECQuery); _shopEventCounter = new EventCounter<ShopID, ShopEventCounterType>(shopECQuery); _mapEventCounter = new EventCounter<MapID, MapEventCounterType>(mapECQuery); _questEventCounter = new EventCounter<QuestID, QuestEventCounterType>(questECQuery); _itemTemplateEventCounter = new EventCounter<ItemTemplateID, ItemTemplateEventCounterType>(itemTemplateECQuery); _npcEventCounter = new EventCounter<CharacterTemplateID, NPCEventCounterType>(npcECQuery); }
/// <summary> /// Creates the prompt for editing the <see cref="DbConnectionSettings"/> file. /// </summary> /// <param name="s">The <see cref="DbConnectionSettings"/>.</param> /// <param name="msg">The message to display.</param> /// <returns>True if to retry the connection; false to abort.</returns> static bool PromptEditDbSettingsFile(DbConnectionSettings s, string msg) { if (!s.OpenFileForEdit()) return false; const string instructions = "Please edit the database settings with the appropriate values. Press Retry when done editing, or Cancel to abort."; if (msg == null) msg = instructions; else msg += Environment.NewLine + Environment.NewLine + instructions; if (MessageBox.Show(msg, "Edit database settings", MessageBoxButtons.RetryCancel) == DialogResult.Cancel) return false; s.Reload(); return true; }
/// <summary> /// Creates a new DbController instance if one does not already exist. Do not use this to just acquire a DbController instance when one may already exist - /// use DbControllerBase.GetInstance() instead. /// </summary> /// <returns></returns> public static ServerDbController CreateDbController() { ServerDbController db = null; // See if the instance already exists try { db = DbControllerBase.GetInstance() as ServerDbController; } catch (MemberAccessException) { } if (db == null) { var settings = new DbConnectionSettings(); db = (ServerDbController)settings.CreateDbControllerPromptEditWhenInvalid(x => new ServerDbController(x.GetMySqlConnectionString()), x => PromptEditDbSettingsFile(settings, x)); } return db; }
static void Main() { Console.WriteLine("This program will generate the code files to match the database." + " As a result, many code files will be altered. Are you sure you wish to continue?"); Console.WriteLine("Press Y to continue, or any other key to abort."); if (Console.ReadKey().Key != ConsoleKey.Y) return; Console.WriteLine(); // Force the NetGore.Features.Server assembly to load up so we can properly find the IDbClassGeneratorSettingsProvider // implementations in NetGore.Features.Server. To do this, we just create a random instance of an object in // NetGore.Features.Server. #pragma warning disable 168 var x = new DbClassGeneratorSettings(); #pragma warning restore 168 DbConnectionSettings dbSettings = new DbConnectionSettings(string.Format("{0}..{1}..{1}DemoGame.Server{1}DbSettings.dat", AppDomain.CurrentDomain.BaseDirectory, Path.DirectorySeparatorChar), false); using (var generator = new MySqlClassGenerator(dbSettings.Host, dbSettings.User, dbSettings.Pass, dbSettings.Database, dbSettings.Port)) { var baseStatColumns = GetStatColumnCollectionItems(generator.Formatter, StatCollectionType.Base); var reqStatColumns = GetStatColumnCollectionItems(generator.Formatter, StatCollectionType.Requirement); // Custom usings generator.AddUsing("NetGore.Db"); generator.AddUsing("DemoGame.DbObjs"); // Custom column collections var baseStatTables = new string[] { "character", "character_template", "item", "item_template" }; var reqStatTables = new string[] { "item", "item_template" }; generator.AddColumnCollection("Stat", typeof(StatType), typeof(int), typeof(short), baseStatTables, baseStatColumns); generator.AddColumnCollection("ReqStat", typeof(StatType), typeof(int), typeof(short), reqStatTables, reqStatColumns); // Custom external types generator.AddCustomType(typeof(AccountID), "account", "id"); generator.AddCustomType(typeof(UserPermissions), "account", "permissions"); generator.AddCustomType(typeof(AllianceID), "alliance", "id"); generator.AddCustomType(typeof(CharacterID), "character", "id"); generator.AddCustomType(typeof(CharacterTemplateID), "character", "template_id"); generator.AddCustomType(typeof(EquipmentSlot), "character_equipped", "slot"); generator.AddCustomType(typeof(InventorySlot), "character_inventory", "slot"); generator.AddCustomType(typeof(ActiveStatusEffectID), "character_status_effect", "id"); generator.AddCustomType(typeof(StatusEffectType), "character_status_effect", "status_effect_id"); generator.AddCustomType(typeof(CharacterTemplateID), "character_template", "id"); generator.AddCustomType(typeof(ItemChance), "character_template_equipped", "chance"); generator.AddCustomType(typeof(ItemChance), "character_template_inventory", "chance"); generator.AddCustomType(typeof(ItemID), "item", "id"); generator.AddCustomType(typeof(GrhIndex), "item", "graphic"); generator.AddCustomType(typeof(ItemType), "item", "type"); generator.AddCustomType(typeof(ItemTemplateID), "item_template", "id"); generator.AddCustomType(typeof(GrhIndex), "item_template", "graphic"); generator.AddCustomType(typeof(ItemType), "item_template", "type"); generator.AddCustomType(typeof(MapID), "map", "id"); generator.AddCustomType(typeof(MapSpawnValuesID), "map_spawn", "id"); generator.AddCustomType(typeof(Direction), "map_spawn", "direction_id"); // Mass-added custom types generator.AddCustomType(typeof(AllianceID), "*", "alliance_id", "attackable_id", "hostile_id"); generator.AddCustomType(typeof(CharacterID), "*", "character_id", "target_character_id", "user_id", "npc_id"); generator.AddCustomType(typeof(CharacterTemplateID), "*", "character_template_id", "user_template_id", "npc_template_id"); generator.AddCustomType(typeof(AccountID), "*", "account_id"); generator.AddCustomType(typeof(MapID), "*", "map_id", "respawn_map_id", "load_map_id"); generator.AddCustomType(typeof(ItemID), "*", "item_id"); generator.AddCustomType(typeof(ItemTemplateID), "*", "item_template_id"); generator.AddCustomType(typeof(BodyID), "*", "body_id"); generator.AddCustomType(typeof(SPValueType), "*", "hp", "mp"); generator.AddCustomType(typeof(AIID), "*", "ai_id"); generator.AddCustomType(typeof(WeaponType), "*", "weapon_type"); generator.AddCustomType(typeof(NPCChatDialogID), "*", "chat_dialog"); generator.AddCustomType(typeof(ShopID), "*", "shop_id"); generator.AddCustomType(typeof(ActionDisplayID), "*", "action_display_id"); generator.AddCustomType(typeof(SkillType), "*", "skill_id"); generator.AddCustomType(typeof(UserEventCounterType), "*", "user_event_counter_type"); generator.AddCustomType(typeof(ShopEventCounterType), "*", "shop_event_counter_type"); generator.AddCustomType(typeof(QuestEventCounterType), "*", "quest_event_counter_type"); generator.AddCustomType(typeof(MapEventCounterType), "*", "map_event_counter_type"); generator.AddCustomType(typeof(ItemTemplateEventCounterType), "*", "item_template_event_counter_type"); generator.AddCustomType(typeof(GuildEventCounterType), "*", "guild_event_counter_type"); generator.AddCustomType(typeof(NPCEventCounterType), "*", "npc_event_counter_type"); // Renaming var formatter = generator.Formatter; formatter.AddAlias("alliance_id", "AllianceID"); formatter.AddAlias("account_id", "AccountID"); formatter.AddAlias("attackable_id", "AttackableID"); formatter.AddAlias("hostile_id", "HostileID"); formatter.AddAlias("character_id", "CharacterID"); formatter.AddAlias("character_template_id", "CharacterTemplateID"); formatter.AddAlias("npc_template_id", "NPCTemplateID"); formatter.AddAlias("user_template_id", "UserTemplateID"); formatter.AddAlias("item_template_id", "ItemTemplateID"); formatter.AddAlias("item_id", "ItemID"); formatter.AddAlias("map_id", "MapID"); formatter.AddAlias("load_map_id", "LoadMapID"); formatter.AddAlias("load_x", "LoadX"); formatter.AddAlias("load_y", "LoadY"); formatter.AddAlias("body_id", "BodyID"); formatter.AddAlias("respawn_map_id", "RespawnMapID"); formatter.AddAlias("respawn_x", "RespawnX"); formatter.AddAlias("respawn_y", "RespawnY"); formatter.AddAlias("give_exp", "GiveExp"); formatter.AddAlias("give_cash", "GiveCash"); formatter.AddAlias("status_effect_id", "StatusEffect"); formatter.AddAlias("ai_id", "AIID"); formatter.AddAlias("event_id", "EventID"); formatter.AddAlias("target_character_id", "TargetCharacterID"); formatter.AddAlias("action_display_id", "ActionDisplayID"); formatter.AddAlias("skill_id", "SkillID"); formatter.AddAlias("npc_id", "NPCID"); formatter.AddAlias("user_id", "UserID"); formatter.AddAlias("npc_event_counter_id", "NPCEventCounterID"); formatter.AddAlias("Name"); formatter.AddAlias("ID"); formatter.AddAlias("AI"); formatter.AddAlias("StatPoints"); formatter.AddAlias("HP"); formatter.AddAlias("MP"); formatter.AddAlias("HP"); formatter.AddAlias("MaxHP"); formatter.AddAlias("MaxMP"); formatter.AddAlias("MinHit"); formatter.AddAlias("MaxHit"); // Custom settings defined elsewhere generator.AddCustomSettings(); // Generate var codeItems = generator.Generate(_tempNamespaceName, _tempNamespaceName); foreach (var item in codeItems) { SaveCodeFile(item); } } Console.WriteLine("Done"); }
/// <summary> /// Initializes a new instance of the <see cref="Server"/> class. /// </summary> /// <exception cref="NotSupportedException">NetGore does not support systems that are not in Little Endian mode!</exception> public Server() { // Check for some system settings if (!BitConverter.IsLittleEndian) { const string errmsg = "NetGore does not support systems that are not in Little Endian mode!"; log.Fatal(errmsg); throw new NotSupportedException(errmsg); } // Initialize the engine settings EngineSettingsInitializer.Initialize(); // Create the DbController var settings = new DbConnectionSettings(); _dbController = settings.CreateDbControllerPromptEditWhenInvalid(x => new ServerDbController(x.GetMySqlConnectionString()), x => PromptEditDbSettingsFile(settings, x)); if (_dbController == null) return; // Add the query stats tracker var queryStats = new BasicQueryStatsTracker { LogFilePath = ContentPaths.Build.Root.Join("querystats.txt") }; queryStats.LogFileFrequency = 1000 * 5; _dbController.ConnectionPool.QueryStats = queryStats; // Validate the database DbTableValidator.ValidateTables(_dbController); ValidateDbControllerQueryAttributes(); // Clean-up var cleaner = new ServerCleaner(this); cleaner.Run(); // Load the game data and such InitializeScripts(); // Create some objects _consoleCommands = new ConsoleCommands(this); _groupManager = new GroupManager((gm, x) => new Group(x)); _userAccountManager = new UserAccountManager(DbController); _world = new World(this); _sockets = new ServerSockets(this); WorldStatsTracker.Instance.NetPeerToTrack = _sockets.GetNetServer(); // Check for the password salt if (string.IsNullOrEmpty(ServerSettings.Default.PasswordSalt)) { const string errmsg = "No password salt has been defined in the server settings file. Make sure you define one before releasing."; if (log.IsWarnEnabled) log.WarnFormat(errmsg); } // Set the thread priority SetThreadPriority(ServerSettings.Default.ThreadPriority); // Validate the server's settings var ssv = new ServerSettingsValidator(); ssv.Check(this); if (log.IsInfoEnabled) log.Info("Server loaded."); }