Пример #1
0
		public CharacterResponseList(Account account)
			: base(0x6b) {
			int charCount = account.Chars.Count;

			// Space for packet length
			Write((short)0);
			// if PACKETVER >= 20100413
			Write((byte)12); // Max slots.
			Write((byte)12); // Available slots.
			Write((byte)12); // Premium slots.
			// endif
			Writer.Fill(20); // unknown bytes

			int charsLength = 0;
			foreach (Character c in account.Chars.Values) {
				charsLength += c.ToStream(Writer);
			}

			// Write packet length
			short length = (short)Writer.Length;
			Writer.Seek(2, System.IO.SeekOrigin.Begin);
			Write(length);
			// Just to be sure.. seek to end
			Writer.Seek(0, System.IO.SeekOrigin.End);
		}
Пример #2
0
		public WorldAuthOK(Account account)
			: base(0x73, 11) {
			Write((int)DateTime.Now.Ticks);
			Write(account.ActiveChar.Location);
			Write((byte)5); // ignored..
			Write((byte)5); // ignored..
		}
Пример #3
0
		public LoginResponseServerList(Account acc)
			: base(0x69) {

			int serverCount = 1;
			Write((short)(47 + (32 * serverCount)));
			Write(acc.LoginID1);
			Write((int)acc.Serial);
			Write(acc.LoginID2);
			Write((int)0); // in old version, that was for ip (not more used)
			Writer.Fill(24); // in old version, that was for name (not more used)
			Write((short)0); // unknown
			Write((byte)acc.Sex); // sd->sex

			// Server list
			int ipNum = (int)Core.Connector.Listener.IPs[0].Address;
			int port = Core.Connector.Listener.Ports[0];
			for (int i = 0; i < serverCount; i++) {
				Write(ipNum); // Server IP
				Write((short)port); // Server Port
				Write("Rovolution", 20); // Server Name
				Write((short)20); // Usercount
				Write((short)0); // Server type (RPG/?)
				Write((short)i); // is new?
			}

		}
Пример #4
0
		public LoginResponseServerList(Account acc)
			: base(0x69) {

			int serverCount = 1;
			Write((short)(47 + (32 * serverCount)));
			Write(acc.LoginID1);
			Write((int)acc.WorldID.ID);
			Write(acc.LoginID2);
			Write((int)0); // in old version, that was for ip (not more used)
			Writer.Fill(24); // in old version, that was for name (not more used)
			Write((short)0); // unknown
			Write((byte)acc.Sex); // sd->sex

			// Server list
			// TODO: after M$ set the Address-property to deprecated, we need our own way to
			//		 convert an IP to a number.
			//		 Compare them vs more networks to ensure it works properly
			//int ipNum = (int)Core.Connector.Listener.IPs[0].Address; // Depri =/
			int ipNum = (int)Core.Connector.Listener.IPs[0].GetAddress();
			int port = Core.Connector.Listener.Ports[0];
			for (int i = 0; i < serverCount; i++) {
				Write(ipNum); // Server IP
				Write((short)port); // Server Port
				Write("Rovolution", 20); // Server Name
				Write((short)1337); // Usercount
				Write((short)0); // Server type (RPG/?)
				Write((short)i); // is new?
			}

		}
Пример #5
0
		public WorldConnectionResponse(Account account)
			: base(0x283, 6) {
			Write(account.ID);
		}
Пример #6
0
		public CharacterResponseSuccess(Account account)
			: base(0, 4) {
			Write(account.WorldID.ID);
		}
Пример #7
0
		public CharacterResponseSuccess(Account account)
			: base(0, 4) {
			Write(account.Serial.Value);
		}
Пример #8
0
		public static ECharacterCreationResult Create(Account account, string name, byte slot, byte str, byte agi, byte vit, byte int_, byte dex, byte luk, short hairColor, short hairStyle, out Character newChar) {
			newChar = null;

			if (name.Length > 24) {
				name = name.Substring(0, 24);
			}
			//name = name.Replace('\032', ' ').Replace('\t', ' ').Replace('\x0A', ' ').Replace('\x0D', ' ');

			if (
				(slot >= Global.MAX_SLOTS) ||
				(str + agi + vit + int_ + dex + luk != 6 * 5) ||
				(str < 1 || str > 9 || agi < 1 || agi > 9 || vit < 1 || vit > 9 || int_ < 1 || int_ > 9 || dex < 1 || dex > 9 || luk < 1 || luk > 9) ||
				(str + int_ != 10 || agi + luk != 10 || vit + dex != 10)
			) {
				return ECharacterCreationResult.CharCreationDenied; // invalid input
			}

			// Check for max character count on this account
			if (account.Chars.Count >= Global.MAX_SLOTS) {
				return ECharacterCreationResult.CharCreationDenied; // character account limit exceeded
			}
			// Check for existing char with this name
			if (Core.Database.Query("SELECT charID FROM `char` WHERE `name` = '{0}'", name.MysqlEscape()).Rows.Count > 0) {
				return ECharacterCreationResult.CharnameAlreadyExists;
			}
			// Check for existing char on this slot
			foreach (Character tmpChar in account.Chars.Values) {
				if (tmpChar.Status.Slot == slot) {
					return ECharacterCreationResult.CharCreationDenied;
				}
			}

			// TODO: this has to be in CharacterDatabaseStatus, nor?
			//		 CharacterDatabaseData represents the character in the character server
			//		 so..
			newChar = new Character(DatabaseID.Zero, false);
			newChar.Parent = account;
			newChar.Status.Name = name;
			newChar.Status.Slot = slot;
			newChar.Status.Zeny = Config.StartZeny;
			newChar.Status.Str = str;
			newChar.Status.Agi = agi;
			newChar.Status.Dex = dex;
			newChar.Status.Vit = vit;
			newChar.Status.Int = int_;
			newChar.Status.Luk = luk;
			newChar.Status.HPMax = newChar.Status.HP = (40 * (100 + vit) / 100);
			newChar.Status.SPMax = newChar.Status.SP = (11 * (100 + int_) / 100);
			newChar.Status.HairStyle = hairStyle;
			newChar.Status.HairColor = hairColor;
			newChar.Status.SavePoint = new Location(Mapcache.GetID(Config.StartMap), Config.StartMapX, Config.StartMapY);
			newChar.Status.Location = new Location(newChar.Status.SavePoint.Map.ID, newChar.Status.SavePoint.Point.X, newChar.Status.SavePoint.Point.Y);

			// Save it
			CharacterDatabaseData status = newChar.Status;
			string query =
				string.Format(
					"INSERT INTO `char` (" +
						"`accountID`, `slot`, `name`, `zeny`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hpMax`, `hp`," +
						"`spMax`, `sp`, `hair`, `hairColor`, `lastMap`, `lastX`, `lastY`, `saveMap`, `saveX`, `saveY`" +
					") VALUES (" +
						"{0}, {1}, '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}', '{11}'," +
						"'{12}', '{13}', '{14}', '{15}', '{16}', '{17}', '{18}', '{19}', '{20}', '{21}'" +
					")"
					,
					account.WorldID.ID, slot, name.MysqlEscape(), status.Zeny, status.Str, status.Agi, status.Vit,
					status.Int, status.Dex, status.Luk, status.HPMax, status.HP, status.SPMax, status.SP,
					status.HairStyle, status.HairColor, status.Location.Map, status.Location.Point.X, status.Location.Point.Y,
					status.SavePoint.Map, status.SavePoint.Point.X, status.SavePoint.Point.X
				);
			Core.Database.Query(query);
			uint charID = (uint)Core.Database.GetLastInsertID();
			if (charID == 0) {
				// Failed to add character?
				return ECharacterCreationResult.CharCreationDenied;
			}
			// save Serial/CharID
			newChar.UpdateDatabaseID(charID, EDatabaseType.Char);
			newChar.WorldID = new WorldID(charID, EDatabaseType.Char);
			// Add it to account dictionary
			account.Chars.Add(newChar.WorldID, newChar);

			return ECharacterCreationResult.Success;
		}
Пример #9
0
		public static Character Load(Account account, DataRow row) {
			Character c = new Character(DatabaseID.Zero, false);
			// Load basic character data
			c.Status = new CharacterDatabaseData(row);

			// Update WorldID (same as Serial/DatabaseID)
			c.WorldID = new WorldID(c.Status.Serial.ID, c.Status.Serial.Type);
			// Update location
			c.Location = c.Status.Location;
			// Update account
			c.Parent = account;

			return c;
		}
Пример #10
0
		/// <summary>
		/// Try to load a specific account from the database
		/// </summary>
		/// <param name="state"></param>
		/// <param name="Name"></param>
		/// <param name="Password"></param>
		/// <param name="Acc"></param>
		/// <returns>EAccountLoadResult</returns>
		public static EAccountLoadResult Load(NetState state, string Name, string Password, out Account Acc, bool loadChars) {
			// Lookup on object manager
			if ((Acc = World.Objects.SearchAccount(Name)) != null) {
				if (loadChars == true) {
					Acc.LoadChars();
				}
				Acc.Netstate = state;
				return EAccountLoadResult.Success;
			}

			// Not found, load from Database
			Acc = new Account(true); // auto-push to world
			Acc.Netstate = state;
			DataTable table = Core.Database.Query("SELECT a.*, COUNT(*) AS charCount FROM account AS a LEFT JOIN `char` AS c ON c.accountID = a.accountID WHERE a.username = '******' LIMIT 0,1", Name.MysqlEscape());
			table.TableName = "Account Table";
			if (table.Rows.Count == 0) {
				return EAccountLoadResult.UnregisteredID;
			}

			DataRow accRow = table.Rows[0];

			// Password check
			if (accRow.Field<string>("password") != Password) {
				Acc = null;
				return EAccountLoadResult.IncorrectPassword;
			}
			Rovolution.Server.Database.RovolutionDatabase.PrintTableTypes(accRow.Table);
			// Enfore a serial value equal to the account ID
			// Assumes our Account creation script wont take a same ID twice
			Acc.WorldID = new WorldID(accRow.Field<uint>("accountID"), EDatabaseType.Account);
			Acc.Name = accRow.Field<string>("username");
			Acc.Password = accRow.Field<string>("password");
			Acc.Sex = (accRow.Field<string>("sex").ToLower() == "m" ? EAccountSex.Male : EAccountSex.Female);
			Acc.Email = accRow.Field<string>("email");
			Acc.GMLevel = accRow.FieldNull<sbyte>("gmLevel");
			Acc.LastIP = accRow.Field<string>("lastIP");
			Acc.LastLogin = accRow.FieldDateTime("lastLogin");
			Acc.LoginID1 = mLoginRandomizer.Next() + 1;
			Acc.LoginID2 = mLoginRandomizer.Next() + 1;
			// `accountState`, `unbanTime`, `expirationTime`, `loginCount`, `birthDate`
			if (loadChars == true) {
				Acc.LoadChars();
			}

			return EAccountLoadResult.Success;
		}
Пример #11
0
		/// <summary>
		/// Try to load a specific account from the database, including all characters
		/// </summary>
		/// <param name="State"></param>
		/// <param name="Name"></param>
		/// <param name="Password"></param>
		/// <param name="Acc"></param>
		/// <returns>EAccountLoadResult</returns>
		public static EAccountLoadResult Load(NetState State, string Name, string Password, out Account Acc) {
			return Load(State, Name, Password, out Acc, true);
		}