Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Second attempt at CryoPod Creature addition #15

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions ArkSavegameToolkitNet.Domain/ArkLocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public class ArkLocation
{ "TheVolcano", Tuple.Create(50.0f, 9181.0f, 50.0f, 9181.0f) },
{ "PGARK", Tuple.Create(0.0f, 6080.0f, 0.0f, 6080.0f) },
{ "CrystalIsles" , Tuple.Create(50.0f, 13718.0f, 50.0f, 13718.0f) },
{ "Valguero_P" , Tuple.Create(50.0f, 8161.0f, 50.0f, 8161.0f) }

{ "Valguero_P" , Tuple.Create(50.0f, 8161.0f, 50.0f, 8161.0f) },
{ "Genesis", Tuple.Create(50.0f, 10500.0f, 50.0f, 10500.0f)}
};

//width, height, latitude-top, longitude-left, longitude-right, latitude-bottom
Expand All @@ -36,7 +36,7 @@ public class ArkLocation

static ArkLocation()
{
System.Drawing.Bitmap island = null, center = null, scorched = null, ragnarok = null, aberration = null, extinction = null, crystal = null, shigo = null, volcano = null, valguero = null;
System.Drawing.Bitmap island = null, center = null, scorched = null, ragnarok = null, aberration = null, extinction = null, crystal = null, shigo = null, volcano = null, valguero = null, genesis = null;
try
{
island = MapResources.topo_map_TheIsland;
Expand All @@ -49,6 +49,8 @@ static ArkLocation()
shigo = MapResources.topo_map_ShigoIslands;
volcano = MapResources.topo_map_TheVolcano;
valguero = MapResources.topo_map_Valguero_P;
genesis = MapResources.topo_map_Genesis;


//painted-maps are divided into a 10x10 grid, lacking precise offsets and should instead align with the grid (0.0f, 0.0f, 100.0f, 100.0f)
//topo-maps offsets are calculated using two easily identifiable points on the map and reversing the formula for TopoMapX/TopoMapY val-2.95f, 0.0f, 86.3f, 89.0f
Expand All @@ -63,7 +65,9 @@ static ArkLocation()
{ "CrystalIsles", Tuple.Create(crystal.Width, crystal.Height, -1.7f, -1.5f, 99.3f, 101.0f) },
{ "ShigoIslands", Tuple.Create(shigo.Width, shigo.Height, -2.0f, -1.6f, 99.8f, 101.0f) },
{ "TheVolcano", Tuple.Create(volcano.Width, volcano.Height, -1.95f, -1.3f, 99.5f, 100.7f) },
{ "Valguero_P", Tuple.Create(valguero.Width, valguero.Height, -10.0f, -10.0f, 110.0f, 110.0f) }
{ "Valguero_P", Tuple.Create(valguero.Width, valguero.Height, -10.0f, -10.0f, 110.0f, 110.0f) },
{ "Genesis", Tuple.Create(genesis.Width, genesis.Height, 0.0f, 0.0f, 100.0f, 100.0f) }

};
}
finally
Expand All @@ -78,6 +82,7 @@ static ArkLocation()
shigo?.Dispose();
volcano?.Dispose();
valguero?.Dispose();
genesis?.Dispose();
}
}

Expand Down
5 changes: 5 additions & 0 deletions ArkSavegameToolkitNet.Domain/ArkPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class ArkPlayer : ArkGameDataContainerBase
private static readonly ArkName _playerDataID = ArkName.Create("PlayerDataID");
private static readonly ArkName _uniqueID = ArkName.Create("UniqueID");
private static readonly ArkName _tribeID = ArkName.Create("TribeID");
private static readonly ArkName _tribeId = ArkName.Create("TribeId");
private static readonly ArkName _playerName = ArkName.Create("PlayerName");
private static readonly ArkName _savedNetworkAddress = ArkName.Create("SavedNetworkAddress");
private static readonly ArkName _bIsFemale = ArkName.Create("bIsFemale");
Expand Down Expand Up @@ -163,6 +164,10 @@ public ArkPlayer(IGameObject profile, IGameObject player, DateTime profileSaveTi
Id = (int)mydata.GetPropertyValue<ulong>(_playerDataID);
SteamId = mydata.GetPropertyValue<StructUniqueNetIdRepl>(_uniqueID)?.NetId;
TribeId = mydata.GetPropertyValue<int?>(_tribeID);
if (TribeId == null)
{
TribeId = mydata.GetPropertyValue<int?>(_tribeId); //genesis
}
Name = mydata.GetPropertyValue<string>(_playerName);
SavedNetworkAddress = mydata.GetPropertyValue<string>(_savedNetworkAddress);
CharacterName = myPlayerCharacterConfig.GetPropertyValue<string>(_playerCharacterName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@
<ItemGroup>
<None Include="Resources\topo_map_extinction.jpg" />
</ItemGroup>
<ItemGroup>
<Content Include="Resources\Genesis_Topographic_Map.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
14 changes: 13 additions & 1 deletion ArkSavegameToolkitNet.Domain/ArkTamedCreature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class ArkTamedCreature : ArkCreature
//private static readonly ArkName _tameIneffectivenessModifier = ArkName.Create("TameIneffectivenessModifier");
private static readonly ArkName _tamerString = ArkName.Create("TamerString");
private static readonly ArkName _targetingTeam = ArkName.Create("TargetingTeam");
private static readonly ArkName _tamingTeamId = ArkName.Create("TamingTeamID"); //genesis
private static readonly ArkName _tribeName = ArkName.Create("TribeName");
private static readonly ArkName _lastUpdatedGestationAtTime = ArkName.Create("LastUpdatedGestationAtTime");
private static readonly ArkName _lastUpdatedMatingAtTime = ArkName.Create("_lastUpdatedMatingAtTime");
Expand Down Expand Up @@ -193,12 +194,22 @@ public ArkTamedCreature(IGameObject creature, IGameObject status, ISaveState sav

_saveState = saveState;

IsCryo = creature.IsCryo;
OwningPlayerId = creature.GetPropertyValue<int?>(_owningPlayerID);
OwningPlayerName = creature.GetPropertyValue<string>(_owningPlayerName);
Name = creature.GetPropertyValue<string>(_tamedName);
TamedOnServerName = creature.GetPropertyValue<string>(_tamedOnServerName);
TamerName = creature.GetPropertyValue<string>(_tamerString);
TargetingTeam = creature.GetPropertyValue<int>(_targetingTeam);

if (creature.Properties.ContainsKey(_tamingTeamId)) //genesis
{
TargetingTeam = creature.GetPropertyValue<int>(_tamingTeamId);
}
else
{
TargetingTeam = creature.GetPropertyValue<int>(_targetingTeam);
}

TribeName = creature.GetPropertyValue<string>(_tribeName);
RandomMutationsMale = creature.GetPropertyValue<int?>(_randomMutationsMale) ?? 0;
RandomMutationsFemale = creature.GetPropertyValue<int?>(_randomMutationsFemale) ?? 0;
Expand Down Expand Up @@ -300,6 +311,7 @@ private void Construct()
public double? BabyNextCuddleTime { get; set; }
public DateTime? BabyNextCuddleTimeApprox => _saveState?.GetApproxDateTimeOf(BabyNextCuddleTime);
public bool IsNeutered { get; set; }
public bool IsCryo { get; set; }
public ArkTamedCreatureAncestor[] DinoAncestors { get; set; }
public ArkTamedCreatureAncestor[] DinoAncestorsMale { get; set; }
public sbyte[] GestationEggColors { get; set; }
Expand Down
6 changes: 6 additions & 0 deletions ArkSavegameToolkitNet.Domain/ArkTribe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class ArkTribe : ArkGameDataContainerBase
private static readonly ArkName _tribeData = ArkName.Create("TribeData");
private static readonly ArkName _tribeName = ArkName.Create("TribeName");
private static readonly ArkName _tribeID = ArkName.Create("TribeID");
private static readonly ArkName _tribeId = ArkName.Create("TribeId"); //genesis
private static readonly ArkName _tribeLog = ArkName.Create("TribeLog");
private static readonly ArkName _ownerPlayerDataID = ArkName.Create("OwnerPlayerDataID");
private static readonly ArkName _membersPlayerDataID = ArkName.Create("MembersPlayerDataID");
Expand All @@ -30,6 +31,7 @@ public class ArkTribe : ArkGameDataContainerBase
{
{ _tribeName, null },
{ _tribeID, null },
{ _tribeId, null},
{ _tribeLog, null },
{ _ownerPlayerDataID, null },
{ _membersPlayerDataID, null },
Expand Down Expand Up @@ -78,6 +80,10 @@ public ArkTribe(IGameObject tribe, DateTime tribeSaveTime) : this()

var tribeData = tribe.GetPropertyValue<StructPropertyList>(_tribeData);
Id = tribeData.GetPropertyValue<int>(_tribeID);
if (Id == 0)
{
Id = tribeData.GetPropertyValue<int>(_tribeId); //Genesis changed case to use TribeId
}
Name = tribeData.GetPropertyValue<string>(_tribeName);
OwnerPlayerId = tribeData.GetPropertyValue<int>(_ownerPlayerDataID);
MemberIds = tribeData.GetPropertyValue<ArkArrayInteger>(_membersPlayerDataID)?.Where(x => x != null).Select(x => x.Value).ToArray() ?? new int[] {};
Expand Down
12 changes: 11 additions & 1 deletion ArkSavegameToolkitNet.Domain/MapResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions ArkSavegameToolkitNet.Domain/MapResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,7 @@
<data name="topo_map_Extinction" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\topo_map_extinction.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="topo_map_Genesis" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\Genesis_Topographic_Map.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions ArkSavegameToolkitNet.TestConsoleApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ static void Main(string[] args)
Console.WriteLine($@"Elapsed (gd-apply) {st.ElapsedMilliseconds:N0} ms");

Console.WriteLine("Save data loaded!");


if (gd.TamedCreatures != null)
{
long cryoCreatureCount = gd.TamedCreatures.LongCount(c => c.IsCryo);
Console.WriteLine(cryoCreatureCount + " cryo creatures loaded.");
}


}
else
{
Expand Down
94 changes: 93 additions & 1 deletion ArkSavegameToolkitNet/ArkSaveGame.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using ArkSavegameToolkitNet.Types;
using ArkSavegameToolkitNet.Property;
using ArkSavegameToolkitNet.Structs;
using ArkSavegameToolkitNet.Types;
using log4net;
using Newtonsoft.Json;
using System;
Expand All @@ -18,6 +20,12 @@ public class ArkSavegame : IGameObjectContainer, IDisposable
{
private static ILog _logger = LogManager.GetLogger(typeof(ArkSavegame));

private static readonly ArkName _customItemData = ArkName.Create("CustomItemDatas");
private static readonly ArkName _myCharacterStatusComponent = ArkName.Create("MyCharacterStatusComponent");
private static readonly ArkName _customDataBytesIdentifier = ArkName.Create("CustomDataBytes");
private static readonly ArkName _byteArraysIdentifier = ArkName.Create("ByteArrays");
private static readonly ArkName _bytesIdentifier = ArkName.Create("Bytes");

[JsonProperty]
public IList<GameObject> Objects
{
Expand Down Expand Up @@ -125,8 +133,92 @@ public bool LoadEverything()
//}

readBinary(_archive, _mmf);
var result = LoadCryopodEntries();

return result;
}


private bool LoadCryopodEntries() {
//Now parse out cryo creature data

var cryoPodEntries = Objects.Where(WhereEmptyCryopodHasCustomItemDataBytesArrayBytes)
.Select(SelectCustomDataBytesArrayBytes)
.ToList();


//string filePathWithoutExtension = _fileName.Substring(0, _fileName.LastIndexOf("."));
//string fileExtension = "cryo";
//string filePath = string.Join(".", filePathWithoutExtension, fileExtension);

int nextObjectId = Objects.Count();
foreach (var byteList in cryoPodEntries)
{

// TODO: this should be casted to byte array (.Cast<byte>().ToArray()) after ArkByteValue, and ArkArchive, sbyte to byte changes are made
// convert from sbytes to bytes
sbyte[] sbyteValues = byteList.Value.Cast<sbyte>().ToArray();
byte[] cryoDataBytes = (byte[])(Array)sbyteValues;

//easier to save to disk and read back as memorymappedfile
var filePath = Path.GetTempFileName();
File.WriteAllBytes(filePath, cryoDataBytes);
var fi = new FileInfo(filePath);

using (MemoryMappedFile cryoMmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.Open, null, 0L, MemoryMappedFileAccess.Read))
using (MemoryMappedViewAccessor cryoVa = cryoMmf.CreateViewAccessor(0L, 0L, MemoryMappedFileAccess.Read))
{
ArkArchive cryoArchive = new ArkArchive(cryoVa, fi.Length, _arkNameCache, _arkStringCache, _exclusivePropertyNameTree);

var result = UpdateCryoCreatureStatus(cryoArchive);

Objects.Add(result.Item1);
Objects.Add(result.Item2);
}

//remove temp (cryo data) file
File.Delete(filePath);
}


return true;

bool WhereEmptyCryopodHasCustomItemDataBytesArrayBytes(GameObject o) => o.ClassName.Name == "PrimalItem_WeaponEmptyCryopod_C"
&& o.GetProperty<PropertyArray>(_customItemData)?.Value[0] is StructPropertyList customProperties
&& customProperties.GetProperty<PropertyStruct>(_customDataBytesIdentifier) is PropertyStruct customDataBytes
&& customDataBytes.Value is StructPropertyList byteArrays
&& byteArrays.GetProperty<PropertyArray>(_byteArraysIdentifier)?.Value.Count > 0 && byteArrays.GetProperty<PropertyArray>(_byteArraysIdentifier)?.Value[0] is StructPropertyList bytes
&& bytes != null && bytes.GetProperty<PropertyArray>(_bytesIdentifier) is PropertyArray byteList
&& byteList != null && byteList.Value.Count > 0; //added further checks to prevent NRE.

PropertyArray SelectCustomDataBytesArrayBytes(GameObject o) => ((StructPropertyList)((StructPropertyList)((StructPropertyList)o.GetProperty<PropertyArray>(_customItemData).Value[0]).GetProperty<PropertyStruct>(_customDataBytesIdentifier).Value).GetProperty<PropertyArray>(_byteArraysIdentifier).Value[0]).GetProperty<PropertyArray>(_bytesIdentifier);

Tuple<GameObject, GameObject> UpdateCryoCreatureStatus(ArkArchive cryoArchive) {
cryoArchive.GetBytes(4);

nextObjectId++;
var dino = new GameObject(cryoArchive)
{
ObjectId = nextObjectId,
IsCryo = true
};

nextObjectId++;
var statusobject = new GameObject(cryoArchive)
{
ObjectId = nextObjectId
};

dino.loadProperties(cryoArchive, new GameObject(), 0, null);
var statusComponentRef = dino.GetProperty<PropertyObject>(_myCharacterStatusComponent);
statusComponentRef.Value.ObjectId = statusobject.ObjectId;
dino.properties.Remove(_myCharacterStatusComponent);
dino.properties.Add(_myCharacterStatusComponent, statusComponentRef);

statusobject.loadProperties(cryoArchive, new GameObject(), 0, null);
return new Tuple<GameObject, GameObject>(dino, statusobject);
}

}

public GameObject GetObjectAtOffset(long offset, int nextPropertiesOffset)
Expand Down
3 changes: 2 additions & 1 deletion ArkSavegameToolkitNet/GameObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ private enum GameObjectIs

//query helper fields
private GameObjectIs _isFlags;


public bool IsCryo { get; set; }
public bool IsCreature => (_isFlags & GameObjectIs.IsCreature) == GameObjectIs.IsCreature;
public bool IsTamedCreature => (_isFlags & GameObjectIs.IsTamedCreature) == GameObjectIs.IsTamedCreature;
public bool IsWildCreature => (_isFlags & GameObjectIs.IsWildCreature) == GameObjectIs.IsWildCreature;
Expand Down
1 change: 1 addition & 0 deletions ArkSavegameToolkitNet/IGameObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public interface IGameObject : IPropertyContainer
Guid Uuid { get; set; }

//query helper fields
bool IsCryo { get; set; }
bool IsCreature { get; }
bool IsTamedCreature { get; }
bool IsWildCreature { get; }
Expand Down