D2Game ReadActiveGameInstance() { uint gameId = reader.ReadUInt32(memory.Address.GameId, AddressingMode.Relative); IntPtr worldPointer = reader.ReadAddress32(memory.Address.World, AddressingMode.Relative); // Get world if game is loaded. if (worldPointer == IntPtr.Zero) { return(null); } D2World world = reader.Read <D2World>(worldPointer); // Find the game address. uint gameIndex = gameId & world.GameMask; uint gameOffset = (gameIndex * 0x0C) + 0x08; IntPtr gamePointer = reader.ReadAddress32(world.GameBuffer + gameOffset); // Check for invalid pointers, this value can actually be negative during transition // screens, so we need to reinterpret the pointer as a signed integer. if (unchecked ((int)gamePointer.ToInt64()) < 0) { return(null); } return(reader.Read <D2Game>(gamePointer)); }
GameInfo GetGameInfo() { uint gameId = reader.ReadUInt32(memory.Address.GameId, AddressingMode.Relative); IntPtr worldPointer = reader.ReadAddress32(memory.Address.World, AddressingMode.Relative); // Get world if game is loaded. if (worldPointer == IntPtr.Zero) { return(null); } D2World world = reader.Read <D2World>(worldPointer); // Find the game address. uint gameIndex = gameId & world.GameMask; uint gameOffset = gameIndex * 0x0C + 0x08; IntPtr gamePointer = reader.ReadAddress32(world.GameBuffer + gameOffset); // Check for invalid pointers, this value can actually be negative during transition // screens, so we need to reinterpret the pointer as a signed integer. if (unchecked ((int)gamePointer.ToInt64()) < 0) { return(null); } try { D2Game game = reader.Read <D2Game>(gamePointer); if (game.Client.IsNull) { return(null); } D2Client client = reader.Read <D2Client>(game.Client); // Make sure we are reading a player type. if (client.UnitType != 0) { return(null); } // Get the player address from the list of units. DataPointer unitAddress = game.UnitLists[0][client.UnitId & 0x7F]; if (unitAddress.IsNull) { return(null); } // Read player with player data. var player = reader.Read <D2Unit>(unitAddress); var playerData = player.UnitData.IsNull ? null : reader.Read <D2PlayerData>(player.UnitData); return(new GameInfo(game, player, playerData)); } catch (ProcessMemoryReadException) { return(null); } }
D2Game ReadActiveGameInstance() { uint gameId = reader.ReadUInt32(memory.GameId, AddressingMode.Relative); IntPtr worldPointer = reader.ReadAddress32(memory.World, AddressingMode.Relative); // Get world if game is loaded. if (worldPointer == IntPtr.Zero) { return(null); } D2World world = reader.Read <D2World>(worldPointer); // Find the game address. uint gameIndex = gameId & world.GameMask; uint gameOffset = (gameIndex * 0x0C) + 0x08; IntPtr gamePointer = reader.ReadAddress32(world.GameBuffer + gameOffset); // Check for invalid pointers, this value can actually be negative during transition // screens, so we need to reinterpret the pointer as a signed integer. if (unchecked ((int)gamePointer.ToInt64()) < 0) { return(null); } // TODO: move this out of this function // TODO: fix bug with not increasing gameCount (maybe use some more info from D2Game obj) // Note: gameId can be the same across D2 restarts // - launch d2 // - start game (counter increases) // - close d2 // - launch d2 // - start game (counter doesnt increase) if (gameId != 0 && (lastGameId != gameId)) { gameCount++; lastGameId = gameId; } return(reader.Read <D2Game>(gamePointer)); }
GameInfo ReadGameInfo() { try { // if game is still loading, dont read further var loading = reader.ReadInt32(memory.Loading) != 0; // after start of the game, loading will be true, but // we are still in menu. so we also check if we are in menu // only if we are not in menu, we can be actually loading // TODO: make InMenu mandatory in the memory table, so that // this works for all versions bool inmenu = false; if (memory.InMenu != null) { inmenu = reader.ReadInt32((System.IntPtr)memory.InMenu) != 0; } if (loading && !inmenu) { Logger.Info("Game still loading"); return(null); } uint gameId = reader.ReadUInt32(memory.GameId); IntPtr worldPointer = reader.ReadAddress32(memory.World); // Get world if game is loaded. if (worldPointer == IntPtr.Zero) { return(null); } D2World world = reader.Read <D2World>(worldPointer); // Find the game address. uint gameIndex = gameId & world.GameMask; uint gameOffset = (gameIndex * 0x0C) + 0x08; IntPtr gamePointer = reader.ReadAddress32(world.GameBuffer + gameOffset); // Check for invalid pointers, this value can actually be negative during transition // screens, so we need to reinterpret the pointer as a signed integer. if (unchecked ((int)gamePointer.ToInt64()) < 0) { return(null); } var game = reader.Read <D2Game>(gamePointer); if (game.Client.IsNull) { return(null); } D2Client client = reader.Read <D2Client>(game.Client); // Make sure we are reading a player type. if (client.UnitType != 0) { return(null); } // TODO: find out why the game handles the two cases differently // for quests, the unit address from game.UnitLists works // for inventory, the unit address from memory.PlayerUnit works // the adresses may be same at the beginning but change if you make a rune word // player address for reading the actual player unit (for inventory, skills, etc.) IntPtr playerAddress = reader.ReadAddress32(memory.PlayerUnit); if ((long)playerAddress <= 0) { return(null); } D2Unit player = reader.Read <D2Unit>(playerAddress); // player address for reading the player (name + quests) var tmpPlayer = UnitByTypeAndGuid(game, D2UnitType.Player, client.UnitId); var playerData = (tmpPlayer == null || tmpPlayer.UnitData.IsNull) ? null : reader.Read <D2PlayerData>(tmpPlayer.UnitData); return(new GameInfo(game, gameId, client, player, playerData)); } catch (ProcessMemoryReadException) { return(null); } }