2016-10-22 46 views
0

(對不起,如果我的英語有點不好...)再次登錄時服務器崩潰。 VBA + SQL

我只是剛剛開始玩這個編程的東西,所以我不太確定如何解決一個小問題我似乎與服務器和客戶端之間的通信。

當我啓動服務器時,玩家可以在沒有任何問題的情況下連接並註銷,但只有在他們登錄新角色時才能連接並註銷。 只要人們開始登錄遊戲前的角色,服務器在大約5分鐘後或者他們註銷時崩潰。 如我所說不是專家,但它幾乎就好像服務器/客戶端無法與dbo.players表正確通信:/ 任何幫助將appriciated!謝謝

再次,遺憾的英語不好


表球員:

CREATE TABLE players (
    player_id INT NOT NULL, 
    player_name VARCHAR(50) NOT NULL, 
    player_title VARCHAR(50) DEFAULT '' NOT NULL, 
    player_surname VARCHAR(50) DEFAULT '' NOT NULL, 
    password_hash CHAR(32) NOT NULL, 
    password_salt VARCHAR(50) NOT NULL, 
    access_status SMALLINT DEFAULT 2 NOT NULL, 
    map_id SMALLINT DEFAULT 1 NOT NULL, 
    map_x SMALLINT DEFAULT 50 NOT NULL, 
    map_y SMALLINT DEFAULT 50 NOT NULL, 
    player_facing SMALLINT DEFAULT 2 NOT NULL, 
    bound_id SMALLINT DEFAULT 1 NOT NULL, 
    bound_x SMALLINT DEFAULT 50 NOT NULL, 
    bound_y SMALLINT DEFAULT 50 NOT NULL, 
    player_gold BIGINT DEFAULT 5000 NOT NULL, 
    player_level SMALLINT DEFAULT 1 NOT NULL, 
    experience BIGINT DEFAULT 0 NOT NULL, 
    experience_sold BIGINT DEFAULT 0 NOT NULL, 
    player_hp INT DEFAULT 0 NOT NULL, 
    player_mp INT DEFAULT 0 NOT NULL, 
    player_sp INT DEFAULT 0 NOT NULL, 
    class_id SMALLINT DEFAULT 1 NOT NULL, 
    guild_id SMALLINT DEFAULT 0 NOT NULL, 
    stat_ac SMALLINT DEFAULT 0 NOT NULL, 
    stat_str SMALLINT DEFAULT 0 NOT NULL, 
    stat_sta SMALLINT DEFAULT 0 NOT NULL, 
    stat_dex SMALLINT DEFAULT 0 NOT NULL, 
    stat_int SMALLINT DEFAULT 0 NOT NULL, 
    res_fire SMALLINT DEFAULT 0 NOT NULL, 
    res_water SMALLINT DEFAULT 0 NOT NULL, 
    res_spirit SMALLINT DEFAULT 0 NOT NULL, 
    res_air SMALLINT DEFAULT 0 NOT NULL, 
    res_earth SMALLINT DEFAULT 0 NOT NULL, 
    body_id SMALLINT DEFAULT 1 NOT NULL, 
    face_id SMALLINT DEFAULT 70 NOT NULL, 
    hair_id SMALLINT DEFAULT 26 NOT NULL, 
    hair_r SMALLINT DEFAULT 0 NOT NULL, 
    hair_g SMALLINT DEFAULT 0 NOT NULL, 
    hair_b SMALLINT DEFAULT 0 NOT NULL, 
    hair_a SMALLINT DEFAULT 0 NOT NULL, 
    aether_threshold DECIMAL(9,4) DEFAULT 0 NOT NULL, 
    toggle_settings BIGINT DEFAULT 0 NOT NULL, 

    PRIMARY KEY(player_id) 
); 

CREATE TABLE inventory (
    player_id INT NOT NULL, 
    item_id INT NOT NULL, 
    slot SMALLINT NOT NULL, 
    stack INT NOT NULL, 
); 

SELECT * FROM players; 

SELECT * FROM inventory; 

CREATE TABLE equipped (
    player_id INT NOT NULL, 
    item_id INT NOT NULL, 
    slot SMALLINT NOT NULL 
); 

SELECT * FROM equipped; 

CREATE TABLE combinebag (
    player_id INT NOT NULL, 
    item_id INT NOT NULL, 
    slot SMALLINT NOT NULL, 
    stack INT NOT NULL 
); 

DROP TABLE spellbook 
CREATE TABLE spellbook (
    player_id INT NOT NULL, 
    spell_id INT NOT NULL, 
    slot SMALLINT NOT NULL, 
    last_casted BIGINT DEFAULT 0 NOT NULL 
); 

GO 
DROP PROCEDURE AddPlayerSpells 
GO 
CREATE PROCEDURE AddPlayerSpells @PlayerName VARCHAR(32) AS 

DECLARE @PlayerID INT 
DECLARE @PlayerClass INT 
DECLARE @PlayerLevel INT 
SELECT @PlayerID=player_id, @PlayerClass=class_id, @PlayerLevel=player_level 
FROM players WHERE [email protected] 

DECLARE @SpellClass INT 
DECLARE @SpellLevel INT 
DECLARE @SpellID INT 

DECLARE @Counter INT = 1 

DECLARE ClassSpellCursor CURSOR FOR (SELECT class_id, level, spell_id FROM classes_levelup_spells) 
OPEN ClassSpellCursor 

FETCH NEXT FROM ClassSpellCursor INTO @SpellClass, @SpellLevel, @SpellID 
WHILE @@FETCH_STATUS = 0 
BEGIN 

    IF (@PlayerClass = @SpellClass) AND (@PlayerLevel >= @SpellLevel) BEGIN 
     INSERT INTO spellbook (player_id, spell_id, slot) VALUES (@PlayerID, @SpellID, @Counter) 
     SET @Counter = @Counter + 1 
    END 

    FETCH NEXT FROM ClassSpellCursor INTO @SpellClass, @SpellLevel, @SpellID 
END 

CLOSE ClassSpellCursor 
DEALLOCATE ClassSpellCursor 

GO 
SELECT (experience+experience_sold) AS exp,player_name,class_id FROM players WHERE access_status=2 ORDER BY exp; 

UPDATE players SET experience=experience+experience_sold,experience_sold=0,player_hp=0,player_mp=0 WHERE player_name='Magus' 

UPDATE players SET player_level=25,experience=520000,player_gold=50000,class_id=4 WHERE player_name='' 

UPDATE players SET player_name='Solo' WHERE player_name='Conflict' 

SELECT player_name,(experience + experience_sold) AS expz FROM players WHERE player_level=50 ORDER BY expz DESC 
SELECT * FROM players WHERE player_name='Cipher' 

EXEC AddPlayerSpells '' 

SELECT * FROM inventory WHERE player_id=4 AND slot=30 
UPDATE items SET graphic_tile=120048,graphic_equip=11,graphic_r=0,graphic_g=255,graphic_b=0,graphic_a=200,item_name='Stunnah Shades' WHERE item_id=35967 

DELETE FROM spellbook WHERE player_id=112 AND slot IN (1,2,3,4,5) 

RESTORE DATABASE Goose FROM Disk='I:\gooseserver\20100505GooseBackup' with recovery 

保存玩家DB

/** 
    * SaveToDatabase, saves player info to database 
    * 
    */ 
    public virtual void SaveToDatabase(GameWorld world) 
    { 
     SqlParameter playerNameParam = new SqlParameter("@playerName", SqlDbType.VarChar, 50); 
     playerNameParam.Value = this.Name; 
     SqlParameter playerTitleParam = new SqlParameter("@playerTitle", SqlDbType.VarChar, 50); 
     playerTitleParam.Value = this.Title; 
     SqlParameter playerSurnameParam = new SqlParameter("@playerSurname", SqlDbType.VarChar, 50); 
     playerSurnameParam.Value = this.Surname; 

     if (this.GuildID == 0 && this.Guild != null) this.Guild.Save(world); 

     if (this.AutoCreatedNotSaved) 
     { 
      string query = "INSERT INTO players (player_id, player_name, player_title, player_surname, " + 
       "password_hash, password_salt, access_status, map_id, map_x, map_y, player_facing, " + 
       "bound_id, bound_x, bound_y, player_gold, player_level, experience, experience_sold, " + 
       "player_hp, player_mp, player_sp, class_id, guild_id, stat_ac, stat_str, stat_sta, " + 
       "stat_dex, stat_int, res_fire, res_water, res_spirit, res_air, res_earth, body_id, " + 
       "face_id, hair_id, hair_r, hair_g, hair_b, hair_a, aether_threshold, toggle_settings) VALUES" + 
       "(" + 
       this.PlayerID + "," + 
       " @playerName, @playerTitle, @playerSurname, " + 
       "'" + this.PasswordHash + "', " + 
       "'" + this.PasswordSalt + "', " + 
       (int)this.Access + ", " + 
       this.MapID + ", " + 
       this.MapX + ", " + 
       this.MapY + ", " + 
       this.Facing + ", " + 
       this.BoundID + ", " + 
       this.BoundX + ", " + 
       this.BoundY + ", " + 
       this.Gold + ", " + 
       this.Level + ", " + 
       this.Experience + ", " + 
       this.ExperienceSold + ", " + 
       this.BaseStats.HP + ", " + 
       this.BaseStats.MP + ", " + 
       this.BaseStats.SP + ", " + 
       this.ClassID + ", " + 
       this.GuildID + ", " + 
       this.BaseStats.AC + ", " + 
       this.BaseStats.Strength + ", " + 
       this.BaseStats.Stamina + ", " + 
       this.BaseStats.Dexterity + ", " + 
       this.BaseStats.Intelligence + ", " + 
       this.BaseStats.FireResist + ", " + 
       this.BaseStats.WaterResist + ", " + 
       this.BaseStats.SpiritResist + ", " + 
       this.BaseStats.AirResist + ", " + 
       this.BaseStats.EarthResist + ", " + 
       this.BodyID + ", " + 
       this.FaceID + ", " + 
       this.HairID + ", " + 
       this.HairR + ", " + 
       this.HairG + ", " + 
       this.HairB + ", " + 
       this.HairA + ", " + 
       this.AetherThreshold + ", " + 
       (long)this.ToggleSettings + ")"; 

      this.AutoCreatedNotSaved = false; 

      SqlCommand command = new SqlCommand(query, world.SqlConnection); 
      command.Parameters.Add(playerNameParam); 
      command.Parameters.Add(playerTitleParam); 
      command.Parameters.Add(playerSurnameParam); 
      command.BeginExecuteNonQuery(new AsyncCallback(GameWorld.DefaultEndExecuteNonQueryAsyncCallback), command); 
     } 
     else 
     { 
      string query = "UPDATE players SET " + 
       "[email protected], " + 
       "[email protected], " + 
       "[email protected], " + 
       "password_hash='" + this.PasswordHash + "', " + 
       "password_salt='" + this.PasswordSalt + "', " + 
       "access_status=" + (int)this.Access + ", " + 
       "map_id=" + this.MapID + ", " + 
       "map_x=" + this.MapX + ", " + 
       "map_y=" + this.MapY + ", " + 
       "player_facing=" + this.Facing + ", " + 
       "bound_id=" + this.BoundID + ", " + 
       "bound_x=" + this.BoundX + ", " + 
       "bound_y=" + this.BoundY + ", " + 
       "player_gold=" + this.Gold + ", " + 
       "player_level=" + this.Level + ", " + 
       "experience=" + this.Experience + ", " + 
       "experience_sold=" + this.ExperienceSold + ", " + 
       "player_hp=" + this.BaseStats.HP + ", " + 
       "player_mp=" + this.BaseStats.MP + ", " + 
       "player_sp=" + this.BaseStats.SP + ", " + 
       "class_id=" + this.ClassID + ", " + 
       "guild_id=" + this.GuildID + ", " + 
       "stat_ac=" + this.BaseStats.AC + ", " + 
       "stat_str=" + this.BaseStats.Strength + ", " + 
       "stat_sta=" + this.BaseStats.Stamina + ", " + 
       "stat_dex=" + this.BaseStats.Dexterity + ", " + 
       "stat_int=" + this.BaseStats.Intelligence + ", " + 
       "res_fire=" + this.BaseStats.FireResist + ", " + 
       "res_water=" + this.BaseStats.WaterResist + ", " + 
       "res_spirit=" + this.BaseStats.SpiritResist + ", " + 
       "res_air=" + this.BaseStats.AirResist + ", " + 
       "res_earth=" + this.BaseStats.EarthResist + ", " + 
       "body_id=" + this.BodyID + ", " + 
       "face_id=" + this.FaceID + ", " + 
       "hair_id=" + this.HairID + ", " + 
       "hair_r=" + this.HairR + ", " + 
       "hair_g=" + this.HairG + ", " + 
       "hair_b=" + this.HairB + ", " + 
       "hair_a=" + this.HairA + ", " + 
       "aether_threshold=" + this.AetherThreshold + ", " + 
       "toggle_settings=" + (long)this.ToggleSettings + " " + 
       "WHERE player_id=" + this.PlayerID; 

      SqlCommand command = new SqlCommand(query, world.SqlConnection); 
      command.Parameters.Add(playerNameParam); 
      command.Parameters.Add(playerTitleParam); 
      command.Parameters.Add(playerSurnameParam); 
      command.BeginExecuteNonQuery(new AsyncCallback(GameWorld.DefaultEndExecuteNonQueryAsyncCallback), command); 
     } 

     this.Inventory.Save(world); 
     this.Spellbook.Save(world); 

     foreach (Pet pet in this.Pets) 
     { 
      pet.SaveToDatabase(world); 
     } 
    } 

    /** 

登錄後,服務器崩潰。

enter image description here

回答

0

首先,誤差似乎是映射到錯誤引用整數值或不帶引號字符值的查詢中的語法錯誤。一目瞭然,在您提供的源文件中出現'" @playerName, @playerTitle, @playerSurname, "未正確引用 - 但很難確定地說,而沒有先看到結果字符串。其次,作爲最佳實踐,此處演示的SQL插入語句類型容易受到SQL注入攻擊,應更改爲參數化查詢。

三,'player_id'字段是身份字段嗎?如果是這樣,你不應該在INSERT中明確提供它的值。在執行INSERT時,標識字段的值將自動分配。