diff --git a/Perpetuum.DataDumper/App.config b/Perpetuum.DataDumper/App.config new file mode 100644 index 000000000..35c2129d0 --- /dev/null +++ b/Perpetuum.DataDumper/App.config @@ -0,0 +1,21 @@ + + + + +
+ + + + + + + + + C:\PerpetuumServer\data + + + C:\PerpetuumServer\data\dictionary.txt + + + + diff --git a/Perpetuum.DataDumper/Base Views/ActiveModuleDataView.cs b/Perpetuum.DataDumper/Base Views/ActiveModuleDataView.cs new file mode 100644 index 000000000..a97757db5 --- /dev/null +++ b/Perpetuum.DataDumper/Base Views/ActiveModuleDataView.cs @@ -0,0 +1,14 @@ +namespace Perpetuum.DataDumper { + public partial class DataDumper + { + public class ActiveModuleDataView : ModuleDataView { + // These are nullable because some items may be + // in a group of active modules but are themselves + // passive and we don't want to show 0 for them + public double? ModuleAccumulator { get; set; } + public double? ModuleCycle { get; set; } + public double? ModuleOptimalRange { get; set; } + } + + } +} diff --git a/Perpetuum.DataDumper/Base Views/EntityDataView.cs b/Perpetuum.DataDumper/Base Views/EntityDataView.cs new file mode 100644 index 000000000..6fbe440ee --- /dev/null +++ b/Perpetuum.DataDumper/Base Views/EntityDataView.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Perpetuum.DataDumper { + public class EntityDataView { + public string ItemName { get; set; } // This should actually be renamed... + public string ItemKey { get; set; } + public List ItemCategories { get; set; } + } +} diff --git a/Perpetuum.DataDumper/Base Views/ItemDataView.cs b/Perpetuum.DataDumper/Base Views/ItemDataView.cs new file mode 100644 index 000000000..2566e8600 --- /dev/null +++ b/Perpetuum.DataDumper/Base Views/ItemDataView.cs @@ -0,0 +1,12 @@ +namespace Perpetuum.DataDumper { + public partial class DataDumper + { + public class ItemDataView : EntityDataView { + public double ItemMass { get; set; } + public double ItemVolume { get; set; } + public double ItemVolumePacked { get; set; } + + } + + } +} diff --git a/Perpetuum.DataDumper/Base Views/ModuleDataView.cs b/Perpetuum.DataDumper/Base Views/ModuleDataView.cs new file mode 100644 index 000000000..963048171 --- /dev/null +++ b/Perpetuum.DataDumper/Base Views/ModuleDataView.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Perpetuum.DataDumper { + public partial class DataDumper + { + public class ModuleDataView : ItemDataView { + public string ModuleTier { get; set; } + public double ModuleCpu { get; set; } + public double ModuleReactor { get; set; } + public List ExtensionsRequired { get; set; } + } + + } +} diff --git a/Perpetuum.DataDumper/DataDumper.cs b/Perpetuum.DataDumper/DataDumper.cs new file mode 100644 index 000000000..3f61973cf --- /dev/null +++ b/Perpetuum.DataDumper/DataDumper.cs @@ -0,0 +1,381 @@ +using Autofac; +using Perpetuum.Bootstrapper; +using Perpetuum.Data; +using Perpetuum.EntityFramework; +using Perpetuum.ExportedTypes; +using Perpetuum.Items; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using Perpetuum.Robots; +using Perpetuum.Services.ExtensionService; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Runtime.InteropServices; +using Newtonsoft.Json; +using Perpetuum.Items.Ammos; +using Perpetuum.Services.ProductionEngine; +using Perpetuum.DataDumper.Views; +using System.Windows.Forms; +using System.CodeDom; +using Perpetuum.Services.Sparks; +using Perpetuum.Groups.Alliances; +using System.Reflection; +using NPOI.SS.UserModel; + +namespace Perpetuum.DataDumper { + public partial class DataDumper + { + private string serverRoot; + private string dictionaryPath; + + public IExtensionReader ExtensionReader; + + private IContainer container; + EntityFactory entityFactory; + IEntityServices entityServices; + IEntityDefaultReader defaultReader; + Dictionary itemNames = new Dictionary(); + ISparkRepository sparkRepository; + + // Some static lists for helpers + public static SlotFlags[] SLOT_SIZE_FLAGS = new SlotFlags[] { SlotFlags.small, SlotFlags.medium, SlotFlags.large }; + public static SlotFlags[] SLOT_TYPE_FLAGS = new SlotFlags[] { SlotFlags.turret, SlotFlags.missile, SlotFlags.melee, SlotFlags.industrial, SlotFlags.ew_and_engineering }; + public static SlotFlags[] SLOT_LOCATION_FLAGS = new SlotFlags[] { SlotFlags.head, SlotFlags.chassis, SlotFlags.leg }; + public static List CATEGORIES_AMMO_WEAPON = new List { + CategoryFlags.cf_railgun_ammo, + CategoryFlags.cf_laser_ammo, + CategoryFlags.cf_missile_ammo, + CategoryFlags.cf_projectile_ammo }; + + public DataDumper(IContainer container, string serverRoot, string dictionaryPath) + { + this.serverRoot = serverRoot; + + this.dictionaryPath = dictionaryPath; + + this.container = container; + + entityFactory = container.Resolve(); + + ExtensionReader = container.Resolve(); + + defaultReader = container.Resolve(); + + var productionDataReader = container.Resolve(); + + sparkRepository = container.Resolve(); + + entityServices = container.Resolve(); + + // Testing for new data dumps + // + // var getEd = defaultReader.GetByName("def_named1_small_armor_repairer"); + // var getCats = String.Join(";", getEd.CategoryFlags.GetCategoryFlagsTree().Where(x => x.ToString() != "undefined").Select(x => x.ToString()).ToList()); + // var testMissile = productionDataReader.ProductionComponents[64]; + // var testRobot = productionDataReader.ProductionComponents[193]; + // var testRobot2 = productionDataReader.ProductionComponents[208]; + + var dataLines = System.IO.File.ReadAllText(dictionaryPath); + + var dictionaryText = GenXY.GenxyConverter.Deserialize(dataLines); + + if (dictionaryText.ContainsKey("dictionary")) { + var sourceDict = (Dictionary)dictionaryText["dictionary"]; + + foreach (var item in sourceDict) { + itemNames.Add(item.Key, item.Value.ToString().Trim()); + } + + } else { + throw new Exception("Dictionary file is invalid"); + } + + // Now read the names from JSON files + string dictionaryLocation = System.IO.Path.Combine(serverRoot, @"customDictionary\0.json"); + + var jsonData = JsonConvert.DeserializeObject>(System.IO.File.ReadAllText(dictionaryLocation)); + + foreach (var item in jsonData) { + if (itemNames.ContainsKey(item.Key)) { + itemNames[item.Key] = item.Value; + } else { + itemNames.Add(item.Key, item.Value); + } + } + + Console.WriteLine($"{dataLines.Length} dictionary names loaded"); + } + + public string GetLocalizedName(string itemKey) + { + if (itemNames.ContainsKey(itemKey)) + { + return itemNames[itemKey]; + } else + { + return itemKey; + } + } + + public static string GenerateCargoDefinition(Type viewType, string tableName, string listDelimiter = ";") { + string header = "\n{{#cargo_declare:_table="+tableName+"\n"; + string body = ""; + string footer = "}}\n"; + var allProperties = viewType.GetProperties().OrderBy(x=> x.Name).ToList(); + + foreach (var property in allProperties) { + var cargoAttribute = property.GetCustomAttribute(); + + string cargoType = "String"; // <- This is the default in Cargo + + if (cargoAttribute != null) { + cargoType = cargoAttribute.Type; + } else { + // Let's set some defaults by property type + if (property.PropertyType == typeof(double)) { + cargoType = "Float"; + } else if (property.PropertyType == typeof(int)) { + cargoType = "Integer"; + } else if (property.PropertyType == typeof(bool)) { + cargoType = "Boolean"; + } else if(property.PropertyType == typeof(List)) { + cargoType = $"List ({listDelimiter}) of String"; + } else if (property.PropertyType == typeof(List)) { + cargoType = $"List ({listDelimiter}) of Integer"; + } else if (property.PropertyType == typeof(List)) { + cargoType = $"List ({listDelimiter}) of Float"; + } + } + + body += $"|{property.Name}={cargoType}\n"; + } + + return header + body + footer; + + } + + public void InitItemView(ItemDataView view, Entity entity) { + view.ItemName = GetLocalizedName(entity.ED.Name); + view.ItemKey = entity.ED.Name; + view.ItemCategories = entity.ED.CategoryFlags.GetCategoryFlagsTree().Where(x=> x.ToString() != "undefined").Select(x => x.ToString()).ToList(); + view.ItemMass = entity.Mass; + view.ItemVolumePacked = entity.ED.CalculateVolume(true, 1); + view.ItemVolume = entity.ED.CalculateVolume(false, 1); + } + + public void InitModuleView(ModuleDataView view, Modules.Module module) { + InitItemView(view, module); + + view.ModuleTier = module.ED.GameTierString(); + view.ModuleCpu = module.CpuUsage; + view.ModuleReactor = module.PowerGridUsage; + + view.ExtensionsRequired = new List(); + + foreach (var extension in module.ED.EnablerExtensions.Keys) { + view.ExtensionsRequired.Add(GetLocalizedName(ExtensionReader.GetExtensionName(extension.id)) + "(" + extension.level + ")"); + } + } + + public void InitActiveModuleView(ActiveModuleDataView view, ActiveModule module) { + InitModuleView(view, module); + + view.ModuleAccumulator = module.CoreUsage; + view.ModuleCycle = module.CycleTime.TotalSeconds; + + var range = module.GetBasePropertyModifier(AggregateField.optimal_range); + + if (range.HasValue) { + view.ModuleOptimalRange = range.Value * 10; + } + } + + public static string GetModifierString(ItemPropertyModifier mod) { + var returnValue = ""; + if (mod.HasValue) { + if (mod.ToString().Contains("Formula: Add")) { + returnValue = mod.Value * 100 + "%"; + + if (mod.Value > 0) { + returnValue = "+" + returnValue; + } + } else { + returnValue = ((mod.Value - 1) * 100) + "%"; + + if (mod.Value - 1 > 0) { + returnValue = "+" + returnValue; + } + } + + } + + return returnValue; + } + + public void WriteDataView(List> dataRows, string sheetName, ISheet worksheet, ref int currentDataRow) { + // Deal with the header + // If we are writing later than the first row in our sheet then we will skip + // the first row in our data because it will contain the header + int skipRow = 0; + + if (currentDataRow > 0) { + skipRow = 1; + } + + foreach (var dataRow in dataRows.Skip(skipRow).ToList()) { + int currentColumn = 0; + var currentRow = worksheet.CreateRow(currentDataRow); + foreach (var dataValue in dataRow) { + currentRow.CreateCell(currentColumn).SetCellValue(dataValue); + currentColumn++; + } + currentDataRow++; + } + } + + /// + /// This will write the properties as headers and values as rows + /// + public List> ComposeDataView(List data, string wikiTableName = "wikitable") { + var returnData = new List>(); + + if (data is null || data.Count == 0) { + return returnData; // Do nothing + } + + var headers = data.First().GetType().GetProperties().Select(i => i.Name).ToList(); + + returnData.Add(headers.Concat(new List { "wiki" }).ToList()); + + foreach (var item in data) + { + var currentProperties = new List(); + + // Add the wiki markup at the end + // {{#cargo_store:_table=WeaponStats|module_name=Niani medium EM-gun|module_key=def_artifact_a_longrange_medium_railgun|module_categories=cf_medium_railguns;cf_railguns;cf_weapons;cf_robot_equipment|cpu=45|reactor=205|ammo_type=Medium slugs|slot_status=Active|ammo_capacity=50|module_mass=650|module_volume_packed=0.25|module_tier=T3+|module_volume=0.5|module_accumulator=32|module_cycle=10|module_damage=250|module_falloff=60|module_hit_dispersion=14|module_optimal_range=300|module_extensions_required=Advanced magnetostatics(2);|slot_type=turret|slot_size=medium|slot_location=chassis}} + string wikiData = $"{{{{#cargo_store:_table={wikiTableName}"; + + foreach (string prop in headers) + { + var currentProp = item.GetType().GetProperty(prop); + var currentValue = ""; + + try + { + if (currentProp == null) + { + currentValue = "Error: Prop not found"; + } + else + { + if (currentProp.PropertyType.Name.Contains("List")) { + currentValue = String.Join(";", (currentProp.GetValue(item) as IEnumerable)); + } else { + currentValue = currentProp.GetValue(item)?.ToString().Replace(",",";") ?? ""; + } + } + } + catch (Exception) + { + currentValue = "EXCEPTION"; + } + + currentProperties.Add(currentValue); + + wikiData += $"|{prop}={currentValue}"; + + } + + wikiData += "}}"; + + currentProperties.Add(wikiData); + + returnData.Add(currentProperties); + + } + + return returnData; + + } + + // TODO: Refactor this to use the built-in function instead of SQL + private List GetDataByItemCategoryName(string categoryName) + { + var itemData = Db.Query().CommandText( + $@"DECLARE @lookupFlag bigint; + SET @lookupFlag = (select value from dbo.categoryFlags where name='{categoryName}'); + SELECT * from entitydefaults where (categoryflags & CAST(dbo.GetCFMask(@lookupFlag)as BIGINT) = @lookupFlag) + AND enabled=1 AND hidden=0 AND purchasable=1;" + ).Execute(); + + return itemData; + } + + public List DumpDataView(DataExportMapping mapping) { + var returnItems = new List(); + + // Handle sparks first, refactor later + if (mapping.ViewType == typeof(SparkDataView)) { + var sparkData = sparkRepository.GetAll(); + + foreach (var spark in sparkData) { + try { + var currentView = new SparkDataView(spark, this); + + returnItems.Add(currentView); + } catch (Exception ex) { + Console.WriteLine(ex.Message); + } + } + + return returnItems; + + } + + if(mapping.ViewType == typeof(RobotDataView)) { + var robotDefinitions = defaultReader.GetAll().GetByCategoryFlags(CategoryFlags.cf_robots); + + foreach (var robotDefinition in robotDefinitions) { + object currentObject = entityFactory.Create(robotDefinition.Name, EntityIDGenerator.Random); + + ((Robot)currentObject).Unpack(); + + dynamic currentView = Activator.CreateInstance(mapping.ViewType, currentObject, this); + + returnItems.Add(currentView); + } + + return returnItems; + } + + var categoryData = GetDataByItemCategoryName(mapping.Category); + + foreach (var categoryItem in categoryData) { + string itemName = categoryItem["definitionname"].ToString(); + int itemId = (int)categoryItem["definition"]; + + try { + object currentObject = entityFactory.Create(itemName, EntityIDGenerator.Random); + + dynamic currentView = Activator.CreateInstance(mapping.ViewType, currentObject, this); + + returnItems.Add(currentView); + } catch (Exception ex) { + Console.WriteLine(ex.Message); + } + + } + return returnItems; + + } + + public object GenerateItem(string itemName) { + var result = entityFactory.Create(itemName, EntityIDGenerator.Random); + + return result; + } + + } +} diff --git a/Perpetuum.DataDumper/DataExportMapping.cs b/Perpetuum.DataDumper/DataExportMapping.cs new file mode 100644 index 000000000..7b53702d0 --- /dev/null +++ b/Perpetuum.DataDumper/DataExportMapping.cs @@ -0,0 +1,51 @@ +using Perpetuum.DataDumper.Views; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Perpetuum.DataDumper { + public class DataExportMapping { + public string TableName { get; set; } + public Type ViewType { get; set; } + public string Category { get; set; } + + public DataExportMapping(string _tableName, Type _type, string _category) { + TableName = _tableName; + ViewType = _type; + Category = _category; + } + + public override string ToString() { + return ViewType.Name.ToString(); + } + + public static List Mappings = new List() { + // These universal ones are strange because they're stored in a different category + // even though in the game UI they're the same thing and they have basically the same stats + // Also the univeral one is a regular module while the others are Active + new DataExportMapping("ModuleMinerStats", typeof(ModuleMinerDataView), "cf_drillers"), + new DataExportMapping("ModuleHarvesterStats", typeof(ModuleHarvesterDataView), "cf_harvesters"), + new DataExportMapping("ModuleArmorHardenerStats", typeof(ModuleArmorHardenerDataView), "cf_armor_hardeners"), + new DataExportMapping("ModuleShieldGeneratorStats", typeof(ModuleShieldGeneratorDataView), "cf_shield_generators"), + new DataExportMapping("ModuleERPStats", typeof(ModuleERPDataView), "cf_kers"), + new DataExportMapping("ModuleRemArmorRepairerStats", typeof(ModuleRemoteArmorRepairerDataView), "cf_remote_armor_repairers"), + new DataExportMapping("ModuleArmorPlateStats", typeof(ModuleArmorPlateDataView), "cf_armor_plates"), + new DataExportMapping("SparkStats", typeof(SparkDataView), ""), + new DataExportMapping("ModuleArmorRepairerStats", typeof(ModuleArmorRepairerDataView), "cf_armor_repair_systems"), + new DataExportMapping("AmmoWeaponStats", typeof(AmmoWeaponDataView), "cf_ammo"), + new DataExportMapping("ModuleWeaponStats", typeof(ModuleWeaponDataView), "cf_weapons"), + new DataExportMapping("RobotStats", typeof(RobotDataView), "cf_robot"), + new DataExportMapping("ModuleAuxAccumulatorStats", typeof(ModuleAuxAccumulatorDataView), "cf_core_batteries"), + new DataExportMapping("ModuleEnergyTransfererStats", typeof(ModuleEnergyTransfererDataView), "cf_energy_transferers"), + new DataExportMapping("ModuleEnergyDrainerStats", typeof(ModuleEnergyDrainerDataView), "cf_energy_vampires"), + new DataExportMapping("ModuleEnergyNeutralizerStats", typeof(ModuleEnergyNeutralizerDataView), "cf_energy_neutralizers"), + new DataExportMapping("ModuleEnergyInjectorStats", typeof(ModuleEnergyInjectorDataView), "cf_core_boosters"), + new DataExportMapping("ModuleDemobilizerStats", typeof(ModuleDemobilizerDataView), "cf_webber"), + new DataExportMapping("ModuleNexusStats", typeof(ModuleNexusDataView), "cf_gang_assist_modules") + + }; + + } +} diff --git a/Perpetuum.DataDumper/DumperForm.Designer.cs b/Perpetuum.DataDumper/DumperForm.Designer.cs new file mode 100644 index 000000000..cddf6d2d7 --- /dev/null +++ b/Perpetuum.DataDumper/DumperForm.Designer.cs @@ -0,0 +1,187 @@ +namespace Perpetuum.DataDumper { + partial class DumperForm { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DumperForm)); + this.StartButton = new System.Windows.Forms.Button(); + this.mappingSelectList = new System.Windows.Forms.CheckedListBox(); + this.label2 = new System.Windows.Forms.Label(); + this.allTypesButton = new System.Windows.Forms.Button(); + this.clearTypesButton = new System.Windows.Forms.Button(); + this.serverPathTextbox = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label1 = new System.Windows.Forms.Label(); + this.dictionaryPathTextbox = new System.Windows.Forms.TextBox(); + this.saveSettingsButton = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // StartButton + // + this.StartButton.Location = new System.Drawing.Point(12, 12); + this.StartButton.Name = "StartButton"; + this.StartButton.Size = new System.Drawing.Size(65, 23); + this.StartButton.TabIndex = 0; + this.StartButton.Text = "Start"; + this.StartButton.UseVisualStyleBackColor = true; + this.StartButton.Click += new System.EventHandler(this.StartButton_Click); + // + // mappingSelectList + // + this.mappingSelectList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.mappingSelectList.FormattingEnabled = true; + this.mappingSelectList.Location = new System.Drawing.Point(12, 63); + this.mappingSelectList.Name = "mappingSelectList"; + this.mappingSelectList.Size = new System.Drawing.Size(306, 379); + this.mappingSelectList.TabIndex = 3; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 42); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(62, 13); + this.label2.TabIndex = 4; + this.label2.Text = "Data Types"; + // + // allTypesButton + // + this.allTypesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.allTypesButton.Location = new System.Drawing.Point(12, 453); + this.allTypesButton.Name = "allTypesButton"; + this.allTypesButton.Size = new System.Drawing.Size(75, 23); + this.allTypesButton.TabIndex = 5; + this.allTypesButton.Text = "All"; + this.allTypesButton.UseVisualStyleBackColor = true; + this.allTypesButton.Click += new System.EventHandler(this.allTypesButton_Click); + // + // clearTypesButton + // + this.clearTypesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.clearTypesButton.Location = new System.Drawing.Point(122, 453); + this.clearTypesButton.Name = "clearTypesButton"; + this.clearTypesButton.Size = new System.Drawing.Size(75, 23); + this.clearTypesButton.TabIndex = 6; + this.clearTypesButton.Text = "Clear"; + this.clearTypesButton.UseVisualStyleBackColor = true; + this.clearTypesButton.Click += new System.EventHandler(this.clearTypesButton_Click); + // + // serverPathTextbox + // + this.serverPathTextbox.Location = new System.Drawing.Point(109, 23); + this.serverPathTextbox.Name = "serverPathTextbox"; + this.serverPathTextbox.Size = new System.Drawing.Size(167, 20); + this.serverPathTextbox.TabIndex = 7; + this.serverPathTextbox.TextChanged += new System.EventHandler(this.serverPathTextbox_TextChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(11, 26); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(92, 13); + this.label3.TabIndex = 8; + this.label3.Text = "Server Data Path:"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.saveSettingsButton); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.dictionaryPathTextbox); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.serverPathTextbox); + this.groupBox1.Location = new System.Drawing.Point(331, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(285, 100); + this.groupBox1.TabIndex = 9; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Settings"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(13, 52); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(79, 13); + this.label1.TabIndex = 10; + this.label1.Text = "Dictionary Path"; + // + // dictionaryPathTextbox + // + this.dictionaryPathTextbox.Location = new System.Drawing.Point(111, 49); + this.dictionaryPathTextbox.Name = "dictionaryPathTextbox"; + this.dictionaryPathTextbox.Size = new System.Drawing.Size(167, 20); + this.dictionaryPathTextbox.TabIndex = 9; + this.dictionaryPathTextbox.TextChanged += new System.EventHandler(this.dictionaryPathTextbox_TextChanged); + // + // saveSettingsButton + // + this.saveSettingsButton.Location = new System.Drawing.Point(7, 71); + this.saveSettingsButton.Name = "saveSettingsButton"; + this.saveSettingsButton.Size = new System.Drawing.Size(58, 23); + this.saveSettingsButton.TabIndex = 11; + this.saveSettingsButton.Text = "Save"; + this.saveSettingsButton.UseVisualStyleBackColor = true; + this.saveSettingsButton.Click += new System.EventHandler(this.saveSettingsButton_Click); + // + // DumperForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(627, 488); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.clearTypesButton); + this.Controls.Add(this.allTypesButton); + this.Controls.Add(this.label2); + this.Controls.Add(this.mappingSelectList); + this.Controls.Add(this.StartButton); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "DumperForm"; + this.Text = "Perpetuum Data Dumper"; + this.Load += new System.EventHandler(this.Form1_Load); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button StartButton; + private System.Windows.Forms.CheckedListBox mappingSelectList; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Button allTypesButton; + private System.Windows.Forms.Button clearTypesButton; + private System.Windows.Forms.TextBox serverPathTextbox; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox dictionaryPathTextbox; + private System.Windows.Forms.Button saveSettingsButton; + } +} + diff --git a/Perpetuum.DataDumper/DumperForm.cs b/Perpetuum.DataDumper/DumperForm.cs new file mode 100644 index 000000000..536a010d0 --- /dev/null +++ b/Perpetuum.DataDumper/DumperForm.cs @@ -0,0 +1,131 @@ +using Autofac; +using NPOI.SS.Formula.Functions; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; +using Org.BouncyCastle.Asn1.X509; +using Perpetuum.DataDumper.Views; +using Perpetuum.EntityFramework; +using Perpetuum.Log; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper { + public partial class DumperForm : Form { + public DumperForm() { + InitializeComponent(); + } + + PerpetuumLightBootstrapper bootstrapper; + + private void Form1_Load(object sender, EventArgs e) { + serverPathTextbox.Text = Properties.Settings.Default.ServerPath; + dictionaryPathTextbox.Text = Properties.Settings.Default.DictionaryPath; + + foreach (var item in DataExportMapping.Mappings.OrderBy(x=> x.TableName).ToList()) { + mappingSelectList.Items.Add(item, true); + } + } + + + private void StartButton_Click(object sender, EventArgs e) { + var tableGroupings = mappingSelectList.CheckedItems.Cast().GroupBy(x => x.TableName).ToList(); + + if (!System.IO.Directory.Exists(Properties.Settings.Default.ServerPath)) { + MessageBox.Show("Server path doesn't exist: " + Properties.Settings.Default.ServerPath); + } + + bootstrapper = new PerpetuumLightBootstrapper(); + + bootstrapper.Init(Properties.Settings.Default.ServerPath); + + bootstrapper.InitDumper(Properties.Settings.Default.ServerPath, Properties.Settings.Default.DictionaryPath); + + IWorkbook workbook = new XSSFWorkbook(); + + ISheet definitionsSheet = workbook.CreateSheet("Definitions"); + + int currentDefinitionRow = 0; + var headerRow = definitionsSheet.CreateRow(currentDefinitionRow); + headerRow.CreateCell(0).SetCellValue("Type"); + headerRow.CreateCell(1).SetCellValue("Definition"); + currentDefinitionRow++; + + // We need to group by the Cargo Table because we may have multipler + // definitions writing into the same table. + + foreach (var tableGroup in tableGroupings) { + // Write the definition for the group + + // Use the first view for the definition since they should all be the same + var typeToWrite = tableGroup.First(); + + string currentDefinition = DataDumper.GenerateCargoDefinition(typeToWrite.ViewType, typeToWrite.TableName); + + var currentRow = definitionsSheet.CreateRow(currentDefinitionRow); + currentRow.CreateCell(0).SetCellValue(typeToWrite.TableName); + currentRow.CreateCell(1).SetCellValue(currentDefinition); + + currentDefinitionRow++; + + int currentDataRow = 0; + ISheet currentDataSheet = workbook.CreateSheet(typeToWrite.TableName); + + foreach (DataExportMapping item in tableGroup) { + dynamic currentData = bootstrapper.Dumper.DumpDataView(item); + + var currentRows = bootstrapper.Dumper.ComposeDataView(currentData, item.TableName); + + bootstrapper.Dumper.WriteDataView(currentRows, item.TableName, currentDataSheet, ref currentDataRow); + } + } + + string filePath = $"dataDump_{DateTime.Now.ToString("yy-MM-dd_hh-mm-ss")}.xlsx"; + + workbook.Write(new FileStream(filePath, FileMode.CreateNew)); + + var result = MessageBox.Show($"File exported to:\n{filePath}\n\nWould you like to open it?", "Export finished", MessageBoxButtons.YesNo); + + if (result == DialogResult.Yes) { + Process.Start(filePath); + } + + } + + private void allTypesButton_Click(object sender, EventArgs e) { + for (int i = 0; i < DataExportMapping.Mappings.Count; i++) { + mappingSelectList.SetItemChecked(i, true); + } + } + + private void clearTypesButton_Click(object sender, EventArgs e) { + for (int i = 0; i < DataExportMapping.Mappings.Count; i++) { + mappingSelectList.SetItemChecked(i, false); + } + } + + private void serverPathTextbox_TextChanged(object sender, EventArgs e) { + Properties.Settings.Default.ServerPath = serverPathTextbox.Text; + } + private void dictionaryPathTextbox_TextChanged(object sender, EventArgs e) { + Properties.Settings.Default.DictionaryPath = dictionaryPathTextbox.Text; + } + + private void saveSettingsButton_Click(object sender, EventArgs e) { + Properties.Settings.Default.Save(); + } + + + } +} diff --git a/Perpetuum.DataDumper/DumperForm.resx b/Perpetuum.DataDumper/DumperForm.resx new file mode 100644 index 000000000..19489cc19 --- /dev/null +++ b/Perpetuum.DataDumper/DumperForm.resx @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAA + AAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AFdBXQZXQV0wV0FdWldB + XX1XQV2NV0FdjldBXX1XQV1cV0FdMVdBXQj///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBXQV43VT9bik86 + V8lHMk/sQi5K/UEtSf9BL0v/RzJP/U05Ve1UPlzLV0RfjlpEYTv///8B////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBYQWFLUjxbyUgy + Uv87KUf/MiA//ywaOv8pGDj/KBY3/ykYOP8uHTv/MyE//zspR/9FME//UDlZ/1dAYM1aQ2NR////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wBaQGUNVz1hmkoy + Vv87JEn/MRtA/ykTPP8kDjj/Igs3/x8HNf8hCzb/Igw1/yUPN/8pFTr/Kxc9/zEbQP85I0f/RC5Q/1M6 + Xv9ZP2ShWkBlEP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AXEBnJFQ6 + YNJBKVD/MxtD/ykRPf8lDTr/IQk5/x8FOP8fBTj/HwU4/yAHOP8jDDn/Khc+/2BWa/9RQl3/JRI7/ygT + Pf8vGUD/OiJK/0sxWf9aPmXXXEBnKf///wD///8A////AP///wD///8A////AP///wD///8A////AGJE + biJSNWHpPiRP/zAWRv8pDkH/JQs//yYLPv8kCD3/Igc+/yEFPv8jBz3/Iwg+/yUNP/9iTnf/9vL5/+DY + 5v82Ikv/Jg1A/ycNP/8rD0L/NRtK/0ktWf9aPmntXEBqJ////wD///8A////AP///wD///8A////AP// + /wFwVoANVTdn00AiVv8xFEv/Kw9G/ywPSf8oDkP/KA5D/ycLRv8lCEX/JAZE/yQGRP8lCUT/KA5F/5OG + n////////////083Zv8nDEX/JglF/yUIRf8pC0f/NRlP/0ssXv9dPm7YX0BwD////wD///8A////AP// + /wD///8B////AV08b5hFJVv/NBhO/y8RS/8vEUr/Nh1Q/7muxP/f1+f/Ujlp/ykMSP8oCEj/KAhH/ycJ + R/8pDEj/PSVV/7Cmu/+uo7j/MBNL/ykMSP8oCEj/JgRH/ycDR/8rCkr/OhpT/1EwZf9fPnGi////AP// + /wD///8A////AP///wFlQnhETyxm/zoaVv8yElH/MRRO/zMTUv9eR3H///////////+qnbb/LA5M/ysJ + Tf8qBk3/KwZO/ywJTv8uDU//Qyhd/6absf8vDk//LApO/ysGTv8oA0z/JwBM/ykDTf8xC1D/QR5b/1o3 + b/9jPnVL////AP///wD///8A1M3ZAlo4cMhCIF3/ORhV/4l5mf+zp77/i3yZ/7Wrvv/Oxdf/9vL5/3Vh + iP8xEVD/LgxP/ysJTv8rCU7/LApO/y4NUP81FlL/uK3C/zscVf8uDE//LQlP/yoGTf8qBE3/KgRN/ywH + Tv83E1X/Titl/2E+ddBkP3cC////AP///wBpR3wwTy1m/z0bWP9eSHT////////////Rydr/Rixf/zkb + Vv9hS3b/pZmw/zMTUv8wD1H/LwtQ/y0MT/8vC1D/Lw5P/zERUP+jl67/Vz9u/zAOUP8tDE//LQpO/ywH + Tv8rBk7/LAdO/zIOUf9CIF3/XDlx/2RBeDX///8AZ0J5BF4+c4NGJWD/ORdV/082Z//t6PL//////4Ry + lv87Hlf/Ox1X/zocVv+wprv/WkNw/zQVU/8yElL/MA9R/zAPUf8xEVD/MxNS/41/m/94ZYv/MhJS/zAP + Uf8wDVH/LgpP/y0JT/8tCU//MA1R/zwZWP9TMWr/Z0J5i2dCeQdpRHwnWDVuw0AgXP82F1X/OBdU/0Il + XP+AbpL/oJSs/z0fWv89H1r/PB9Z/3Fchf+onbP/ORtX/zcYVv82F1T/NhdU/zYXVP83GFX/cl2G/5mM + pv83GFX/NRZV/zMSUv8yEVL/MQ5R/zEOUf8zD1L/OhhX/0wrZf9kQXjLaUR8LmdEe1BPL2jnPR1Z/zUW + Vf83F1X/ORtY/zweWf+6r8P/Ykt4/z4iW/8/Ilv/PyJb/7arwP9YQW//PB5Z/zsdWP86HFf/OhxX/zsd + WP9YP2//rKC3/z4eWf86HFf/OBhW/zYXVP80FVT/NRNU/zQTU/85F1b/SCZi/2E+de1pR31aZUF5gEoq + ZP08G1n/NhdV/zcXVf85Glf/Ox1Z/2pVf/+sobf/QSRc/0EkXP9BJFz/pJiw//////+uobn/PR9a/z4h + W/8+IVv/QCNd/0ImXf+zqb3/Ujlp/z8iXP89H1r/OxxZ/zkaV/84Glb/NxdV/zsZWP9FJV//XDtz/WxI + fntiQHefSCdi/zsbWf83Flb/NxhW/zkbWP87HVn/QiNd/+Lc6P/p4+//lomj/6GVrf/18fj///////// + //+lmbD/lYii/3xoj/9iS3j/nI+n///////28vn/dWGJ/0IlXf8/I1v/PR9a/zsdWP87HFn/OxxZ/0Ym + Yf9aOXH/bUuBh2RAeJ1JKGP/PBxa/zgXVv85Glf/OhxZ/zwdWf9HK2L/+vj8//////+ekqr/aVF//4h4 + l//j3Or/npGr/2RNev+FdJb/pZqx/7aswP/////////////////u6PP/eWWM/11Fc/9+apH/y8LT/2tW + gP8+IVv/Rydi/1s6cv9wTIKHZkR7fU0tZ/w/Hlv/OhlY/zsbWf87HVn/PR5a/z4hW/9iSnj/d2KL/0Il + Xv9DJl7/QyZe/0EkXf9CJV7/QiVe/0MmXv9FKWD/Riph/9nS4f///////////9TK3f+ila//rKC3//Pv + 9///////zMTV/0EjXv9MLGX/Xz11/HBNhHpsSoBNVDNs5UMjX/89HVr/PR1a/z0eWv8/H1z/PyBc/0Ai + Xf9BI17/QSRe/0EkXv9BJF7/QSNe/0AjXf9BI17/RCVe/0UpYP9HK2P/Zk98/9/Y5f+pnLX/Si5k/0gs + ZP9IKmL/mYyn/+Td6f+Hd5f/RCdg/1Awaf9lQ3rrdFCFV3FPhSNePXS/Sitl/0EiXv8/H1z/QCBd/z8i + Xf9AI17/QiNf/0IjX/9CJF7/QiNf/0IjX/9CI1//QiNf/0IkXv9DJl//Ripi/0gsZP+Qgp//kYOf/0kt + Y/9JLWT/SStj/0crY/9HKWH/Ryti/0UnYf9IKWX/WDhv/21Mgsd3U4gsdFGHA2hHfXxRMWr/RSZh/0Ei + Xv9CI1//QiNf/0IjX/9CI1//QiNf/0IjX/9CI1//QiNf/0IjX/9CI1//QiVf/0UmYf9GKWL/SCtk/7+0 + yP9kTHr/SCxk/0crY/9GKmP/RSlh/0QnYf9EJ2H/Rili/00vZ/9fPnX/dVGGhnRRhwX///8AcU+FKFo6 + cv5KK2X/RCVg/0MkX/9DJF//QyRf/0MkX/9DJF//QyRf/0MkX/9DJF//QyRf/0QlYP9EJ2H/Rili/0gr + ZP9pUYD/vLHF/0ktZP9IK2T/Ryhj/0YnYv9GJ2L/RCdh/0UpYv9JK2X/VDZt/2pJf/94Vosw////AP// + /wD///8AZUR7wFEya/9IKGP/RSZh/0UmYf9FJmH/RSZh/0UmYf9FJmH/RSZh/0UmYf9GJ2L/RSli/0gq + ZP9JLWT/Si5m/6eas/+OgJ3/Si1m/0krZf9IKmT/Ridi/0YnYv9GJ2L/Ryhj/04vaP9dPnX/c1GGyXdU + igH///8A////AP///wBzUYY6XD10/E4vaP9IKmT/Ryhj/0coY/9HKGP/Ryhj/0coY/9HKGP/Ryhj/0gq + ZP9JLGX/Si5m/0wwaP9SN23/yMDQ/15Fdv9ML2f/Si1m/0krZf9IKmT/Ryhj/0gqZP9MLWf/VTdv/2pK + gP54VotC////AP///wD///8A////AP///wBsS4GLWTlx/00vaP9JK2X/SCpk/0gqZP9IKmT/SCpk/0gq + ZP9JK2X/SCxl/0suZv9OMWn/TzJp/3Zhiv+zp77/TzJp/00waP9LLWf/SCxl/0gqZP9JK2X/Sy1n/1M0 + bf9jQnr/dlSJlP///wD///8A////AP///wD///8A////AHhWiwdoSH7HVjhw/08waf9LLWf/Sixm/0os + Zv9KLGb/Sixm/0stZ/9MLmj/TTBo/1A1a/+nmbP//Pv+/6qdt/9RNWv/TzJq/00vaP9LLWf/Sy1n/00u + aP9TNG3/YEF4/3RSh856WI0K////AP///wD///8A////AP///wD///8A////AHlWjBdoSH7eWTtz/1Ey + a/9NL2j/TC5o/0wuaP9MLmj/TS9o/04waf9PM2v/VDpu//r4/P//////7Obx/1I3bf9QNWv/TjFp/04w + af9PMWr/VTdv/2FBef9zUYfkfFmOHP///wD///8A////AP///wD///8A////AP///wD///8A////AHlX + jBlrSoHEXD51/1Q1bv9QMWr/TjBp/00vaP9OMGn/TzFq/1Aza/9RNmz/npCs/+Xe7P+Of53/UjZt/1E0 + bP9RM2z/UzRt/1k7c/9lRHz/dVOJyn1ajx7///8A////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AHxajwZxUIeJZUV8/Vo8c/9WOHD/UzRt/1I0bf9QNGz/UzVu/1M4b/9fRXf/d2OL/1k/ + c/9WOXH/Vjlx/1k7c/9gQnn/bEyC/3pYjY5+W5EI////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wB6WI07b0+FumZHff1eQHf/Wjxz/1g6cv9WOXH/Vjlx/1c7 + cf9aPHL/Wz91/2BBd/9lRnv/bEyC/nZUir59W5BA////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AfFqPKHVUiXhtTYO5aEl/4GRE + e/liQnr/Y0R6/2dIffpsTYLidFOJvXpYjnuBX5Qq////AP///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AIBd + kiJ8WpBKelmOc3lYjZV6WI2XfFqPdYBfkkyDYpUl////Af///wD///8A////AP///wD///8A////AP// + /wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Perpetuum.DataDumper/Helpers/CargoTypeAttribute.cs b/Perpetuum.DataDumper/Helpers/CargoTypeAttribute.cs new file mode 100644 index 000000000..1e463d673 --- /dev/null +++ b/Perpetuum.DataDumper/Helpers/CargoTypeAttribute.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Perpetuum.DataDumper { + + [System.AttributeUsage(System.AttributeTargets.Class)] + public class CargoTypeAttribute : System.Attribute { + public string Type; + + public CargoTypeAttribute(string type) { + this.Type = type; + } + } +} diff --git a/Perpetuum.DataDumper/Helpers/EnumHelper.cs b/Perpetuum.DataDumper/Helpers/EnumHelper.cs new file mode 100644 index 000000000..e3e33db94 --- /dev/null +++ b/Perpetuum.DataDumper/Helpers/EnumHelper.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Perpetuum.DataDumper { + public static class EnumHelper + where T : struct { + // ReSharper disable StaticFieldInGenericType + private static readonly Enum[] Values; + // ReSharper restore StaticFieldInGenericType + private static readonly T DefaultValue; + + static EnumHelper() { + var type = typeof(T); + if (type.IsSubclassOf(typeof(Enum)) == false) { + throw new ArgumentException(); + } + Values = Enum.GetValues(type).Cast().ToArray(); + DefaultValue = default(T); + } + + public static T[] MaskToList(Enum mask, bool ignoreDefault = true) { + var q = Values.Where(mask.HasFlag); + if (ignoreDefault) { + q = q.Where(v => !v.Equals(DefaultValue)); + } + return q.Cast().ToArray(); + } + } +} diff --git a/Perpetuum.DataDumper/Helpers/ExtensionMethods.cs b/Perpetuum.DataDumper/Helpers/ExtensionMethods.cs new file mode 100644 index 000000000..88cd81094 --- /dev/null +++ b/Perpetuum.DataDumper/Helpers/ExtensionMethods.cs @@ -0,0 +1,35 @@ +using Perpetuum.EntityFramework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Perpetuum.DataDumper +{ + public static class ExtensionMethods + { + public static string GameTierString(this EntityDefault info) + { + string levelText = $"T{info.Tier.level}"; + + if (info.Tier.type == ExportedTypes.TierType.Prototype) { + levelText += "P"; + } else if (info.Tier.type == ExportedTypes.TierType.Special) { + // We nede to read from options to differentiate special + string optionTier = info.Options.GetOption("tier"); + optionTier = optionTier.Replace("level_", ""); + + if (optionTier.Contains("a")) { + levelText += "-"; + } else if (optionTier.Contains("+")) { + levelText += "+"; + } else if (info.Tier.level == 0) { + levelText = "S"; + } + } + + return levelText; + } + } +} diff --git a/Perpetuum.DataDumper/Perpetuum.DataDumper.csproj b/Perpetuum.DataDumper/Perpetuum.DataDumper.csproj new file mode 100644 index 000000000..113c981b2 --- /dev/null +++ b/Perpetuum.DataDumper/Perpetuum.DataDumper.csproj @@ -0,0 +1,173 @@ + + + + + Debug + AnyCPU + {55911748-316C-43CA-B703-47DBF77AC171} + WinExe + Perpetuum.DataDumper + Perpetuum.DataDumper + v4.6.1 + 512 + false + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + x64 + bin\x64\Debug\ + TRACE;DEBUG + + + x64 + bin\x64\Release\ + + + + ..\packages\Autofac.4.6.1\lib\net45\Autofac.dll + + + ..\packages\Portable.BouncyCastle.1.8.6\lib\net40\BouncyCastle.Crypto.dll + + + ..\packages\SharpZipLib.1.2.0\lib\net45\ICSharpCode.SharpZipLib.dll + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\NPOI.2.5.1\lib\net45\NPOI.dll + + + ..\packages\NPOI.2.5.1\lib\net45\NPOI.OOXML.dll + + + ..\packages\NPOI.2.5.1\lib\net45\NPOI.OpenXml4Net.dll + + + ..\packages\NPOI.2.5.1\lib\net45\NPOI.OpenXmlFormats.dll + + + ..\packages\Open.NAT.2.1.0.0\lib\net45\Open.Nat.dll + + + + + + + + + + + + + + + + + + + + + + + + + + Form + + + DumperForm.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + DumperForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {e113962c-ad5d-4f17-8d08-656221cbd2d4} + Perpetuum.Bootstrapper + + + {e322bf83-76b8-4395-9ff2-26df13f6816c} + Perpetuum.ExportedTypes + + + {F69F19CA-DF42-420E-BC21-2ADD28C50A0C} + Perpetuum.RequestHandlers + + + {8587a597-848e-497f-8036-3b6f8047ec45} + Perpetuum + + + + + \ No newline at end of file diff --git a/Perpetuum.DataDumper/PerpetuumLightServer.cs b/Perpetuum.DataDumper/PerpetuumLightServer.cs new file mode 100644 index 000000000..5a4c892b7 --- /dev/null +++ b/Perpetuum.DataDumper/PerpetuumLightServer.cs @@ -0,0 +1,27 @@ +using Autofac; +using Perpetuum.Bootstrapper; +using Perpetuum.Data; +using Perpetuum.EntityFramework; +using Perpetuum.Items; +using Perpetuum.Modules; +using Perpetuum.Robots; +using Perpetuum.Services.ExtensionService; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; + +namespace Perpetuum.DataDumper { + + public class PerpetuumLightBootstrapper : PerpetuumBootstrapper { + // public void Init(string gameRoot) + + public DataDumper Dumper; + + public void InitDumper(string serverRoot, string dictionaryPath) + { + Dumper = new DataDumper(GetContainer(), serverRoot, dictionaryPath); + } + + } +} diff --git a/Perpetuum.DataDumper/Program.cs b/Perpetuum.DataDumper/Program.cs new file mode 100644 index 000000000..b465af53f --- /dev/null +++ b/Perpetuum.DataDumper/Program.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Perpetuum.DataDumper { + static class Program { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new DumperForm()); + } + } +} diff --git a/Perpetuum.DataDumper/Properties/AssemblyInfo.cs b/Perpetuum.DataDumper/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..c58b2bd54 --- /dev/null +++ b/Perpetuum.DataDumper/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Perpetuum.DataDumper")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Perpetuum.DataDumper")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("55911748-316c-43ca-b703-47dbf77ac171")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Perpetuum.DataDumper/Properties/Resources.Designer.cs b/Perpetuum.DataDumper/Properties/Resources.Designer.cs new file mode 100644 index 000000000..cf0defedc --- /dev/null +++ b/Perpetuum.DataDumper/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Perpetuum.DataDumper.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Perpetuum.DataDumper.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Perpetuum.DataDumper/Properties/Resources.resx b/Perpetuum.DataDumper/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Perpetuum.DataDumper/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Perpetuum.DataDumper/Properties/Settings.Designer.cs b/Perpetuum.DataDumper/Properties/Settings.Designer.cs new file mode 100644 index 000000000..a3cf13773 --- /dev/null +++ b/Perpetuum.DataDumper/Properties/Settings.Designer.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Perpetuum.DataDumper.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("C:\\PerpetuumServer\\data")] + public string ServerPath { + get { + return ((string)(this["ServerPath"])); + } + set { + this["ServerPath"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("C:\\PerpetuumServer\\data\\dictionary.txt")] + public string DictionaryPath { + get { + return ((string)(this["DictionaryPath"])); + } + set { + this["DictionaryPath"] = value; + } + } + } +} diff --git a/Perpetuum.DataDumper/Properties/Settings.settings b/Perpetuum.DataDumper/Properties/Settings.settings new file mode 100644 index 000000000..f99e22b1e --- /dev/null +++ b/Perpetuum.DataDumper/Properties/Settings.settings @@ -0,0 +1,12 @@ + + + + + + C:\PerpetuumServer\data + + + C:\PerpetuumServer\data\dictionary.txt + + + \ No newline at end of file diff --git a/Perpetuum.DataDumper/Views/AmmoWeaponDataView.cs b/Perpetuum.DataDumper/Views/AmmoWeaponDataView.cs new file mode 100644 index 000000000..87dce23e9 --- /dev/null +++ b/Perpetuum.DataDumper/Views/AmmoWeaponDataView.cs @@ -0,0 +1,63 @@ +using Perpetuum.ExportedTypes; +using Perpetuum.Items.Ammos; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class AmmoWeaponDataView : ItemDataView { + public double? DamageChemical { get; set; } + public double? DamageKinetic { get; set; } + public double? DamageSeismic { get; set; } + public double? DamageThermal { get; set; } + public double? DamageToxic { get; set; } + public double DamageTotal { get => (DamageChemical ?? 0) + (DamageKinetic ?? 0) + (DamageSeismic ?? 0) + (DamageThermal ?? 0); } + public double? OptimalRange { get; set; } + public double? ExplosionRadius { get; set; } + public string ModifierRange { get; set; } + public string ModifierFalloff { get; set; } + + public AmmoWeaponDataView(Ammo item, DataDumper dumper) { + dumper.InitItemView(this, item); + + var dictionaryData = item.ToDictionary(); + + DamageChemical = item.GetBasePropertyModifier(AggregateField.damage_chemical).Value; + DamageKinetic = item.GetBasePropertyModifier(AggregateField.damage_kinetic).Value; + DamageSeismic = item.GetBasePropertyModifier(AggregateField.damage_explosive).Value; + DamageThermal = item.GetBasePropertyModifier(AggregateField.damage_thermal).Value; + DamageToxic = item.GetBasePropertyModifier(AggregateField.damage_toxic).Value; + + ModifierFalloff = (item.GetBasePropertyModifier(AggregateField.falloff).Value * 10).ToString(); + ExplosionRadius = item.GetBasePropertyModifier(AggregateField.explosion_radius).Value; + + // Empty out the 0's + if (DamageChemical == 0) { DamageChemical = null; }; + if (DamageKinetic == 0) { DamageKinetic = null; }; + if (DamageSeismic == 0) { DamageSeismic = null; }; + if (DamageThermal == 0) { DamageThermal = null; }; + if (DamageToxic == 0) { DamageToxic = null; }; + + if (ModifierFalloff == "0") { ModifierFalloff = null; }; // keeping this as a string for now because other modules may use it as a modifier? + if (ExplosionRadius == 0) { ExplosionRadius = null; }; + + // This will get the property even if it doesn't explicitly exist + // It will be set to the default value, but the HasValue will tell + // us if it's something other than the default + + ModifierRange = GetModifierString(item.GetBasePropertyModifier(AggregateField.optimal_range_modifier)); + + var rangeProp = item.GetBasePropertyModifier(AggregateField.optimal_range); + + if (rangeProp.HasValue) { + OptimalRange = rangeProp.Value * 10; + } + } + + } + + +} diff --git a/Perpetuum.DataDumper/Views/ModuleArmorHardenerDataView.cs b/Perpetuum.DataDumper/Views/ModuleArmorHardenerDataView.cs new file mode 100644 index 000000000..b8f6ba7b4 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleArmorHardenerDataView.cs @@ -0,0 +1,68 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleArmorHardenerDataView : ActiveModuleDataView { + + public double ModuleResistActiveChemical { get; set; } + public double ModuleResistPassiveChemical { get; set; } + public double ModuleResistActiveKinetic { get; set; } + public double ModuleResistPassiveKinetic { get; set; } + public double ModuleResistActiveSeismic { get; set; } + public double ModuleResistPassiveSeismic { get; set; } + public double ModuleResistActiveThermal { get; set; } + public double ModuleResistPassiveThermal { get; set; } + public string ModuleResistType { get; set; } + public double ModuleResistPassive { get; set; } + public double ModuleResistActive { get; set; } + + public ModuleArmorHardenerDataView(ActiveModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + FillModuleData(item); + } + + public ModuleArmorHardenerDataView(Module item, DataDumper dumper) { + dumper.InitModuleView(this, item); + + FillModuleData(item); + } + + private void FillModuleData(Module module) { + ModuleResistActiveChemical = module.GetBasePropertyModifier(AggregateField.effect_resist_chemical).Value; + ModuleResistPassiveChemical = module.GetBasePropertyModifier(AggregateField.resist_chemical).Value; + ModuleResistActiveKinetic = module.GetBasePropertyModifier(AggregateField.effect_resist_kinetic).Value; + ModuleResistPassiveKinetic = module.GetBasePropertyModifier(AggregateField.resist_kinetic).Value; + ModuleResistActiveSeismic = module.GetBasePropertyModifier(AggregateField.effect_resist_explosive).Value; + ModuleResistPassiveSeismic = module.GetBasePropertyModifier(AggregateField.resist_explosive).Value; + ModuleResistActiveThermal = module.GetBasePropertyModifier(AggregateField.effect_resist_thermal).Value; + ModuleResistPassiveThermal = module.GetBasePropertyModifier(AggregateField.resist_thermal).Value; + + var passives = new List> { + new Tuple(ModuleResistPassiveChemical,ModuleResistActiveChemical, "Chemical"), + new Tuple(ModuleResistPassiveKinetic, ModuleResistActiveKinetic, "Kinetic"), + new Tuple(ModuleResistPassiveSeismic, ModuleResistActiveSeismic, "Seismic"), + new Tuple(ModuleResistPassiveThermal, ModuleResistActiveThermal, "Thermal") + }; + + if (passives.Where(x => x.Item1 != 0).Count() > 1) { + ModuleResistType = "All"; + ModuleResistPassive = module.GetBasePropertyModifier(AggregateField.resist_chemical).Value; + } else { + var activeType = passives.Where(x => x.Item1 != 0).Single(); + ModuleResistType = activeType.Item3; + ModuleResistPassive = activeType.Item1; + ModuleResistActive = activeType.Item2; + } + } + } + +} diff --git a/Perpetuum.DataDumper/Views/ModuleArmorPlateView.cs b/Perpetuum.DataDumper/Views/ModuleArmorPlateView.cs new file mode 100644 index 000000000..a15c68749 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleArmorPlateView.cs @@ -0,0 +1,26 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleArmorPlateDataView : ModuleDataView { + public double ModuleHp { get; set; } + public double ModuleSurfaceHit { get; set; } + public double ModuleDemobResist { get; set; } + + public ModuleArmorPlateDataView(Module item, DataDumper dumper) { + dumper.InitModuleView(this, item); + + ModuleHp = item.GetBasePropertyModifier(AggregateField.armor_max).Value; + ModuleDemobResist = item.GetBasePropertyModifier(AggregateField.massiveness).Value * 100; + ModuleSurfaceHit = item.GetBasePropertyModifier(AggregateField.signature_radius).Value; + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleArmorRepairerDataView.cs b/Perpetuum.DataDumper/Views/ModuleArmorRepairerDataView.cs new file mode 100644 index 000000000..b7847d420 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleArmorRepairerDataView.cs @@ -0,0 +1,23 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleArmorRepairerDataView : ActiveModuleDataView { + public double ModuleRepairAmount { get; set; } + + public ModuleArmorRepairerDataView(ArmorRepairModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + ModuleRepairAmount = item.GetBasePropertyModifier(AggregateField.armor_repair_amount).Value; + + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleAuxAccumulator.cs b/Perpetuum.DataDumper/Views/ModuleAuxAccumulator.cs new file mode 100644 index 000000000..3a1a08265 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleAuxAccumulator.cs @@ -0,0 +1,22 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleAuxAccumulatorDataView : ModuleDataView { + public double ModuleAccumulatorCapacity { get; set; } + + public ModuleAuxAccumulatorDataView(Module item, DataDumper dumper) { + dumper.InitModuleView(this, item); + + ModuleAccumulatorCapacity = item.GetBasePropertyModifier(AggregateField.core_max).Value; + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleDemobilizerDataView.cs b/Perpetuum.DataDumper/Views/ModuleDemobilizerDataView.cs new file mode 100644 index 000000000..8652dbc68 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleDemobilizerDataView.cs @@ -0,0 +1,22 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleDemobilizerDataView : ActiveModuleDataView { + public string ModuleTopSpeedModifier { get; set; } + + public ModuleDemobilizerDataView(ActiveModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + ModuleTopSpeedModifier = GetModifierString(item.GetBasePropertyModifier(AggregateField.effect_massivness_speed_max_modifier)); + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleERPDataView.cs b/Perpetuum.DataDumper/Views/ModuleERPDataView.cs new file mode 100644 index 000000000..19a7a25bc --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleERPDataView.cs @@ -0,0 +1,29 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleERPDataView : ActiveModuleDataView { + + public double ModuleRecoveryChemical { get; set; } + public double ModuleRecoveryKinetic { get; set; } + public double ModuleRecoverySeismic { get; set; } + public double ModuleRecoveryThermal { get; set; } + + public ModuleERPDataView(Module item, DataDumper dumper) { + dumper.InitModuleView(this, item); + + ModuleRecoveryChemical = item.GetBasePropertyModifier(AggregateField.chemical_damage_to_core_modifier).Value * 100; + ModuleRecoveryKinetic = item.GetBasePropertyModifier(AggregateField.kinetic_damage_to_core_modifier).Value * 100; + ModuleRecoverySeismic = item.GetBasePropertyModifier(AggregateField.explosive_damage_to_core_modifier).Value * 100; + ModuleRecoveryThermal = item.GetBasePropertyModifier(AggregateField.thermal_damage_to_core_modifier).Value * 100; + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleEnergyDrainerDataView.cs b/Perpetuum.DataDumper/Views/ModuleEnergyDrainerDataView.cs new file mode 100644 index 000000000..2ebf4f342 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleEnergyDrainerDataView.cs @@ -0,0 +1,24 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleEnergyDrainerDataView : ActiveModuleDataView { + public double ModuleEnergyTransfer { get; set; } + public double ModuleElectrostaticDispersion { get; set; } + + public ModuleEnergyDrainerDataView(ActiveModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + ModuleEnergyTransfer = item.GetBasePropertyModifier(AggregateField.energy_vampired_amount).Value; + ModuleElectrostaticDispersion = item.GetBasePropertyModifier(AggregateField.energy_dispersion).Value; + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleEnergyInjectorDataView.cs b/Perpetuum.DataDumper/Views/ModuleEnergyInjectorDataView.cs new file mode 100644 index 000000000..30d9d928e --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleEnergyInjectorDataView.cs @@ -0,0 +1,22 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleEnergyInjectorDataView : ActiveModuleDataView { + public int AmmoCapacity { get; set; } + public ModuleEnergyInjectorDataView(ActiveModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + AmmoCapacity = item.AmmoCapacity; + + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleEnergyNeutralizerDataView.cs b/Perpetuum.DataDumper/Views/ModuleEnergyNeutralizerDataView.cs new file mode 100644 index 000000000..09b76e1c2 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleEnergyNeutralizerDataView.cs @@ -0,0 +1,24 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleEnergyNeutralizerDataView : ActiveModuleDataView { + public double ModuleEnergyTransfer { get; set; } + public double ModuleElectrostaticDispersion { get; set; } + + public ModuleEnergyNeutralizerDataView(ActiveModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + ModuleEnergyTransfer = item.GetBasePropertyModifier(AggregateField.energy_neutralized_amount).Value; + ModuleElectrostaticDispersion = item.GetBasePropertyModifier(AggregateField.energy_dispersion).Value; + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleEnergyTransfererDataView.cs b/Perpetuum.DataDumper/Views/ModuleEnergyTransfererDataView.cs new file mode 100644 index 000000000..bad49d0b0 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleEnergyTransfererDataView.cs @@ -0,0 +1,22 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleEnergyTransfererDataView : ActiveModuleDataView { + public double ModuleEnergyTransfer { get; set; } + + public ModuleEnergyTransfererDataView(ActiveModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + ModuleEnergyTransfer = item.GetBasePropertyModifier(AggregateField.energy_transfer_amount).Value; + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleHarvesterDataView.cs b/Perpetuum.DataDumper/Views/ModuleHarvesterDataView.cs new file mode 100644 index 000000000..d9c479e11 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleHarvesterDataView.cs @@ -0,0 +1,24 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleHarvesterDataView : ActiveModuleDataView { + public double ModuleMiningModifier { get; set; } + public int AmmoCapacity { get; set; } + + public ModuleHarvesterDataView(GathererModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + ModuleMiningModifier = item.GetBasePropertyModifier(AggregateField.mining_amount_modifier).Value; + AmmoCapacity = item.AmmoCapacity; + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleMinerDataView.cs b/Perpetuum.DataDumper/Views/ModuleMinerDataView.cs new file mode 100644 index 000000000..b8df9ee71 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleMinerDataView.cs @@ -0,0 +1,24 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleMinerDataView : ActiveModuleDataView { + public double ModuleMiningModifier { get; set; } + public int AmmoCapacity { get; set; } + + public ModuleMinerDataView(DrillerModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + ModuleMiningModifier = item.GetBasePropertyModifier(AggregateField.mining_amount_modifier).Value; + AmmoCapacity = item.AmmoCapacity; + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleNexusDataView.cs b/Perpetuum.DataDumper/Views/ModuleNexusDataView.cs new file mode 100644 index 000000000..fe32eb440 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleNexusDataView.cs @@ -0,0 +1,76 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleNexusDataView : ActiveModuleDataView { + public string NexusCategory { get; set; } + public string NexusPropertyName { get; set; } + public string NexusPropertyValue { get; set; } + public double ModuleEffectRadius { get; set; } + public string ModuleEffectRadiusModifier { get; set; } + + static List fixedModifiers = new List { + AggregateField.core_usage, AggregateField.cpu_usage, + AggregateField.cycle_time, AggregateField.default_effect_range, + AggregateField.powergrid_usage, AggregateField.effect_enhancer_aura_radius_modifier }; + + private string GetModuleType(GangModule item) { + if (item.IsCategory(CategoryFlags.cf_gang_assist_speed)) { + return "Velocity"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_information)) { + return "Farlock"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_industry)) { + return "Industrial"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_siege)) { + return "Assault"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_defense)) { + return "Armor"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_ewar)) { + return "EW"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_shared_dataprocessing)) { + return "Lock Booster"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_coordinated_manuevering)) { + return "Evasive"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_maintance)) { + return "Repairer"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_precision_firing)) { + return "Critical Hit"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_core_management)) { + return "Recharger"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_fast_extracting)) { + return "Fast Extractor"; + } else if (item.IsCategory(CategoryFlags.cf_gang_assist_shield_calculations)) { + return "Shield"; + } else { + return ""; + } + } + + public ModuleNexusDataView(GangModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + var specialProperty = item.BasePropertyModifiers.All.Where(x => !fixedModifiers.Contains(x.Field)).Single(); + + NexusCategory = GetModuleType(item); + + NexusPropertyName = dumper.GetLocalizedName(specialProperty.Field.ToString()); + NexusPropertyValue = GetModifierString(specialProperty); + + ModuleEffectRadius = item.GetBasePropertyModifier(AggregateField.default_effect_range).Value; + + var radiusMod = item.GetBasePropertyModifier(AggregateField.effect_enhancer_aura_radius_modifier); + + if (radiusMod.HasValue) { + ModuleEffectRadiusModifier = GetModifierString(radiusMod); + } + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleRemoteArmorRepairerDataView.cs b/Perpetuum.DataDumper/Views/ModuleRemoteArmorRepairerDataView.cs new file mode 100644 index 000000000..76057e2b5 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleRemoteArmorRepairerDataView.cs @@ -0,0 +1,25 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleRemoteArmorRepairerDataView : ActiveModuleDataView { + + public double module_repair_amount { get; set; } + public double module_optimal_range { get; set; } + + public ModuleRemoteArmorRepairerDataView(ActiveModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + module_optimal_range = item.GetBasePropertyModifier(AggregateField.optimal_range).Value * 10; + module_repair_amount = item.GetBasePropertyModifier(AggregateField.armor_repair_amount).Value; + } + } +} \ No newline at end of file diff --git a/Perpetuum.DataDumper/Views/ModuleShieldGeneratorDataView.cs b/Perpetuum.DataDumper/Views/ModuleShieldGeneratorDataView.cs new file mode 100644 index 000000000..b68a83f06 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleShieldGeneratorDataView.cs @@ -0,0 +1,25 @@ +using Perpetuum.Containers; +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleShieldGeneratorDataView : ActiveModuleDataView { + + public double module_shield_radius { get; set; } + public double module_absorption_ratio { get; set; } + + public ModuleShieldGeneratorDataView(ActiveModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + module_shield_radius = item.GetBasePropertyModifier(AggregateField.shield_radius).Value; + module_absorption_ratio = Math.Round(1 / item.GetBasePropertyModifier(AggregateField.shield_absorbtion).Value, 3); + } + } +} diff --git a/Perpetuum.DataDumper/Views/ModuleWeaponDataView.cs b/Perpetuum.DataDumper/Views/ModuleWeaponDataView.cs new file mode 100644 index 000000000..c295d64d8 --- /dev/null +++ b/Perpetuum.DataDumper/Views/ModuleWeaponDataView.cs @@ -0,0 +1,76 @@ +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Modules.Weapons; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class ModuleWeaponDataView : ActiveModuleDataView { + public string AmmoType { get; set; } + public int AmmoCapacity { get; set; } + public double ModuleDamage { get; set; } + public double ModuleFalloff { get; set; } + public double ModuleHitDispersion { get; set; } + public string MissileOptimalRange { get; set; } + + private List SlotFlagValues; + public string SlotFlags { + get { + return String.Join(";", SlotFlagValues.Select(x => x.ToString())); + } + set { + SlotFlagValues = EnumHelper.MaskToList((SlotFlags)Convert.ToInt64(value)).ToList(); + } + } + public string SlotType { + get { + return SlotFlagValues.Intersect(SLOT_TYPE_FLAGS).SingleOrDefault().ToString(); + } + } + + public string SlotSize { + get { + return SlotFlagValues.Intersect(SLOT_SIZE_FLAGS).SingleOrDefault().ToString(); + } + } + + public string SlotLocation { + get { + return SlotFlagValues.Intersect(SLOT_LOCATION_FLAGS).SingleOrDefault().ToString(); + } + } + + public ModuleWeaponDataView(WeaponModule item, DataDumper dumper) { + dumper.InitActiveModuleView(this, item); + + var dictionaryData = item.ToDictionary(); + + dictionaryData["ammoCategoryFlags"] = (CategoryFlags)dictionaryData["ammoCategoryFlags"]; + + AmmoType = dumper.GetLocalizedName(((CategoryFlags)dictionaryData["ammoCategoryFlags"]).ToString()).Replace(";undefined", ""); + SlotFlags = item.ModuleFlag.ToString(); + AmmoCapacity = item.AmmoCapacity; + ModuleDamage = item.DamageModifier.Value * 100; + ModuleFalloff = item.Properties.Single(x => x.Field == AggregateField.falloff).Value * 10; + ModuleHitDispersion = item.Accuracy.Value; + + var rangeModifierProperty = item.GetBasePropertyModifier(AggregateField.module_missile_range_modifier); + + if (rangeModifierProperty.HasValue) { + string directionSymbol = "+"; + + if (rangeModifierProperty.Value < 0) { + directionSymbol = "-"; + } + + MissileOptimalRange = directionSymbol + (rangeModifierProperty.Value - 1) * 100 + "%"; + + } + } + + } +} diff --git a/Perpetuum.DataDumper/Views/RobotDataView.cs b/Perpetuum.DataDumper/Views/RobotDataView.cs new file mode 100644 index 000000000..df7419dcf --- /dev/null +++ b/Perpetuum.DataDumper/Views/RobotDataView.cs @@ -0,0 +1,142 @@ +using Perpetuum.ExportedTypes; +using Perpetuum.Modules; +using Perpetuum.Robots; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class RobotDataView : ItemDataView { + // Main Stats + public double Speed { get; set; } + public double Armor { get; set; } + public double Accumulator { get; set; } + public double Cargo { get; set; } + public double Cpu { get; set; } + public double Reactor { get; set; } + public double SlopeCapacity { get; set; } + + // Slots + public int SlotsHead { get; set; } + public int SlotsLeg { get; set; } + public int SlotsChassis { get; set; } + public int SlotsGuns { get; set; } + public int SlotsMissiles { get; set; } + public int SlotsIndustrial { get; set; } + public int SlotsMisc { get; set; } + + // Defense + public double SurfaceSize { get; set; } + public double ResistanceChem { get; set; } + public double ResistanceKinetic { get; set; } + public double ResistanceSeismic { get; set; } + public double ResistanceThermal { get; set; } + public double ResistanceDemobilizer { get; set; } + + // Targeting + public double SensorStrength { get; set; } + public double LockingRange { get; set; } + public double LockingTime { get; set; } + public double MaxLockedTargets { get; set; } + public double SignalDetection { get; set; } + public double SignalMasking { get; set; } + + // Misc + public double AccumulatorRecharge { get; set; } + public double AccumulatorStability { get; set; } + public double InterferenceEmission { get; set; } + public double InterferenceRadius { get; set; } + public double InterferenceMin { get; set; } + public double InterferenceMax { get; set; } + + public RobotDataView(Robot input, DataDumper dumper) { + dumper.InitItemView(this, input); + + var dictionaryData = input.ToDictionary(); + + RobotHead head = input.GetRobotComponent(); + RobotChassis chassis = input.GetRobotComponent(); + RobotLeg legs = input.GetRobotComponent(); + RobotInventory inventory = input.Components.OfType().SingleOrDefault(); + + var allSlotFlags = head.ED.Options.SlotFlags + .Concat(chassis.ED.Options.SlotFlags) + .Concat(legs.ED.Options.SlotFlags).ToList(); + + var typeFlags = new List(); + + foreach (var slotFlags in allSlotFlags) { + var currentSlotTypes = EnumHelper.MaskToList((SlotFlags)Convert.ToInt64(slotFlags)).ToList() + .Intersect(SLOT_TYPE_FLAGS).ToList(); + + typeFlags.AddRange(currentSlotTypes); + } + + + // main Stats + Speed = (double)input.Properties.SingleOrDefault(x=> x.Field == AggregateField.speed_max).Value * 36; // needs to be multiplied by 36 + Armor = input.ArmorMax; + Accumulator = input.CoreMax; + Cargo = (double) inventory.GetCapacityInfo()["capacity"]; + Cpu = input.Cpu; + // The Max property is what we want, but it's not public and since this is a fake robot it will equal max + Reactor = input.PowerGrid; + + if (input.Slope == 4) { + SlopeCapacity = 45; + } else if (input.Slope == 5) { + SlopeCapacity= 51; + } else if (input.Slope == 6) { + SlopeCapacity= 56; + } else { + SlopeCapacity = input.Slope; + } + + // Slots + SlotsHead = head.MaxSlots; + SlotsChassis = chassis.MaxSlots; + SlotsLeg = legs.MaxSlots; + SlotsGuns = typeFlags.Where(x => x == SlotFlags.turret).Count(); + SlotsMissiles = typeFlags.Where(x => x == SlotFlags.missile).Count(); + SlotsIndustrial = typeFlags.Where(x => x == SlotFlags.industrial).Count(); + SlotsMisc = typeFlags.Where(x => x == SlotFlags.ew_and_engineering).Count(); + + // Defense + SurfaceSize = input.SignatureRadius; + ResistanceChem = input.GetPropertyModifier(AggregateField.resist_chemical).Value; + ResistanceKinetic = input.GetPropertyModifier(AggregateField.resist_kinetic).Value; + ResistanceSeismic = input.GetPropertyModifier(AggregateField.resist_explosive).Value; + ResistanceThermal = input.GetPropertyModifier(AggregateField.resist_thermal).Value; + ResistanceDemobilizer = 0; // input.GetPropertyModifier(AggregateField.effect_massivness_speed_max_modifier).Value; + + + // Targeting + SensorStrength = input.SensorStrength; // input.GetPropertyModifier(AggregateField.sensor_strength).Value; + + // Same as input.GetPropertyModifier(AggregateField.locking_range).Value * 10; + LockingRange = input.MaxTargetingRange * 10; + LockingTime = input.GetPropertyModifier(AggregateField.locking_time).Value / 1000; + MaxLockedTargets = input.GetPropertyModifier(AggregateField.locked_targets_max).Value; + SignalDetection = input.DetectionStrength; + SignalMasking = input.StealthStrength; + + // Misc + AccumulatorRecharge = input.CoreRechargeTime.TotalSeconds; + AccumulatorStability = input.ReactorRadiation; + InterferenceEmission = input.GetPropertyModifier(AggregateField.blob_emission).Value; // Same as input.BlobEmission but it's not public + InterferenceRadius = input.GetPropertyModifier(AggregateField.blob_emission_radius).Value * 10; // Same as input.BlobEmissionRadius but it's not public + InterferenceMin = input.GetPropertyModifier(AggregateField.blob_level_low).Value; + InterferenceMax = input.GetPropertyModifier(AggregateField.blob_level_high).Value; + + // Required Extensions + var testExt = input.ExtensionBonusEnablerExtensions.ToList(); + var test2 = input.ED.EnablerExtensions; // Extensions required (Extension + Level) + var test3 = input.RobotComponents.SelectMany(component => component.ExtensionBonuses).ToList(); // Bonuses from extension + + // Extension Bonuses + } + } +} diff --git a/Perpetuum.DataDumper/Views/SparkDataView.cs b/Perpetuum.DataDumper/Views/SparkDataView.cs new file mode 100644 index 000000000..93b5b7194 --- /dev/null +++ b/Perpetuum.DataDumper/Views/SparkDataView.cs @@ -0,0 +1,95 @@ +using NPOI.POIFS.Storage; +using Perpetuum.Groups.Alliances; +using Perpetuum.Items.Ammos; +using Perpetuum.Services.ExtensionService; +using Perpetuum.Services.Sparks; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Perpetuum.DataDumper.DataDumper; + +namespace Perpetuum.DataDumper.Views { + public class SparkDataView : EntityDataView { + public double? price_purchase { get; set; } + public double? price_equip { get; set; } + public double? required_standing { get; set; } + public int sequence { get; set; } + public string icon { get; set; } + public string extensions { get; set; } + public string alliance { get; set; } + public string energy_prop { get; set; } + + public SparkDataView(Spark spark, DataDumper dumper) { + + ItemName = dumper.GetLocalizedName(spark.sparkName); + ItemKey = spark.sparkName; + ItemCategories = new List(); // No categories + price_equip = spark.changePrice; + price_purchase = spark.unlockPrice; + required_standing = spark.standingLimit * 100; + sequence = spark.displayOrder; + icon = spark.icon; + energy_prop = spark.energyCredit.ToString(); + + if (spark.allianceEid.HasValue) { + // For some reason the Alliance object doesn't pull over the name + // so we need to pull it as an eneity + // var currentAlliance = Alliance.Repository.Load(spark.allianceEid); + + // Trying as an entity doesn't work either + // var currentAlliance = entityServices.Repository.Load(.Value); + + + var allianceData = AllianceHelper.GetAllianceInfo(); + + foreach (var allianceInfo in allianceData) { + var childDict = (Dictionary)allianceInfo.Value; + long allianceEid = (long)childDict["allianceEID"]; + string allianceName = (string)childDict["name"]; + + if (allianceEid == spark.allianceEid) { + alliance = dumper.GetLocalizedName(allianceName); + break; + } + } + } + + var extensionsDict = new Dictionary(); + var extensionStrings = new List(); + + foreach (Extension extension in spark.RelatedExtensions) { + var extensionInfo = dumper.ExtensionReader.GetExtensionByID(extension.id); + + extensionsDict.Add(extensionInfo.name, extension.level); + + string localName = SparkBonusString(extensionInfo.name, extension.level, dumper); + + extensionStrings.Add(localName); + + } + + this.extensions = String.Join(";", extensionStrings); + } + + private string SparkBonusString(string extensionName, int value, DataDumper dumper) { + var formulaStrings = new List { "{%BONUS100%}", "{%BONUS%}" }; + + // First check if the localized name exists + var localName = dumper.GetLocalizedName(extensionName); + + if (localName == extensionName) { + // This means the desc wasn't found + localName = dumper.GetLocalizedName(extensionName + "_desc"); + + foreach (var formula in formulaStrings) { + localName = localName.Replace(formula, value.ToString()); + } + + } + + return localName; + } + } +} diff --git a/Perpetuum.DataDumper/packages.config b/Perpetuum.DataDumper/packages.config new file mode 100644 index 000000000..0adae8da2 --- /dev/null +++ b/Perpetuum.DataDumper/packages.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Perpetuum.sln b/Perpetuum.sln index bab491d9c..f2f5db153 100644 --- a/Perpetuum.sln +++ b/Perpetuum.sln @@ -28,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perpetuum.Bootstrapper", "s EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perpetuum.ServerService", "src\Perpetuum.ServerService\Perpetuum.ServerService.csproj", "{9C77CE95-825E-4BB1-9129-66835BDB8C96}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perpetuum.DataDumper", "Perpetuum.DataDumper\Perpetuum.DataDumper.csproj", "{55911748-316C-43CA-B703-47DBF77AC171}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -122,12 +124,25 @@ Global {9C77CE95-825E-4BB1-9129-66835BDB8C96}.Release|x64.Build.0 = Release|Any CPU {9C77CE95-825E-4BB1-9129-66835BDB8C96}.Release|x86.ActiveCfg = Release|Any CPU {9C77CE95-825E-4BB1-9129-66835BDB8C96}.Release|x86.Build.0 = Release|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Debug|x64.ActiveCfg = Debug|x64 + {55911748-316C-43CA-B703-47DBF77AC171}.Debug|x64.Build.0 = Debug|x64 + {55911748-316C-43CA-B703-47DBF77AC171}.Debug|x86.ActiveCfg = Debug|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Debug|x86.Build.0 = Debug|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Release|Any CPU.Build.0 = Release|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Release|x64.ActiveCfg = Release|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Release|x64.Build.0 = Release|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Release|x86.ActiveCfg = Release|Any CPU + {55911748-316C-43CA-B703-47DBF77AC171}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {4736AD6B-6565-4EEF-ABCB-19454342A986} = {7DE0E6B2-17B2-4988-9A45-BC3FA49AB223} + {55911748-316C-43CA-B703-47DBF77AC171} = {7DE0E6B2-17B2-4988-9A45-BC3FA49AB223} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DEB5AFE6-BD52-405C-BA07-8D5E7FC9B57C} diff --git a/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs b/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs index abff49268..8f227d099 100644 --- a/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs +++ b/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs @@ -185,20 +185,20 @@ namespace Perpetuum.Bootstrapper { - class EntityAggregateServices : IEntityServices + public class EntityAggregateServices : IEntityServices { public IEntityFactory Factory { get; set; } public IEntityDefaultReader Defaults { get; set; } public IEntityRepository Repository { get; set; } } - - class RobotTemplateServicesImpl : IRobotTemplateServices + + public class RobotTemplateServicesImpl : IRobotTemplateServices { public IRobotTemplateReader Reader { get; set; } public IRobotTemplateRelations Relations { get; set; } } - class TeleportStrategyFactoriesImpl : ITeleportStrategyFactories + public class TeleportStrategyFactoriesImpl : ITeleportStrategyFactories { public TeleportWithinZone.Factory TeleportWithinZoneFactory { get; set; } public TeleportToAnotherZone.Factory TeleportToAnotherZoneFactory { get; set; } diff --git a/src/Perpetuum/EntityFramework/EntityFactory.cs b/src/Perpetuum/EntityFramework/EntityFactory.cs index 1da163065..01cf32102 100644 --- a/src/Perpetuum/EntityFramework/EntityFactory.cs +++ b/src/Perpetuum/EntityFramework/EntityFactory.cs @@ -67,5 +67,4 @@ public Entity Create(EntityDefault entityDefault,IIDGenerator idGenerator) return entity; } } -} - +} \ No newline at end of file diff --git a/src/Perpetuum/Modules/SlotFlags.cs b/src/Perpetuum/Modules/SlotFlags.cs index 9e56fa365..5d7e2b1c7 100644 --- a/src/Perpetuum/Modules/SlotFlags.cs +++ b/src/Perpetuum/Modules/SlotFlags.cs @@ -1,20 +1,24 @@ -namespace Perpetuum.Modules +using System; + +namespace Perpetuum.Modules { + /// Doc - These are powers of 2 /// /// Types for module slots /// + [Flags] public enum SlotFlags { - turret, - missile, - melee, - head, - chassis, - leg, - small, - medium, - large, - industrial, - ew_and_engineering + turret = 1, + missile = 2, + melee = 4, + head = 8, + chassis = 16, + leg = 32, + small = 64, + medium = 128, + large = 256, + industrial = 512, + ew_and_engineering = 1024 } } \ No newline at end of file