Beispiel #1
0
        public frmStructureExclusionFilter(ArkGameData gameData)
        {
            InitializeComponent();

            gd = gameData;
            currentExclusions = Program.ProgramConfig.StructureExclusions;

            PopulateStructures();
        }
        public ArkTamedCreature[] GetTamedDinosInMap(string Path)
        {
            GameData = new ArkGameData(@Path, loadOnlyPropertiesInDomain: true);

            if (GameData.Update(CancellationToken.None, deferApplyNewData: true)?.Success == true)
            {
                GameData.ApplyPreviousUpdate();
            }
            return(GameData.TamedCreatures);
        }
        static void Main(string[] args)
        {
            var savePath = @"C:\save\NoHibernation\TheIsland.ark";
            // var savePath = @"C:\save\WithHibernation\TheIsland.ark";
            var clusterPath = @"C:\save\cluster";
            var domainOnly  = true; //true: optimize loading of the domain model, false: load everything and keep references in memory

            //prepare
            var cd = new ArkClusterData(clusterPath, loadOnlyPropertiesInDomain: domainOnly);
            var gd = new ArkGameData(savePath, cd, 1, loadOnlyPropertiesInDomain: domainOnly);

            var st = Stopwatch.StartNew();

            //extract savegame
            if (gd.Update(CancellationToken.None, null, true)?.Success == true)
            {
                Console.WriteLine($@"Elapsed (gd) {st.ElapsedMilliseconds:N0} ms");
                st = Stopwatch.StartNew();

                //extract cluster data: no cluster data exists for singlePlayer
                ArkClusterDataUpdateResult clusterResult;
                if (System.IO.File.Exists(clusterPath))
                {
                    clusterResult = cd.Update(CancellationToken.None);
                }

                Console.WriteLine($@"Elapsed (cd) {st.ElapsedMilliseconds:N0} ms");
                st = Stopwatch.StartNew();

                //assign the new data to the domain model
                gd.ApplyPreviousUpdate(domainOnly);

                Console.WriteLine($@"Elapsed (gd-apply) {st.ElapsedMilliseconds:N0} ms");

                Console.WriteLine("Save data loaded!");
            }
            else
            {
                Console.WriteLine("Failed to load save data!");
            }

            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }
        public frmDinoInventoryViewer(ArkGameData gameData, ArkTamedCreature selectedCreature)
        {
            InitializeComponent();

            currentCreature = selectedCreature;

            string dinoName = selectedCreature.Name != null ? selectedCreature.Name : string.Empty;

            if (dinoName.Length == 0)
            {
                dinoName = selectedCreature.ClassName;
                DinoClassMap classMap = Program.ProgramConfig.DinoMap.Where(d => d.ClassName == selectedCreature.ClassName).FirstOrDefault();
                if (classMap != null && classMap.FriendlyName.Length > 0)
                {
                    dinoName = classMap.FriendlyName;
                }
            }

            lblPlayerName.Text  = dinoName;
            lblPlayerLevel.Text = selectedCreature.Level.ToString();
            lblTribeName.Text   = selectedCreature.TribeName;

            //inventory images
            imageList1.Images.Clear();
            int x = 1;

            while (true)
            {
                Image itemImage = (Image)ARKViewer.Properties.Resources.ResourceManager.GetObject($"item_{x}");
                if (itemImage == null)
                {
                    break;
                }

                imageList1.Images.Add(itemImage);
                x++;
            }

            PopulateCreatureInventory();
        }
        static void Main(string[] args)
        {
            var savePath    = @"C:\save\TheIsland.ark";
            var clusterPath = @"C:\save\cluster";

            //prepare
            var cd = new ArkClusterData(clusterPath);
            var gd = new ArkGameData(savePath, cd);

            var st = Stopwatch.StartNew();

            //extract savegame
            if (gd.Update(CancellationToken.None, null, true)?.Success == true)
            {
                Console.WriteLine($@"Elapsed (gd) {st.ElapsedMilliseconds:N0} ms");
                st = Stopwatch.StartNew();

                //extract cluster data
                var clusterResult = cd.Update(CancellationToken.None);

                Console.WriteLine($@"Elapsed (cd) {st.ElapsedMilliseconds:N0} ms");
                st = Stopwatch.StartNew();

                //assign the new data to the domain model
                gd.ApplyPreviousUpdate(false);

                Console.WriteLine($@"Elapsed (gd-apply) {st.ElapsedMilliseconds:N0} ms");

                Console.WriteLine("Save data loaded!");
            }
            else
            {
                Console.WriteLine("Failed to load save data!");
            }

            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }
Beispiel #6
0
        public frmPlayerInventoryViewer(ArkGameData gameData, List <ItemClassMap> availableItemList, ArkPlayer selectedPlayer)
        {
            InitializeComponent();

            currentPlayer         = selectedPlayer;
            lblPlayerName.Text    = selectedPlayer.CharacterName;
            lblPlayerLevel.Text   = selectedPlayer.CharacterLevel.ToString();
            lblTribeName.Text     = selectedPlayer.Tribe != null ? selectedPlayer.Tribe.Name : "";
            picPlayerGender.Image = selectedPlayer.Gender == ArkPlayerGender.Male ? ARKViewer.Properties.Resources.marker_28 : ARKViewer.Properties.Resources.marker_29;

            lblPlayerId.Text = $"Player Id: {selectedPlayer.Id.ToString()}";

            //inventory images
            itemMapList = availableItemList;
            imageList1.Images.Clear();
            int x = 1;

            while (true)
            {
                Image itemImage = (Image)ARKViewer.Properties.Resources.ResourceManager.GetObject($"item_{x}");
                if (itemImage == null)
                {
                    break;
                }

                imageList1.Images.Add(itemImage);
                x++;
            }

            PopulateMissionScores();

            PopulatePersonalInventory();


            List <ArkTamedCreature> tribeTameList = new List <ArkTamedCreature>();

            if (selectedPlayer.Tribe != null)
            {
                foreach (var player in selectedPlayer.Tribe.Members)
                {
                    var playerTames = gameData.TamedCreatures.Where(s => s.OwningPlayerId == player.Id || s.ImprinterPlayerDataId == player.Id || s.TargetingTeam == player.TribeId).Distinct();
                    if (playerTames != null && playerTames.Count() > 0)
                    {
                        tribeTameList.AddRange(playerTames);
                    }
                }
            }
            else
            {
                //going solo
                var playerTames = gameData.TamedCreatures.Where(s => s.OwningPlayerId == selectedPlayer.Id || s.ImprinterPlayerDataId == selectedPlayer.Id).Distinct();
                if (playerTames != null && playerTames.Count() > 0)
                {
                    tribeTameList.AddRange(playerTames);
                }
            }

            tamedCreatureList = tribeTameList.Distinct().ToList();

            //get a list of tamed dinos

            //get list of tamed dino types
            cboCreatureType.Items.Clear();
            cboCreatureType.Items.Add(new ComboValuePair("", "[All]"));
            if (tamedCreatureList != null && tamedCreatureList.Count > 0)
            {
                var tamedCreatureTypes = tamedCreatureList.GroupBy(t => t.ClassName)
                                         .Select(g => new ComboValuePair()
                {
                    Key = g.Key, Value = (ARKViewer.Program.ProgramConfig.DinoMap.FirstOrDefault(d => d.ClassName == g.Key) == null?g.Key: ARKViewer.Program.ProgramConfig.DinoMap.First(d => d.ClassName == g.Key).FriendlyName)
                })
                                         .OrderBy(o => o.Value);

                cboCreatureType.Items.AddRange(tamedCreatureTypes.ToArray());
            }
            cboCreatureType.SelectedIndex = 0;


            //get list of inventory containers
            tribeStructureList = new List <ArkStructure>();
            List <ArkItem> tribeStructures = new List <ArkItem>();

            if (selectedPlayer.Tribe != null)
            {
                foreach (var player in selectedPlayer.Tribe.Members)
                {
                    var playerStructures = gameData.Structures.Where(s => s.Inventory != null && s.Inventory.Count() > 0 && (s.OwningPlayerId == player.Id || s.TargetingTeam == player.TribeId));
                    if (playerStructures != null && playerStructures.Count() > 0)
                    {
                        tribeStructureList.AddRange(playerStructures);
                    }
                }
            }
            else
            {
                //going solo
                if (selectedPlayer.Inventory != null && selectedPlayer.Inventory.Count() > 0)
                {
                    var playerStructures = gameData.Structures.Where(s => s.Inventory != null && s.Inventory.Count() > 0 && (s.OwningPlayerId == selectedPlayer.Id));
                    if (playerStructures != null && playerStructures.Count() > 0)
                    {
                        foreach (var structureInv in playerStructures)
                        {
                            tribeStructureList.AddRange(playerStructures);
                        }
                    }
                }
            }


            var containerTypes = tribeStructureList.GroupBy(s => s.ClassName)
                                 .Select(g => new ComboValuePair()
            {
                Key = g.Key, Value = (ARKViewer.Program.ProgramConfig.StructureMap.FirstOrDefault(d => d.ClassName == g.Key) == null ? g.Key: ARKViewer.Program.ProgramConfig.StructureMap.First(d => d.ClassName == g.Key).FriendlyName)
            })
                                 .OrderBy(o => o.Value);

            cboStorageType.Items.Clear();
            cboStorageType.Items.Add(new ComboValuePair("", "[All]"));
            cboStorageType.Items.AddRange(containerTypes.ToArray());
            cboStorageType.SelectedIndex = 0;
        }
Beispiel #7
0
        public frmStructureLocations(ArkGameData gameData, string className, string title, Image icon)
        {
            InitializeComponent();

            lblType.Text  = title;
            picType.Image = icon;

            lvwMapMarkers.Items.Clear();

            var structureList = gameData.Structures.Where(s => s.ClassName.StartsWith(className));

            foreach (var structure in structureList)
            {
                ListViewItem newItem = lvwMapMarkers.Items.Add(structure.Location.Latitude.Value.ToString("0.00"));
                newItem.SubItems.Add(structure.Location.Longitude.Value.ToString("0.00"));
                newItem.Tag = structure;


                if (structure.ClassName == "RockDrakeNest_C")
                {
                    ArkItem fertileEgg = gameData.Items.Where(i => i.ClassName == "PrimalItemConsumable_Egg_RockDrake_Fertilized_C" && i.Location != null && i.Location.Latitude.Value.ToString("0.00").Equals(structure.Location.Latitude.Value.ToString("0.00")) && i.Location.Longitude.Value.ToString("0.00").Equals(structure.Location.Longitude.Value.ToString("0.00")) && i.OwnerInventoryId == null).FirstOrDefault();
                    if (fertileEgg != null)
                    {
                        newItem.BackColor   = Color.LightGreen;
                        newItem.ToolTipText = $"{fertileEgg.CustomDescription}";
                    }
                }
                else if (structure.ClassName == "DeinonychusNest_C")
                {
                    ArkItem fertileEgg = gameData.Items.Where(i => i.ClassName == "PrimalItemConsumable_Egg_Deinonychus_Fertilized_C" && i.Location != null && i.Location.Latitude.Value.ToString("0.00").Equals(structure.Location.Latitude.Value.ToString("0.00")) && i.Location.Longitude.Value.ToString("0.00").Equals(structure.Location.Longitude.Value.ToString("0.00")) && i.OwnerInventoryId == null).FirstOrDefault();
                    if (fertileEgg != null)
                    {
                        newItem.BackColor   = Color.LightGreen;
                        newItem.ToolTipText = $"{fertileEgg.CustomDescription}";
                    }
                }
                else if (structure.ClassName == "CherufeNest_C")
                {
                    ArkItem fertileEgg = gameData.Items.Where(i => i.ClassName == "PrimalItemConsumable_Egg_Cherufe_Fertilized_C" && i.Location != null && (Math.Abs(Math.Round(i.Location.Latitude.Value, 1) - Math.Round(structure.Location.Latitude.Value, 1)) <= 0.2) && (Math.Abs(Math.Round(i.Location.Longitude.Value, 1) - Math.Round(structure.Location.Longitude.Value, 1)) <= 0.2) && i.OwnerInventoryId == null && usedEggs.LongCount(e => e.Id == i.Id) == 0).FirstOrDefault();
                    if (fertileEgg != null)
                    {
                        usedEggs.Add(fertileEgg);
                        newItem.BackColor   = Color.LightGreen;
                        newItem.ToolTipText = $"{fertileEgg.CustomDescription}";
                    }
                }
                else if (structure.ClassName.StartsWith("WyvernNest_"))
                {
                    var fertileEggs = gameData.Items.Where(i => i.ClassName.ToLower().Contains("egg") && i.Location != null && i.Location.Latitude.Value.ToString("0.00").Equals(structure.Location.Latitude.Value.ToString("0.00")) && i.Location.Longitude.Value.ToString("0.00").Equals(structure.Location.Longitude.Value.ToString("0.00")) && i.OwnerInventoryId == null);
                    if (fertileEggs != null && fertileEggs.Count() > 0)
                    {
                        newItem.BackColor   = Color.LightGreen;
                        newItem.ToolTipText = $"{fertileEggs.First().CustomDescription}";
                    }
                }
                else
                {
                    if (structure.Inventory != null)
                    {
                        //tooltip the inventory contents
                        var itemSummary = structure.Inventory.Where(s => s.ClassName != "PrimalItem_PowerNodeCharge_C").GroupBy(i => i.ClassName).Select(g => new { ClassName = g.Key, FriendlyName = Program.ProgramConfig.ItemMap.Count(im => im.ClassName == g.Key) > 0 ? Program.ProgramConfig.ItemMap.FirstOrDefault(im => im.ClassName == g.Key).FriendlyName : g.Key, Quantity = g.Sum(s => s.Quantity) });
                        if (itemSummary != null && itemSummary.Count() > 0)
                        {
                            newItem.BackColor = Color.LightGreen;

                            string tooltipText = "";
                            foreach (var summary in itemSummary)
                            {
                                if (tooltipText.Length != 0)
                                {
                                    tooltipText = $"{tooltipText}\n";
                                }

                                string summaryText = $"{summary.FriendlyName} x {summary.Quantity.ToString()}";
                                tooltipText = $"{tooltipText}{summaryText}";
                            }

                            newItem.ToolTipText = tooltipText;
                        }
                    }
                }
            }
        }
Beispiel #8
0
        private void SendAnnouncement()
        {
            if (string.IsNullOrWhiteSpace(ClusterFolder) || string.IsNullOrWhiteSpace(SaveFilePath))
            {
                MessageBox.Show("You must select both a cluster folder and a save file path.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (string.IsNullOrWhiteSpace(txtWebhookID.Text) || string.IsNullOrWhiteSpace(txtWebhookToken.Text) || !IsInt(txtWebhookID.Text))
            {
                MessageBox.Show("Invalid Webhook data. ID must be an integer and both fields must have an entry.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            client = new Discord.Webhook.DiscordWebhookClient(Convert.ToUInt64(txtWebhookID.Text), txtWebhookToken.Text);

            var cd = new ArkClusterData(ClusterFolder, loadOnlyPropertiesInDomain: true);
            var gd = new ArkGameData(SaveFilePath, cd, loadOnlyPropertiesInDomain: true);

            //extract savegame
            var upd = gd.Update(CancellationToken.None, deferApplyNewData: true);

            if (upd == null)
            {
                return;
            }
            if (upd.Success == true)
            {
                //extract cluster data
                var cr = cd.Update(CancellationToken.None);

                //assign the new data to the domain model
                gd.ApplyPreviousUpdate();

                // Populate Wild dinos
                var wildDinos = gd.WildCreatures;

                // init message
                var message = @"```autohotkey" + Environment.NewLine;

                // Go through entries
                foreach (DataGridViewRow row in dgvTrackList.Rows)
                {
                    if (string.IsNullOrWhiteSpace(row.Cells[0].Value.ToString()) || string.IsNullOrWhiteSpace(row.Cells[1].Value.ToString()))
                    {
                        MessageBox.Show("Incomplete Data", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    var dType        = row.Cells[0].Value.ToString();
                    var searchString = row.Cells[1].Value.ToString();

                    //init controllers
                    var foundDinos = false;

                    // Get desired Dinos
                    var queriedDinos = new List <ArkWildCreature>();
                    queriedDinos = wildDinos.Where(q => q.ClassName.Contains(searchString)).ToList();

                    // Discord
                    if (queriedDinos.Count > 0)
                    {
                        foundDinos = true;
                        message   += $"{dType} sightings on " + queriedDinos.First().Location.MapName + ":" + Environment.NewLine;

                        message += $"_{"_______",-7}_{"________________",-16}_{"_______",-7}_{"_________",-9}_" + Environment.NewLine;
                        message += $"|{"Gender",-7}|{"Type",-16}|{"Level",-7}|{"Location",-9}|" + Environment.NewLine;
                        message += $"|{"_______",-7}|{"________________",-16}|{"_______",-7}|{"_________",-9}|" + Environment.NewLine;
                        foreach (var dino in queriedDinos)
                        {
                            var gender = $" {dino.Gender.ToString()}";
                            var name   = $" {dino.ClassName.Split('_').First()}";
                            var level  = $" {dino.BaseLevel.ToString()}";
                            var loc    = $" {dino.Location.Latitude.Value.ToString("N0", CultureInfo.InvariantCulture)}, { dino.Location.Latitude.Value.ToString("N0", CultureInfo.InvariantCulture)}";
                            message += $"|{gender,-7}|{name,-16}|{level,-7}|{loc,-9}|" + Environment.NewLine;
                        }
                        message += $"|{"_______",-7}|{"________________",-16}|{"_______",-7}|{"_________",-9}|" + Environment.NewLine;
                    }

                    if (MessageTooLong)
                    {
                        message += Environment.NewLine + "```";
                        client.SendMessageAsync(message).Wait();
                        MessageFragsSent = true;
                        message          = @"```autohotkey" + Environment.NewLine;
                    }

                    if (!MessageTooLong && foundDinos && row.Index < dgvTrackList.RowCount)
                    {
                        message += Environment.NewLine + Environment.NewLine + Environment.NewLine;
                    }
                }

                MessageTooLong = message.Length >= 2000 && !MessageFragsSent;

                if (MessageTooLong)
                {
                    SendAnnouncement();
                    MessageTooLong = false;
                }
                else if (!MessageTooLong && !MessageFragsSent)
                {
                    message += Environment.NewLine + "```";
                    client.SendMessageAsync(message).Wait();
                }

                MessageTooLong   = false;
                MessageFragsSent = false;
            }
        }
Beispiel #9
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);


            Application.ThreadException += Application_ThreadException;
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            ProgramConfig = new ViewerConfiguration();

            string     logFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"ARKViewer.log");
            TextWriter logWriter   = null;

            //support quoted command line arguments which doesn't seem to be supported with Environment.GetCommandLineArgs()
            string[] commandArguments = Regex.Split(Environment.CommandLine.Trim(), " (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");

            //remove empty argument entries
            commandArguments = commandArguments.Where(a => string.IsNullOrEmpty(a) == false).ToArray();
            if (commandArguments.Length > 0)
            {
                logWriter = new StreamWriter(logFilename);
                logWriter.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} - ArkViewer Command Line Started: {commandArguments.Length}");

                int argIndex = 0;
                foreach (string arg in commandArguments)
                {
                    logWriter.WriteLine($"\tArg-{argIndex} = {arg}");
                    argIndex++;
                }
            }
            if (commandArguments != null && commandArguments.Length > 1)
            {
                //command line, load save game data for export
                string savePath     = "";
                string saveFilename = "";
                bool   shouldSort   = ProgramConfig.SortCommandLineExport;


                if (commandArguments.Length > 3)
                {
                    //ark save game specified
                    saveFilename = commandArguments[3].ToString().Trim().Replace("\"", "");
                    savePath     = Path.GetDirectoryName(saveFilename);
                }
                else
                {
                    //use last configured save
                    switch (ARKViewer.Program.ProgramConfig.Mode)
                    {
                    case ViewerModes.Mode_SinglePlayer:
                        if (ARKViewer.Program.ProgramConfig.SelectedFile.Length > 0)
                        {
                            savePath     = Path.GetFullPath(ARKViewer.Program.ProgramConfig.SelectedFile);
                            saveFilename = ARKViewer.Program.ProgramConfig.SelectedFile;
                        }

                        break;

                    case ViewerModes.Mode_Offline:
                        if (ARKViewer.Program.ProgramConfig.SelectedFile.Length > 0)
                        {
                            savePath     = Path.GetFullPath(ARKViewer.Program.ProgramConfig.SelectedFile);
                            saveFilename = ARKViewer.Program.ProgramConfig.SelectedFile;
                        }
                        break;

                    case ViewerModes.Mode_Ftp:
                        savePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), ARKViewer.Program.ProgramConfig.SelectedServer);

                        if (ARKViewer.Program.ProgramConfig.SelectedFile.Length > 0)
                        {
                            saveFilename = Path.Combine(savePath, ARKViewer.Program.ProgramConfig.SelectedFile);
                        }
                        break;

                    default:

                        break;
                    }
                }


                if (File.Exists(saveFilename))
                {
                    try
                    {
                        ArkGameData      gd         = new ArkGameData(saveFilename, loadOnlyPropertiesInDomain: false);
                        List <TribeMap>  allTribes  = new List <TribeMap>();
                        List <PlayerMap> allPlayers = new List <PlayerMap>();

                        if (gd.Update(CancellationToken.None, null, true)?.Success == true)
                        {
                            gd.ApplyPreviousUpdate();

                            //get structures
                            if (commandArguments[1].ToString().Trim().ToLower() == "structures" || commandArguments[1].ToString().Trim().ToLower() == "tribes" || commandArguments[1].ToString().Trim().ToString() == "all")
                            {
                                if (gd.Structures != null && gd.Structures.Count() > 0)
                                {
                                    var structureTribes = gd.Structures.Where(s => s.OwnerName != null && s.TargetingTeam.GetValueOrDefault(0) != 0).Select(s => new TribeMap()
                                    {
                                        TribeId = s.TargetingTeam.GetValueOrDefault(0), TribeName = s.OwnerName
                                    }).Distinct().ToList();

                                    if (structureTribes != null)
                                    {
                                        if (gd.Tribes != null && gd.Tribes.Count() > 0)
                                        {
                                            var serverTribes = gd.Tribes.Where(t => structureTribes.LongCount(s => s.TribeId == t.Id) == 0 && t.Id != 0)
                                                               .Select(i => new TribeMap()
                                            {
                                                TribeId = i.Id, TribeName = i.Name, ContainsLog = i.Logs.Count() > 0
                                            });

                                            if (serverTribes != null)
                                            {
                                                structureTribes.AddRange(serverTribes.ToArray());
                                            }
                                        }
                                        allTribes = structureTribes.Distinct().ToList();
                                    }
                                    else
                                    {
                                        if (gd.Tribes != null && gd.Tribes.Count() > 0)
                                        {
                                            var serverTribes = gd.Tribes.Where(t => structureTribes.LongCount(s => s.TribeId == t.Id) == 0)
                                                               .Select(i => new TribeMap()
                                            {
                                                TribeId = i.Id, TribeName = i.Name
                                            });

                                            allTribes = serverTribes.Distinct().ToList();
                                        }
                                    }

                                    if (gd.Players != null && gd.Players.Count() > 0)
                                    {
                                        var serverPlayers = gd.Players.Select(i => new PlayerMap()
                                        {
                                            TribeId = (long)i.TribeId.GetValueOrDefault(0), PlayerId = (long)i.Id, PlayerName = i.CharacterName != null ? i.CharacterName : i.Name
                                        });
                                        if (serverPlayers != null)
                                        {
                                            foreach (var serverPlayer in serverPlayers.Where(p => p.TribeId == 0))
                                            {
                                                var testTribe = gd.Tribes.Where(t => t.MemberIds.Contains((int)serverPlayer.PlayerId)).FirstOrDefault();
                                                if (testTribe != null)
                                                {
                                                    serverPlayer.TribeId = testTribe.Id;
                                                }
                                            }

                                            allPlayers = serverPlayers.Where(p => p.TribeId != 0).ToList();
                                        }
                                    }

                                    var structurePlayers = gd.Structures.Where(s => s.TargetingTeam.GetValueOrDefault(0) != 0 && s.OwningPlayerName != null && allPlayers.LongCount(c => c.PlayerId == s.OwningPlayerId) == 0).Select(s => new PlayerMap()
                                    {
                                        TribeId = s.TargetingTeam.Value, PlayerId = (long)s.OwningPlayerId, PlayerName = s.OwningPlayerName
                                    }).Distinct().OrderBy(o => o.PlayerName).ToList();
                                    if (structurePlayers != null && structurePlayers.Count() > 0)
                                    {
                                        allPlayers.AddRange(structurePlayers.ToArray());
                                    }


                                    foreach (var tribe in allTribes)
                                    {
                                        int playerCount      = allPlayers.Count(p => p.TribeId == tribe.TribeId);
                                        int tribePlayerCount = gd.Tribes.Where(t => t.Id == tribe.TribeId).Select(m => m.Members).Count();

                                        tribe.PlayerCount    = playerCount > tribePlayerCount ? playerCount : tribePlayerCount;
                                        tribe.StructureCount = gd.Structures.LongCount(s => s.TargetingTeam.GetValueOrDefault(0) == tribe.TribeId);
                                        tribe.TameCount      = gd.TamedCreatures.LongCount(t => t.TargetingTeam == tribe.TribeId);

                                        var tribeTames = gd.NoRafts.Where(t => t.TargetingTeam == tribe.TribeId);
                                        if (tribeTames != null && tribeTames.Count() > 0)
                                        {
                                            TimeSpan noTime = new TimeSpan();

                                            var lastTamedCreature = tribeTames.Where(t => t.TamedAtTime != null).OrderBy(o => o?.TamedForApprox.GetValueOrDefault(noTime).TotalSeconds).FirstOrDefault();
                                            if (lastTamedCreature != null)
                                            {
                                                var tamedTime = lastTamedCreature.TamedForApprox.GetValueOrDefault(noTime);
                                                tribe.LastActive = DateTime.Now.Subtract(tamedTime);
                                            }
                                        }
                                        if (gd.Players != null && gd.Players.Count() > 0)
                                        {
                                            var tribePlayers = gd.Players.Where(p => p.TribeId == tribe.TribeId);
                                            if (tribePlayers != null && tribePlayers.Count() > 0)
                                            {
                                                var lastActivePlayer = tribePlayers.OrderBy(p => p.LastActiveTime).First();
                                                if (lastActivePlayer.LastActiveTime > tribe.LastActive)
                                                {
                                                    tribe.LastActive = lastActivePlayer.LastActiveTime;
                                                }
                                            }
                                        }

                                        if (gd.Tribes != null && gd.Tribes.Count() > 0)
                                        {
                                            var actualTribe = gd.Tribes.FirstOrDefault(t => t.Id == tribe.TribeId);
                                            if (actualTribe != null)
                                            {
                                                if (actualTribe.LastActiveTime > tribe.LastActive)
                                                {
                                                    tribe.LastActive = actualTribe.LastActiveTime;
                                                    tribe.TribeName  = actualTribe.Name;
                                                }
                                                //error reported by @mjfro2 - crash when tribe has no log data
                                                long logCount = actualTribe.Logs == null ? 0 : actualTribe.Logs.Count();
                                                tribe.ContainsLog = logCount > 0;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            gd = null;
                        }

                        string exportFilePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                        string exportFilename = "";

                        string commandOptionCheck = commandArguments[1].ToString().Trim().ToLower();

                        if (commandArguments.Length > 2)
                        {
                            //export filename
                            exportFilename = commandArguments[2].ToString().Trim().Replace("\"", "");

                            //use path only if "all"
                            if (commandOptionCheck == "all")
                            {
                                exportFilePath = Path.GetDirectoryName(exportFilename);
                                exportFilename = "";
                            }
                        }

                        if (commandOptionCheck == "wild" || commandOptionCheck == "all")
                        {
                            //Wild
                            exportFilename = exportFilename.Length > 0 ? exportFilename : Path.Combine(exportFilePath, "ARKViewer_Export_Wild.json");

                            using (FileStream fs = File.Create(exportFilename))
                            {
                                using (StreamWriter sw = new StreamWriter(fs))
                                {
                                    using (JsonTextWriter jw = new JsonTextWriter(sw))
                                    {
                                        var creatureList = shouldSort ? gd.WildCreatures.OrderBy(o => o.ClassName).Cast <ArkWildCreature>() : gd.WildCreatures;

                                        jw.WriteStartArray();

                                        //Creature, Sex, Lvl, Lat, Lon, HP, Stam, Weight, Speed, Food, Oxygen, Craft, C0, C1, C2, C3, C4, C5
                                        foreach (var creature in creatureList)
                                        {
                                            jw.WriteStartObject();

                                            jw.WritePropertyName("id");
                                            jw.WriteValue(creature.Id);

                                            jw.WritePropertyName("creature");
                                            jw.WriteValue(creature.ClassName);

                                            jw.WritePropertyName("sex");
                                            jw.WriteValue(creature.Gender);

                                            jw.WritePropertyName("lvl");
                                            jw.WriteValue(creature.BaseLevel);

                                            jw.WritePropertyName("lat");
                                            if (creature.Location != null && creature.Location.Latitude != null)
                                            {
                                                jw.WriteValue(creature.Location.Latitude);
                                            }
                                            else
                                            {
                                                jw.WriteValue(0);
                                            }

                                            jw.WritePropertyName("lon");
                                            if (creature.Location != null && creature.Location.Longitude != null)
                                            {
                                                jw.WriteValue(creature.Location.Longitude);
                                            }
                                            else
                                            {
                                                jw.WriteValue(0);
                                            }

                                            jw.WritePropertyName("hp");
                                            jw.WriteValue(creature.BaseStats[0]);

                                            jw.WritePropertyName("stam");
                                            jw.WriteValue(creature.BaseStats[1]);

                                            jw.WritePropertyName("melee");
                                            jw.WriteValue(creature.BaseStats[8]);

                                            jw.WritePropertyName("weight");
                                            jw.WriteValue(creature.BaseStats[7]);

                                            jw.WritePropertyName("speed");
                                            jw.WriteValue(creature.BaseStats[9]);

                                            jw.WritePropertyName("food");
                                            jw.WriteValue(creature.BaseStats[4]);

                                            jw.WritePropertyName("oxy");
                                            jw.WriteValue(creature.BaseStats[3]);

                                            jw.WritePropertyName("craft");
                                            jw.WriteValue(creature.BaseStats[11]);

                                            jw.WritePropertyName("c0");
                                            jw.WriteValue(creature.Colors[0]);

                                            jw.WritePropertyName("c1");
                                            jw.WriteValue(creature.Colors[1]);

                                            jw.WritePropertyName("c2");
                                            jw.WriteValue(creature.Colors[2]);

                                            jw.WritePropertyName("c3");
                                            jw.WriteValue(creature.Colors[3]);

                                            jw.WritePropertyName("c4");
                                            jw.WriteValue(creature.Colors[4]);

                                            jw.WritePropertyName("c5");
                                            jw.WriteValue(creature.Colors[5]);

                                            jw.WritePropertyName("ccc");
                                            if (creature.Location != null)
                                            {
                                                jw.WriteValue($"{creature.Location.X} {creature.Location.Y} {creature.Location.Z}");
                                            }
                                            else
                                            {
                                                jw.WriteValue("");
                                            }

                                            jw.WriteEnd();
                                        }

                                        jw.WriteEndArray();
                                    }
                                }
                            }
                        }
                        if (commandOptionCheck == "tamed" || commandOptionCheck == "all")
                        {
                            //Tamed
                            exportFilename = exportFilename.Length > 0 && commandOptionCheck != "all" ? exportFilename : Path.Combine(exportFilePath, "ARKViewer_Export_Tamed.json");

                            using (FileStream fs = File.Create(exportFilename))
                            {
                                using (StreamWriter sw = new StreamWriter(fs))
                                {
                                    using (JsonTextWriter jw = new JsonTextWriter(sw))
                                    {
                                        var creatureList = shouldSort ? gd.TamedCreatures.OrderBy(o => o.ClassName).Cast <ArkTamedCreature>() : gd.TamedCreatures;

                                        jw.WriteStartArray();

                                        foreach (var creature in creatureList)
                                        {
                                            jw.WriteStartObject();
                                            jw.WritePropertyName("id");
                                            jw.WriteValue(creature.Id);

                                            jw.WritePropertyName("tribeid");
                                            jw.WriteValue(creature.TargetingTeam);

                                            jw.WritePropertyName("tribe");
                                            jw.WriteValue(creature.TribeName);

                                            jw.WritePropertyName("tamer");
                                            jw.WriteValue(creature.TamerName);

                                            jw.WritePropertyName("imprinter");
                                            jw.WriteValue(creature.ImprinterName);


                                            jw.WritePropertyName("imprint");
                                            jw.WriteValue(creature.DinoImprintingQuality);

                                            jw.WritePropertyName("creature");
                                            jw.WriteValue(creature.ClassName);

                                            jw.WritePropertyName("name");
                                            jw.WriteValue(creature.Name != null ? creature.Name : "");


                                            jw.WritePropertyName("sex");
                                            jw.WriteValue(creature.Gender);

                                            jw.WritePropertyName("base");
                                            jw.WriteValue(creature.BaseLevel);


                                            jw.WritePropertyName("lvl");
                                            jw.WriteValue(creature.Level);

                                            jw.WritePropertyName("lat");
                                            if (creature.Location != null && creature.Location.Latitude != null)
                                            {
                                                jw.WriteValue(creature.Location.Latitude);
                                            }
                                            else
                                            {
                                                jw.WriteValue(0);
                                            }

                                            jw.WritePropertyName("lon");
                                            if (creature.Location != null && creature.Location.Longitude != null)
                                            {
                                                jw.WriteValue(creature.Location.Longitude);
                                            }
                                            else
                                            {
                                                jw.WriteValue(0);
                                            }

                                            jw.WritePropertyName("hp-w");
                                            jw.WriteValue(creature.BaseStats[0]);

                                            jw.WritePropertyName("stam-w");
                                            jw.WriteValue(creature.BaseStats[1]);

                                            jw.WritePropertyName("melee-w");
                                            jw.WriteValue(creature.BaseStats[8]);

                                            jw.WritePropertyName("weight-w");
                                            jw.WriteValue(creature.BaseStats[7]);

                                            jw.WritePropertyName("speed-w");
                                            jw.WriteValue(creature.BaseStats[9]);

                                            jw.WritePropertyName("food-w");
                                            jw.WriteValue(creature.BaseStats[4]);

                                            jw.WritePropertyName("oxy-w");
                                            jw.WriteValue(creature.BaseStats[3]);

                                            jw.WritePropertyName("craft-w");
                                            jw.WriteValue(creature.BaseStats[11]);

                                            jw.WritePropertyName("hp-t");
                                            jw.WriteValue(creature.TamedStats[0]);

                                            jw.WritePropertyName("stam-t");
                                            jw.WriteValue(creature.TamedStats[1]);

                                            jw.WritePropertyName("melee-t");
                                            jw.WriteValue(creature.TamedStats[8]);

                                            jw.WritePropertyName("weight-t");
                                            jw.WriteValue(creature.TamedStats[7]);

                                            jw.WritePropertyName("speed-t");
                                            jw.WriteValue(creature.TamedStats[9]);

                                            jw.WritePropertyName("food-t");
                                            jw.WriteValue(creature.TamedStats[4]);

                                            jw.WritePropertyName("oxy-t");
                                            jw.WriteValue(creature.TamedStats[3]);

                                            jw.WritePropertyName("craft-t");
                                            jw.WriteValue(creature.TamedStats[11]);


                                            jw.WritePropertyName("c0");
                                            jw.WriteValue(creature.Colors[0]);

                                            jw.WritePropertyName("c1");
                                            jw.WriteValue(creature.Colors[1]);

                                            jw.WritePropertyName("c2");
                                            jw.WriteValue(creature.Colors[2]);

                                            jw.WritePropertyName("c3");
                                            jw.WriteValue(creature.Colors[3]);

                                            jw.WritePropertyName("c4");
                                            jw.WriteValue(creature.Colors[4]);

                                            jw.WritePropertyName("c5");
                                            jw.WriteValue(creature.Colors[5]);

                                            jw.WritePropertyName("mut-f");
                                            jw.WriteValue(creature.RandomMutationsFemale);

                                            jw.WritePropertyName("mut-m");
                                            jw.WriteValue(creature.RandomMutationsMale);

                                            jw.WritePropertyName("cryo");
                                            jw.WriteValue(creature.IsCryo);

                                            jw.WritePropertyName("viv");
                                            jw.WriteValue(creature.IsVivarium);

                                            jw.WritePropertyName("ccc");
                                            if (creature.Location != null)
                                            {
                                                jw.WriteValue($"{creature.Location.X} {creature.Location.Y} {creature.Location.Z}");
                                            }
                                            else
                                            {
                                                jw.WriteValue("");
                                            }

                                            jw.WriteEnd();
                                        }

                                        jw.WriteEndArray();
                                    }
                                }
                            }
                        }

                        if (commandOptionCheck == "structures" || commandOptionCheck == "all")
                        {
                            //Structures
                            exportFilename = exportFilename.Length > 0 && commandOptionCheck != "all" ? exportFilename : Path.Combine(exportFilePath, "ARKViewer_Export_Structures.json");

                            //Player, Tribe, Structure, Lat, Lon
                            using (FileStream fs = File.Create(exportFilename))
                            {
                                using (StreamWriter sw = new StreamWriter(fs))
                                {
                                    using (JsonTextWriter jw = new JsonTextWriter(sw))
                                    {
                                        jw.WriteStartArray();

                                        foreach (var structure in gd.Structures)
                                        {
                                            jw.WriteStartObject();

                                            jw.WritePropertyName("tribeid");
                                            jw.WriteValue(structure.TargetingTeam.GetValueOrDefault(0));

                                            jw.WritePropertyName("playerid");
                                            if (structure.OwningPlayerId == structure.TargetingTeam.GetValueOrDefault(0))
                                            {
                                                jw.WriteValue(0);
                                            }
                                            else
                                            {
                                                jw.WriteValue(structure.OwningPlayerId.GetValueOrDefault(0));
                                            }


                                            jw.WritePropertyName("tribe");
                                            if (allTribes.Count(t => t.TribeId == structure.TargetingTeam.GetValueOrDefault(0)) > 0)
                                            {
                                                jw.WriteValue(allTribes.First(t => t.TribeId == structure.TargetingTeam.GetValueOrDefault(0)).TribeName);
                                            }
                                            else
                                            {
                                                jw.WriteValue("");
                                            }


                                            jw.WritePropertyName("player");
                                            jw.WriteValue(structure.OwningPlayerName == "null" ? "" : structure.OwningPlayerName);

                                            jw.WritePropertyName("struct");
                                            jw.WriteValue(structure.ClassName);

                                            jw.WritePropertyName("lat");
                                            if (structure.Location != null && structure.Location.Latitude != null)
                                            {
                                                jw.WriteValue(structure.Location.Latitude);
                                            }
                                            else
                                            {
                                                jw.WriteValue(0);
                                            }


                                            jw.WritePropertyName("lon");
                                            if (structure.Location != null && structure.Location.Longitude != null)
                                            {
                                                jw.WriteValue(structure.Location.Longitude);
                                            }
                                            else
                                            {
                                                jw.WriteValue(0);
                                            }

                                            jw.WritePropertyName("ccc");
                                            if (structure.Location != null)
                                            {
                                                jw.WriteValue($"{structure.Location.X} {structure.Location.Y} {structure.Location.Z}");
                                            }
                                            else
                                            {
                                                jw.WriteValue("");
                                            }


                                            jw.WriteEnd();
                                        }

                                        jw.WriteEndArray();
                                    }
                                }
                            }
                        }


                        if (commandOptionCheck == "tribes" || commandOptionCheck == "all")
                        {
                            //Tribes
                            exportFilename = exportFilename.Length > 0 && commandOptionCheck != "all" ? exportFilename : Path.Combine(exportFilePath, "ARKViewer_Export_Tribes.json");

                            //Id, Name, Players, Tames, Structures, Last Active
                            using (FileStream fs = File.Create(exportFilename))
                            {
                                using (StreamWriter sw = new StreamWriter(fs))
                                {
                                    using (JsonTextWriter jw = new JsonTextWriter(sw))
                                    {
                                        jw.WriteStartArray();

                                        foreach (var playerTribe in allTribes)
                                        {
                                            jw.WriteStartObject();

                                            jw.WritePropertyName("tribeid");
                                            jw.WriteValue(playerTribe.TribeId);

                                            jw.WritePropertyName("tribe");
                                            jw.WriteValue(playerTribe.TribeName);

                                            jw.WritePropertyName("players");
                                            jw.WriteValue(playerTribe.PlayerCount);

                                            jw.WritePropertyName("tames");
                                            jw.WriteValue(playerTribe.TameCount);

                                            jw.WritePropertyName("structures");
                                            jw.WriteValue(playerTribe.StructureCount);

                                            jw.WritePropertyName("active");
                                            jw.WriteValue(playerTribe.LastActive);


                                            jw.WriteEnd();
                                        }

                                        jw.WriteEndArray();
                                    }
                                }
                            }
                        }


                        if (commandOptionCheck == "all" || commandOptionCheck == "players")
                        {
                            //Players
                            exportFilename = exportFilename.Length > 0 && commandOptionCheck != "all" ? exportFilename : Path.Combine(exportFilePath, "ARKViewer_Export_Players.json");

                            //Id, Name, Tribe, Sex, Lvl, Lat, Lon, HP, Stam, Melee, Weight, Speed, Food, Water, Oxygen, Crafting, Fortitude, Steam, Last Online
                            using (FileStream fs = File.Create(exportFilename))
                            {
                                using (StreamWriter sw = new StreamWriter(fs))
                                {
                                    using (JsonTextWriter jw = new JsonTextWriter(sw))
                                    {
                                        jw.WriteStartArray();

                                        foreach (var player in gd.Players)
                                        {
                                            jw.WriteStartObject();

                                            jw.WritePropertyName("playerid");
                                            jw.WriteValue(player.Id);

                                            jw.WritePropertyName("steam");
                                            jw.WriteValue(player.Name);

                                            jw.WritePropertyName("name");
                                            jw.WriteValue(player.CharacterName);

                                            jw.WritePropertyName("tribeid");
                                            jw.WriteValue(player.TribeId);

                                            jw.WritePropertyName("tribe");
                                            if (player.Tribe != null && player.Tribe.Name != null)
                                            {
                                                jw.WriteValue(player.Tribe.Name);
                                            }
                                            else
                                            {
                                                jw.WriteValue("");
                                            }

                                            jw.WritePropertyName("sex");
                                            jw.WriteValue(player.Gender);

                                            jw.WritePropertyName("lvl");
                                            jw.WriteValue(player.CharacterLevel);

                                            jw.WritePropertyName("lat");
                                            if (player.Location != null)
                                            {
                                                jw.WriteValue(player.Location.Latitude);
                                            }
                                            else
                                            {
                                                jw.WriteValue(0);
                                            }

                                            jw.WritePropertyName("lon");
                                            if (player.Location != null)
                                            {
                                                jw.WriteValue(player.Location.Longitude);
                                            }
                                            else
                                            {
                                                jw.WriteValue(0);
                                            }


                                            //0=health
                                            //1=stamina
                                            //2=torpor
                                            //3=oxygen
                                            //4=food
                                            //5=water
                                            //6=temperature
                                            //7=weight
                                            //8=melee damage
                                            //9=movement speed
                                            //10=fortitude
                                            //11=crafting speed
                                            jw.WritePropertyName("hp");
                                            jw.WriteValue(player.Stats[0]);

                                            jw.WritePropertyName("stam");
                                            jw.WriteValue(player.Stats[1]);

                                            jw.WritePropertyName("melee");
                                            jw.WriteValue(player.Stats[8]);

                                            jw.WritePropertyName("weight");
                                            jw.WriteValue(player.Stats[7]);

                                            jw.WritePropertyName("speed");
                                            jw.WriteValue(player.Stats[9]);

                                            jw.WritePropertyName("food");
                                            jw.WriteValue(player.Stats[4]);

                                            jw.WritePropertyName("water");
                                            jw.WriteValue(player.Stats[5]);

                                            jw.WritePropertyName("oxy");
                                            jw.WriteValue(player.Stats[3]);

                                            jw.WritePropertyName("craft");
                                            jw.WriteValue(player.Stats[11]);

                                            jw.WritePropertyName("fort");
                                            jw.WriteValue(player.Stats[10]);

                                            jw.WritePropertyName("active");
                                            jw.WriteValue(player.LastActiveTime);

                                            jw.WritePropertyName("ccc");
                                            if (player.Location != null)
                                            {
                                                jw.WriteValue($"{player.Location.X} {player.Location.Y} {player.Location.Z}");
                                            }
                                            else
                                            {
                                                jw.WriteValue("");
                                            }


                                            jw.WriteEnd();
                                        }

                                        jw.WriteEndArray();
                                    }
                                }
                            }
                        }

                        //success
                        Environment.ExitCode = 0;
                    }
                    catch (Exception ex)
                    {
                        string traceLog     = ex.StackTrace;
                        string errorMessage = ex.Message;

                        try
                        {
                            StringBuilder errorData = new StringBuilder();

                            errorData.AppendLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                            errorData.AppendLine($"Error: {errorMessage}");
                            errorData.AppendLine($"Trace: {traceLog}");
                            errorData.AppendLine("");
                            if (logWriter == null)
                            {
                                logWriter = new StreamWriter(logFilename);
                            }
                            logWriter.Write(errorData.ToString());
                        }
                        catch
                        {
                            //couldn't write to error.log
                        }

                        Console.Out.WriteLine($"Error : {ex.Message.ToString()}");

                        //error
                        Environment.ExitCode = -1;
                    }
                }
                else
                {
                    //no save file found or inaccessible
                    if (logWriter == null)
                    {
                        logWriter = new StreamWriter(logFilename);
                    }
                    logWriter.Write($"Unable to find or access save game file: {saveFilename}");
                    Environment.ExitCode = -2;
                }

                if (logWriter != null)
                {
                    logWriter.Close();
                    logWriter.Dispose();
                }

                Application.Exit();
            }
            else
            {
                //no command line options, run viewer


                Application.Run(new frmViewer());
            }
        }