public GameInfo(D2Game game, D2Client client, D2Unit player, D2PlayerData playerData) { Game = game; Client = client; Player = player; PlayerData = playerData; }
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); } }
D2GameInfo ReadGameInfo() { try { D2Game game = ReadActiveGameInstance(); if (game == null || 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.) if ((long)memory.PlayerUnit <= 0) { return(null); } IntPtr playerAddress = reader.ReadAddress32(memory.PlayerUnit, AddressingMode.Relative); if ((long)playerAddress <= 0) { return(null); } D2Unit player = reader.Read <D2Unit>(playerAddress); // player address for reading the player (name + quests) DataPointer unitAddress = game.UnitLists[0][client.UnitId & 0x7F]; if (unitAddress.IsNull) { return(null); } // Read player with player data. var tmpPlayer = reader.Read <D2Unit>(unitAddress); var playerData = tmpPlayer.UnitData.IsNull ? null : reader.Read <D2PlayerData>(tmpPlayer.UnitData); return(new D2GameInfo(game, client, player, playerData)); } catch (ProcessMemoryReadException) { return(null); } }
D2GameInfo ReadGameInfo() { try { D2Game game = ReadActiveGameInstance(); if (game == null || 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 D2GameInfo(game, player, playerData)); } catch (ProcessMemoryReadException) { return(null); } }
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); } }