public PropertyBase(string name, string typeName, int index, TValue value) { Name = ArkName.Create(name); //TypeName = ArkName.Create(typeName); Index = index; _value = value; }
//public static IProperty GetProperty(this IPropertyContainer self, string name) //{ // return self.GetProperty(name, 0); //} //public static IProperty GetProperty(this IPropertyContainer self, string name, int index) //{ // foreach (var prop in self.Properties) // { // if (prop.Index == index && prop.Name.Token.Equals(name)) // { // return prop; // } // } // return null; //} public static TProperty GetProperty <TProperty>(this IPropertyContainer self, string token) where TProperty : class, IProperty { IProperty prop = null; return(self.Properties.TryGetValue(ArkName.Create(token), out prop) ? prop as TProperty : (TProperty)null); }
public StructPropertyList(ArkArchive archive, ArkName structType) : this(structType) { Properties = new Dictionary <ArkName, IProperty>(); var property = PropertyRegistry.readProperty(archive); while (property != null) { Properties.Add(ArkName.Create(property.Name.Token, property.Index), property); property = PropertyRegistry.readProperty(archive); } }
public StructPropertyList(ArkArchive archive, ArkName structType, ArkNameTree exclusivePropertyNameTree = null) : this(structType) { Properties = new Dictionary <ArkName, IProperty>(); var property = PropertyRegistry.readProperty(archive, exclusivePropertyNameTree); while (property != null) { if (property != ExcludedProperty.Instance) { Properties.Add(ArkName.Create(property.Name.Token, property.Index), property); } property = PropertyRegistry.readProperty(archive, exclusivePropertyNameTree); } }
public ArkArrayStruct(ArkArchive archive, int dataSize) { var size = archive.GetInt(); Capacity = size; ArkName structType; if (size * 4 + 4 == dataSize) { structType = ArkName.Create("Color"); } else if (size * 12 + 4 == dataSize) { structType = ArkName.Create("Vector"); } else if (size * 16 + 4 == dataSize) { structType = ArkName.Create("LinearColor"); } else { structType = null; } if (structType != null) { for (int n = 0; n < size; n++) { Add(StructRegistry.read(archive, structType)); } } else { for (int n = 0; n < size; n++) { Add(new StructPropertyList(archive, null)); } } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return(ArkName.Create(JToken.Load(reader).ToString())); }
public bool Update(bool manualUpdate, IConfig fullconfig, ISavegameBackupService savegameBackupService, IProgress <string> progress, CancellationToken ct) { //backup this savegame if (!manualUpdate) { SavegameBackupResult result = null; try { if (fullconfig.BackupsEnabled) { result = savegameBackupService.CreateBackup(Config, _contextManager?.GetCluster(Config.Cluster)?.Config); if (result != null && result.ArchivePaths != null) { progress.Report($@"Server ({Config.Key}): Backup successfull ({(string.Join(", ", result.ArchivePaths.Select(x => $@"""{x}""")))})!"); } else { progress.Report($"Server ({Config.Key}): Backup failed..."); } } } catch (Exception ex) { Logging.LogException($"Server ({Config.Key}): Backup failed", ex, typeof(ArkServerContext), LogLevel.ERROR, ExceptionLevel.Ignored); } BackupCompleted?.Invoke(this, fullconfig.BackupsEnabled, result); } //todo: temp copy all var copy = true; var success = false; var cancelled = false; var tmppaths = new List <string>(); var gid = Guid.NewGuid().ToString(); var tempFileOutputDirPath = Path.Combine(fullconfig.TempFileOutputDirPath, gid); ArkSavegame save = null; var st = Stopwatch.StartNew(); try { progress.Report($"Server ({Config.Key}): Update started ({DateTime.Now:HH:mm:ss.ffff})"); var directoryPath = Path.GetDirectoryName(Config.SaveFilePath); if (copy) { //todo: if it exists get a new path if (!Directory.Exists(tempFileOutputDirPath)) { Directory.CreateDirectory(tempFileOutputDirPath); } } if (copy) { var saveFilePath = Path.Combine(tempFileOutputDirPath, Path.GetFileName(Config.SaveFilePath)); tmppaths.Add(saveFilePath); File.Copy(Config.SaveFilePath, saveFilePath); save = new ArkSavegame(saveFilePath); } else { save = new ArkSavegame(Config.SaveFilePath); } save.LoadEverything(); ct.ThrowIfCancellationRequested(); ArkSavegameToolkitNet.ArkTribe[] tribes = null; if (copy) { var tribePaths = new List <string>(); foreach (var tp in Directory.GetFiles(directoryPath, "*.arktribe", SearchOption.TopDirectoryOnly)) { var tribePath = Path.Combine(tempFileOutputDirPath, Path.GetFileName(tp)); tribePaths.Add(tp); tmppaths.Add(tribePath); File.Copy(tp, tribePath); } tribes = tribePaths.Select(x => new ArkSavegameToolkitNet.ArkTribe(x)).ToArray(); } else { tribes = Directory.GetFiles(directoryPath, "*.arktribe", SearchOption.TopDirectoryOnly).Select(x => new ArkSavegameToolkitNet.ArkTribe(x)).ToArray(); } ct.ThrowIfCancellationRequested(); ArkProfile[] profiles = null; if (copy) { var profilePaths = new List <string>(); foreach (var pp in Directory.GetFiles(directoryPath, "*.arkprofile", SearchOption.TopDirectoryOnly)) { var profilePath = Path.Combine(tempFileOutputDirPath, Path.GetFileName(pp)); profilePaths.Add(pp); tmppaths.Add(profilePath); File.Copy(pp, profilePath); } profiles = profilePaths.Select(x => new ArkProfile(x)).ToArray(); } else { profiles = Directory.GetFiles(directoryPath, "*.arkprofile", SearchOption.TopDirectoryOnly).Select(x => new ArkProfile(x)).ToArray(); } ct.ThrowIfCancellationRequested(); var _myCharacterStatusComponent = ArkName.Create("MyCharacterStatusComponent"); var statusComponents = save.Objects.Where(x => x.IsDinoStatusComponent).ToDictionary(x => x.Index, x => x); var tamed = save.Objects.Where(x => x.IsTamedCreature).Select(x => { GameObject status = null; statusComponents.TryGetValue(x.GetPropertyValue <ObjectReference>(_myCharacterStatusComponent).ObjectId, out status); return(x.AsTamedCreature(status, null, save.SaveState)); }).ToArray(); var wild = save.Objects.Where(x => x.IsWildCreature).Select(x => { GameObject status = null; statusComponents.TryGetValue(x.GetPropertyValue <ObjectReference>(_myCharacterStatusComponent).ObjectId, out status); return(x.AsWildCreature(status, null, save.SaveState)); }).ToArray(); var _myData = ArkName.Create("MyData"); var _playerDataID = ArkName.Create("PlayerDataID"); var _linkedPlayerDataID = ArkName.Create("LinkedPlayerDataID"); var playerdict = save.Objects.Where(x => x.IsPlayerCharacter).ToLookup(x => x.GetPropertyValue <ulong>(_linkedPlayerDataID), x => x); var duplicates = playerdict.Where(x => x.Count() > 1).ToArray(); var players = profiles.Select(x => { var mydata = x.GetPropertyValue <StructPropertyList>(_myData); var playerId = mydata.GetPropertyValue <ulong>(_playerDataID); var player = playerdict[playerId]?.FirstOrDefault(); return(x.Profile.AsPlayer(player, x.SaveTime, save.SaveState)); }).ToArray(); SaveState = save.SaveState; TamedCreatures = tamed; WildCreatures = wild; Players = players; Tribes = tribes.Select(x => x.Tribe.AsTribe(x.SaveTime)).ToArray(); Items = save.Objects.Where(x => x.IsItem).Select(x => x.AsItem(save.SaveState)).ToArray(); Structures = save.Objects.Where(x => x.IsStructure).Select(x => x.AsStructure(save.SaveState)).ToArray(); progress.Report($"Server ({Config.Key}): Update finished in {st.ElapsedMilliseconds:N0} ms"); IsInitialized = true; LastUpdate = DateTime.Now; success = true; } catch (OperationCanceledException) { progress.Report($"Server ({Config.Key}): Update was cancelled after {st.ElapsedMilliseconds:N0} ms"); cancelled = true; } catch (Exception ex) { Logging.LogException($"Failed to update server ({Config.Key})", ex, typeof(ArkServerContext), LogLevel.ERROR, ExceptionLevel.Ignored); progress.Report($"Server ({Config.Key}): Update failed after {st.ElapsedMilliseconds:N0} ms"); } finally { save?.Dispose(); if (copy) { try { foreach (var path in tmppaths) { File.Delete(path); } Directory.Delete(tempFileOutputDirPath); } catch { /* ignore exception */ } } UpdateCompleted?.Invoke(this, success, cancelled); } GC.Collect(); return(success); }
/// <summary> /// Write property data structure information for a collection of GameObjects to specified file path. /// </summary> public static void WriteDataStructure(IEnumerable <IGrouping <string, IGameObject> > gameObjectGroups, string filePath) { //todo: refactor this code to make it less hackish Func <Type, string> getTypeName = null; getTypeName = new Func <Type, string>(t => { var nt = Nullable.GetUnderlyingType(t); if (nt != null) { return($"{getTypeName(nt)}?"); } if (t.IsGenericType) { return($"{t.Name.Remove(t.Name.IndexOf('`'))}<{string.Join(",", t.GetGenericArguments().Select(at => getTypeName(at)))}>"); } if (t.IsArray) { return($"{getTypeName(t.GetElementType())}[{new string(',', t.GetArrayRank() - 1)}]"); } return(t.Name); }); Func <int?, IEnumerable <IProperty>, string, List <string>, List <string> > recursivePropertyList = null; recursivePropertyList = new Func <int?, IEnumerable <IProperty>, string, List <string>, List <string> >((gameObjectCount, props, path, list) => { foreach (var grp in props.GroupBy(x => ArkName.Create(x.Name.Name, x.Index))) { var prop = path == null ? grp.Key.Token : $"{path}->{grp.Key}"; var proparrstruct = grp.OfType <PropertyArray>().Where(x => (x.Value as ArkArrayStruct)?.OfType <StructPropertyList>().Any() == true); var proplist = grp.OfType <PropertyStruct>().Where(x => x.Value is StructPropertyList); var optional = gameObjectCount != null && (gameObjectCount.Value > grp.Count() || gameObjectCount < 0); if (proplist.Any()) { recursivePropertyList(optional ? -1 : (int?)null, proplist.SelectMany(x => (x.Value as StructPropertyList).Properties.Values), prop, list); } else if (proparrstruct.Any()) { recursivePropertyList(optional ? -1 : (int?)null, proparrstruct.SelectMany(x => (x.Value as ArkArrayStruct).OfType <StructPropertyList>().SelectMany(y => y.Properties.Values)), prop, list); } else { list.Add($"{prop} ({getTypeName(((dynamic)grp.First()).Value.GetType())}){(optional ? " [*]" : "")}"); } } return(list); }); var classes = gameObjectGroups .Select(x => { var c = x.Count(); return(new { @class = x.Key, count = c, props = recursivePropertyList(c, x.SelectMany(y => y.Properties.Values), null, new List <string>()).OrderBy(y => y).ToArray() }); }) .OrderBy(x => x.@class).Distinct().ToList(); using (var sw = new StreamWriter(filePath, false)) { var serializer = new JsonSerializer { Formatting = Formatting.Indented }; serializer.Serialize(sw, classes); } }