├── Assets
├── MKMT.psd
├── mkmt.ico
└── mkmt.png
├── MKMTool
├── mkmt.ico
├── doc
│ ├── mainWindow.png
│ ├── checkCheapDeals.png
│ ├── priceExternalList.png
│ └── updatePriceSettings.png
├── packages.config
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── Resources.Designer.cs
│ ├── AssemblyInfo.cs
│ └── Resources.resx
├── AccountInfo.Designer.cs
├── Program.cs
├── SettingPresetStore.cs
├── PopupListbox.cs
├── MKMTool.licenseheader
├── AccountInfo.cs
├── App.config
├── config_template.xml
├── StockView.Designer.cs
├── MKMPriceAsFormula.cs
├── StockView.resx
├── AccountInfo.resx
├── PopupListbox.resx
├── WantlistEditorView.resx
├── checkDisplayPrices.resx
├── PriceExternalList.resx
├── CheckWantsView.resx
├── PopupListbox.Designer.cs
├── MKMAuth.cs
├── SettingPresetStore.Designer.cs
├── StockView.cs
├── MKMCsvUtils.cs
├── checkDisplayPrices.Designer.cs
├── CheckDisplayPrices.cs
├── MKMTool.csproj
├── WantlistEditorView.Designer.cs
└── WantlistEditorView.cs
├── Presets
├── default.xml
├── generate new prices.xml
└── cheap, small changes only.xml
├── MKMTool.sln
├── .gitignore
└── .editorconfig
/Assets/MKMT.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexander-pick/MKMTool/HEAD/Assets/MKMT.psd
--------------------------------------------------------------------------------
/Assets/mkmt.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexander-pick/MKMTool/HEAD/Assets/mkmt.ico
--------------------------------------------------------------------------------
/Assets/mkmt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexander-pick/MKMTool/HEAD/Assets/mkmt.png
--------------------------------------------------------------------------------
/MKMTool/mkmt.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexander-pick/MKMTool/HEAD/MKMTool/mkmt.ico
--------------------------------------------------------------------------------
/MKMTool/doc/mainWindow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexander-pick/MKMTool/HEAD/MKMTool/doc/mainWindow.png
--------------------------------------------------------------------------------
/MKMTool/doc/checkCheapDeals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexander-pick/MKMTool/HEAD/MKMTool/doc/checkCheapDeals.png
--------------------------------------------------------------------------------
/MKMTool/doc/priceExternalList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexander-pick/MKMTool/HEAD/MKMTool/doc/priceExternalList.png
--------------------------------------------------------------------------------
/MKMTool/doc/updatePriceSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexander-pick/MKMTool/HEAD/MKMTool/doc/updatePriceSettings.png
--------------------------------------------------------------------------------
/MKMTool/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MKMTool/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 0
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Presets/default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Presets/generate new prices.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 3;3.00;10;2.00;50;1.00;999999;0.10;
5 |
--------------------------------------------------------------------------------
/Presets/cheap, small changes only.xml:
--------------------------------------------------------------------------------
1 |
2 | 1;2.00;5;0.25;10;0.15;50;0.10;100;0.05;999999;0.03;
3 | 1;3.00;2;0.50;3;0.25;6;0.20;10;0.15;20;0.08;100;0.05;999999;0.03;
4 |
--------------------------------------------------------------------------------
/MKMTool.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30128.74
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MKMTool", "MKMTool\MKMTool.csproj", "{EF8BE2AC-A470-4EBA-9147-0840DFE9DCE2}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{46F85A5F-85B7-42E5-A8BD-48C7808C96AF}"
9 | ProjectSection(SolutionItems) = preProject
10 | .editorconfig = .editorconfig
11 | EndProjectSection
12 | EndProject
13 | Global
14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
15 | Debug|Any CPU = Debug|Any CPU
16 | Release|Any CPU = Release|Any CPU
17 | EndGlobalSection
18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
19 | {EF8BE2AC-A470-4EBA-9147-0840DFE9DCE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {EF8BE2AC-A470-4EBA-9147-0840DFE9DCE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {EF8BE2AC-A470-4EBA-9147-0840DFE9DCE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
22 | {EF8BE2AC-A470-4EBA-9147-0840DFE9DCE2}.Release|Any CPU.Build.0 = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(SolutionProperties) = preSolution
25 | HideSolutionNode = FALSE
26 | EndGlobalSection
27 | GlobalSection(ExtensibilityGlobals) = postSolution
28 | SolutionGuid = {24066089-EEFF-4EBE-BC23-B00D917B9BAD}
29 | EndGlobalSection
30 | EndGlobal
31 |
--------------------------------------------------------------------------------
/MKMTool/AccountInfo.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace MKMTool
2 | {
3 | partial class AccountInfo
4 | {
5 | /// Required designer variable.
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | /// Clean up any resources being used.
9 | /// true if managed resources should be disposed; otherwise, false.
10 | protected override void Dispose(bool disposing)
11 | {
12 | if (disposing && (components != null))
13 | {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | /// Required method for Designer support - do not modify
22 | /// the contents of this method with the code editor.
23 | private void InitializeComponent()
24 | {
25 | this.treeView1 = new System.Windows.Forms.TreeView();
26 | this.SuspendLayout();
27 | //
28 | // treeView1
29 | //
30 | this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
31 | this.treeView1.Location = new System.Drawing.Point(0, 0);
32 | this.treeView1.Margin = new System.Windows.Forms.Padding(6);
33 | this.treeView1.Name = "treeView1";
34 | this.treeView1.Size = new System.Drawing.Size(864, 981);
35 | this.treeView1.TabIndex = 0;
36 | //
37 | // AccountInfo
38 | //
39 | this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
40 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
41 | this.ClientSize = new System.Drawing.Size(864, 981);
42 | this.Controls.Add(this.treeView1);
43 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
44 | this.Margin = new System.Windows.Forms.Padding(6);
45 | this.MaximizeBox = false;
46 | this.Name = "AccountInfo";
47 | this.ShowIcon = false;
48 | this.Text = "Your MKM Account Info";
49 | this.ResumeLayout(false);
50 |
51 | }
52 |
53 | #endregion
54 |
55 | private System.Windows.Forms.TreeView treeView1;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/MKMTool/Program.cs:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of MKMTool
3 |
4 | MKMTool is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | MKMTool is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with MKMTool. If not, see .
16 |
17 | Diese Datei ist Teil von MKMTool.
18 |
19 | MKMTool ist Freie Software: Sie können es unter den Bedingungen
20 | der GNU General Public License, wie von der Free Software Foundation,
21 | Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
22 | veröffentlichten Version, weiterverbreiten und/oder modifizieren.
23 |
24 | MKMTool wird in der Hoffnung, dass es nützlich sein wird, aber
25 | OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
26 | Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
27 | Siehe die GNU General Public License für weitere Details.
28 |
29 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
30 | Programm erhalten haben. Wenn nicht, siehe .
31 | */
32 | using System;
33 | using System.Windows.Forms;
34 |
35 | namespace MKMTool
36 | {
37 | internal static class Program
38 | {
39 | /// The main entry point for the application.
40 | [STAThread]
41 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Keep capital M for Main()")]
42 | private static void Main()
43 | {
44 | Application.EnableVisualStyles();
45 | Application.SetCompatibleTextRenderingDefault(false);
46 | Application.Run(MainView.Instance);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/MKMTool/SettingPresetStore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 | using System.IO;
4 |
5 | namespace MKMTool
6 | {
7 | /// A small dialog window for inputing name of the xml file to which to store MKMBotSettings Preset.
8 | ///
9 | public partial class SettingPresetStore : Form
10 | {
11 | private readonly MKMBotSettings toStore;
12 | private string chosenName;
13 |
14 | public SettingPresetStore(MKMBotSettings toStore)
15 | {
16 | InitializeComponent();
17 | this.toStore = toStore;
18 | }
19 |
20 | /// Gets the name finally chosen by the user for the preset.
21 | /// The name chosen for the preset (without the ".xml" extension).
22 | public string GetChosenName()
23 | {
24 | return chosenName;
25 | }
26 |
27 | private void buttonStore_Click(object sender, EventArgs e)
28 | {
29 | try
30 | {
31 | FileInfo f = new FileInfo(@".//Presets//" + textBoxFileName.Text + ".xml");
32 | if (f.Exists)
33 | {
34 | if (MessageBox.Show("Preset with this name already exists.\nOverwrite?", "Preset already exists",
35 | MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
36 | return;
37 | }
38 | toStore.Description = textBoxDescription.Text;
39 | // first try to write it into a memory stream to see if Save() finishes correctly
40 | // only if it does, delete the previous file (if there was one) and write into it
41 | MemoryStream ms = new MemoryStream();
42 | toStore.Serialize().Save(ms);
43 | if (f.Exists)
44 | f.Delete();
45 | FileStream fs = f.OpenWrite();
46 | ms.Position = 0;
47 | ms.CopyTo(fs);
48 | ms.Close();
49 | fs.Close();
50 | chosenName = textBoxFileName.Text;
51 | DialogResult = DialogResult.OK;
52 | Close();
53 | }
54 | catch (Exception exc)
55 | {
56 | MessageBox.Show("Saving preset to a file failed (make sure the name is a valid name for a file):"
57 | + Environment.NewLine + Environment.NewLine + exc.Message + Environment.NewLine,
58 | "Storing preset failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
59 | }
60 | }
61 |
62 | private void buttonCancel_Click(object sender, EventArgs e)
63 | {
64 | DialogResult = DialogResult.Cancel;
65 | Close();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/MKMTool/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MKMTool.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.6.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("")]
29 | public string LastSettingsPreset {
30 | get {
31 | return ((string)(this["LastSettingsPreset"]));
32 | }
33 | set {
34 | this["LastSettingsPreset"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("")]
41 | public string LastSettingsPresetExtList {
42 | get {
43 | return ((string)(this["LastSettingsPresetExtList"]));
44 | }
45 | set {
46 | this["LastSettingsPresetExtList"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("0")]
53 | public uint LastUpdatedArticle {
54 | get {
55 | return ((uint)(this["LastUpdatedArticle"]));
56 | }
57 | set {
58 | this["LastUpdatedArticle"] = value;
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/MKMTool/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MKMTool.Properties
12 | {
13 | using System;
14 |
15 |
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | // This class was auto-generated by the StronglyTypedResourceBuilder
18 | // class via a tool like ResGen or Visual Studio.
19 | // To add or remove a member, edit your .ResX file then rerun ResGen
20 | // with the /str option, or rebuild your VS project.
21 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
22 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
23 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
24 | internal class Resources
25 | {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources()
33 | {
34 | }
35 |
36 | /// Returns the cached ResourceManager instance used by this class.
37 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
38 | internal static global::System.Resources.ResourceManager ResourceManager
39 | {
40 | get
41 | {
42 | if (object.ReferenceEquals(resourceMan, null))
43 | {
44 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MKMTool.Properties.Resources", typeof(Resources).Assembly);
45 | resourceMan = temp;
46 | }
47 | return resourceMan;
48 | }
49 | }
50 |
51 | /// Overrides the current thread's CurrentUICulture property for all
52 | /// resource lookups using this strongly typed resource class.
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture
55 | {
56 | get
57 | {
58 | return resourceCulture;
59 | }
60 | set
61 | {
62 | resourceCulture = value;
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/MKMTool/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of MKMTool
3 |
4 | MKMTool is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | MKMTool is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with MKMTool. If not, see .
16 |
17 | Diese Datei ist Teil von MKMTool.
18 |
19 | MKMTool ist Freie Software: Sie können es unter den Bedingungen
20 | der GNU General Public License, wie von der Free Software Foundation,
21 | Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
22 | veröffentlichten Version, weiterverbreiten und/oder modifizieren.
23 |
24 | MKMTool wird in der Hoffnung, dass es nützlich sein wird, aber
25 | OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
26 | Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
27 | Siehe die GNU General Public License für weitere Details.
28 |
29 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
30 | Programm erhalten haben. Wenn nicht, siehe .
31 | */
32 | using System.Reflection;
33 | using System.Runtime.InteropServices;
34 |
35 | // General Information about an assembly is controlled through the following
36 | // set of attributes. Change these attribute values to modify the information
37 | // associated with an assembly.
38 |
39 | [assembly: AssemblyTitle("MKMTool")]
40 | [assembly: AssemblyDescription("")]
41 | [assembly: AssemblyConfiguration("")]
42 | [assembly: AssemblyCompany("")]
43 | [assembly: AssemblyProduct("MKMTool")]
44 | [assembly: AssemblyCopyright("Copyright © 2017")]
45 | [assembly: AssemblyTrademark("")]
46 | [assembly: AssemblyCulture("")]
47 |
48 | // Setting ComVisible to false makes the types in this assembly not visible
49 | // to COM components. If you need to access a type in this assembly from
50 | // COM, set the ComVisible attribute to true on that type.
51 |
52 | [assembly: ComVisible(false)]
53 |
54 | // The following GUID is for the ID of the typelib if this project is exposed to COM
55 |
56 | [assembly: Guid("ef8be2ac-a470-4eba-9147-0840dfe9dce2")]
57 |
58 | // Version information for an assembly consists of the following four values:
59 | //
60 | // Major Version
61 | // Minor Version
62 | // Build Number
63 | // Revision
64 | //
65 | // You can specify all the values or you can default the Build and Revision Numbers
66 | // by using the '*' as shown below:
67 | // [assembly: AssemblyVersion("1.0.*")]
68 |
69 | [assembly: AssemblyVersion("1.0.0.0")]
70 | [assembly: AssemblyFileVersion("0.8.2.2")]
71 |
--------------------------------------------------------------------------------
/MKMTool/PopupListbox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Forms;
4 |
5 | namespace MKMTool
6 | {
7 | /// A simple window with title, confirm button and a list-box allowing multiple choice from the specified list.
8 | ///
9 | public partial class PopupListbox : Form
10 | {
11 | /// Initializes a new instance of the class.
12 | /// Title will be displayed both above the list box as well as the window title.
13 | public PopupListbox(string title)
14 | {
15 | InitializeComponent();
16 | Text = title;
17 | labelTitle.Text = title;
18 | }
19 |
20 | private void buttonConfirm_Click(object sender, EventArgs e)
21 | {
22 | DialogResult = DialogResult.OK;
23 | Close();
24 | }
25 |
26 | /// Sets the collection to use to create entries in the list.
27 | /// - does not reset current selection.
28 | /// The data source to use to populate the list-box.
29 | public void SetDataSource(List dataSource)
30 | {
31 | listBoxContent.DataSource = dataSource;
32 | }
33 |
34 | /// If some of the string in the specified dataSource are not in the list-box yet, they will be added.
35 | /// The data source to populate the list-box.
36 | public void UpdateDataSource(List dataSource)
37 | {
38 | foreach (string s in dataSource)
39 | {
40 | if (!listBoxContent.Items.Contains(s))
41 | listBoxContent.Items.Add(s);
42 | }
43 | }
44 |
45 | /// Gathers all the selected items and returns them.
46 | /// Collection of names of the selected items.
47 | public List GetSelected()
48 | {
49 | List ret = new List();
50 | foreach (var selected in listBoxContent.SelectedItems)
51 | ret.Add(selected.ToString());
52 | return ret;
53 | }
54 |
55 | /// Sets the specified items as selected. Make sure to call SetDataSource before this.
56 | /// The list of item names to select. Items not in the list will be deselected.
57 | /// Items in this list not existing in the data source of this PopupListbox will be ignored.
58 | public void SetSelected(List selected)
59 | {
60 | listBoxContent.ClearSelected();
61 | // for each selected string, find if it is in the list-box's list and if so, set to true
62 | // this is more efficient assuming selected.Count << listBoxContent.Items.Count
63 | foreach (string s in selected)
64 | {
65 | int index = listBoxContent.Items.IndexOf(s);
66 | if (index != -1)
67 | listBoxContent.SetSelected(index, true);
68 | }
69 | }
70 |
71 | private void listBoxContent_SelectedValueChanged(object sender, EventArgs e)
72 | {
73 | buttonConfirm.Text = "OK (" + listBoxContent.SelectedItems.Count + " selected)";
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/MKMTool/MKMTool.licenseheader:
--------------------------------------------------------------------------------
1 | extensions: designer.cs generated.cs
2 | extensions: .cs .cpp .h
3 | /*
4 | This file is part of MKMTool
5 |
6 | MKMTool is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | MKMTool is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with MKMTool. If not, see .
18 |
19 | Diese Datei ist Teil von MKMTool.
20 |
21 | MKMTool ist Freie Software: Sie können es unter den Bedingungen
22 | der GNU General Public License, wie von der Free Software Foundation,
23 | Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
24 | veröffentlichten Version, weiterverbreiten und/oder modifizieren.
25 |
26 | MKMTool wird in der Hoffnung, dass es nützlich sein wird, aber
27 | OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
28 | Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
29 | Siehe die GNU General Public License für weitere Details.
30 |
31 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
32 | Programm erhalten haben. Wenn nicht, siehe .
33 | */
34 | extensions: .xml .config .xsd
35 |
--------------------------------------------------------------------------------
/MKMTool/AccountInfo.cs:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of MKMTool
3 |
4 | MKMTool is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | MKMTool is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with MKMTool. If not, see .
16 |
17 | Diese Datei ist Teil von MKMTool.
18 |
19 | MKMTool ist Freie Software: Sie können es unter den Bedingungen
20 | der GNU General Public License, wie von der Free Software Foundation,
21 | Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
22 | veröffentlichten Version, weiterverbreiten und/oder modifizieren.
23 |
24 | MKMTool wird in der Hoffnung, dass es nützlich sein wird, aber
25 | OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
26 | Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
27 | Siehe die GNU General Public License für weitere Details.
28 |
29 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
30 | Programm erhalten haben. Wenn nicht, siehe .
31 | */
32 | using System.Windows.Forms;
33 | using System.Xml;
34 |
35 | namespace MKMTool
36 | {
37 | public partial class AccountInfo : Form
38 | {
39 | public AccountInfo()
40 | {
41 | InitializeComponent();
42 | treeView1.Nodes.Clear();
43 | treeView1.Nodes.Add(new TreeNode("Account Details"));
44 | var tNode = treeView1.Nodes[0];
45 |
46 | try
47 | {
48 | var doc = MKMInteract.RequestHelper.GetAccount();
49 |
50 | addNode(doc["response"]["account"], tNode);
51 | }
52 | catch (System.Exception eError)
53 | {
54 | MKMHelpers.LogError("fetching account info", eError.Message, true);
55 | }
56 | //treeView1.ExpandAll();
57 | }
58 |
59 | // SRC:
60 | // https://support.microsoft.com/de-de/help/317597/how-to-populate-a-treeview-control-with-xml-data-in-visual-c-2005-or-in-visual-c-.net
61 | private void addNode(XmlNode inXmlNode, TreeNode inTreeNode)
62 | {
63 | XmlNode xNode;
64 | TreeNode tNode;
65 | XmlNodeList nodeList;
66 | int i;
67 |
68 | // Loop through the XML nodes until the leaf is reached.
69 | // Add the nodes to the TreeView during the looping process.
70 | if (inXmlNode.HasChildNodes)
71 | {
72 | nodeList = inXmlNode.ChildNodes;
73 | for (i = 0; i <= nodeList.Count - 1; i++)
74 | {
75 | xNode = inXmlNode.ChildNodes[i];
76 | inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
77 | tNode = inTreeNode.Nodes[i];
78 | addNode(xNode, tNode);
79 | }
80 | }
81 | else
82 | {
83 | // Here you need to pull the data from the XmlNode based on the
84 | // type of node, whether attribute values are required, and so forth.
85 | inTreeNode.Text = inXmlNode.OuterXml.Trim();
86 | }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/MKMTool/App.config:
--------------------------------------------------------------------------------
1 |
2 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 0
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/MKMTool/config_template.xml:
--------------------------------------------------------------------------------
1 |
2 |
33 |
34 |
35 |
36 | false
37 |
38 |
39 |
40 |
41 |
42 | Magic the Gathering;
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | ,
63 |
64 |
65 |
66 |
67 | 100
68 |
69 | 4
70 |
71 | ENTER_YOUR_APP_TOKEN_INSTEAD_OF_THIS_TEXT
72 | ENTER_YOUR_APP_SECRET_INSTEAD_OF_THIS_TEXT
73 | ENTER_YOUR_ACCESS_TOKEN_INSTEAD_OF_THIS_TEXT
74 | ENTER_YOUR_ACCESS_SECRET_INSTEAD_OF_THIS_TEXT
75 |
--------------------------------------------------------------------------------
/MKMTool/StockView.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace MKMTool
2 | {
3 | partial class StockView
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.stockGridView = new System.Windows.Forms.DataGridView();
32 | this.searchBox = new System.Windows.Forms.TextBox();
33 | this.label1 = new System.Windows.Forms.Label();
34 | this.buttonExport = new System.Windows.Forms.Button();
35 | ((System.ComponentModel.ISupportInitialize)(this.stockGridView)).BeginInit();
36 | this.SuspendLayout();
37 | //
38 | // stockGridView
39 | //
40 | this.stockGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
41 | | System.Windows.Forms.AnchorStyles.Left)
42 | | System.Windows.Forms.AnchorStyles.Right)));
43 | this.stockGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
44 | this.stockGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
45 | this.stockGridView.Location = new System.Drawing.Point(12, 41);
46 | this.stockGridView.Name = "stockGridView";
47 | this.stockGridView.Size = new System.Drawing.Size(966, 571);
48 | this.stockGridView.TabIndex = 0;
49 | //
50 | // searchBox
51 | //
52 | this.searchBox.Location = new System.Drawing.Point(59, 15);
53 | this.searchBox.Name = "searchBox";
54 | this.searchBox.Size = new System.Drawing.Size(628, 20);
55 | this.searchBox.TabIndex = 1;
56 | this.searchBox.TextChanged += new System.EventHandler(this.button1_Click);
57 | //
58 | // label1
59 | //
60 | this.label1.AutoSize = true;
61 | this.label1.Location = new System.Drawing.Point(12, 18);
62 | this.label1.Name = "label1";
63 | this.label1.Size = new System.Drawing.Size(41, 13);
64 | this.label1.TabIndex = 2;
65 | this.label1.Text = "Search";
66 | //
67 | // buttonExport
68 | //
69 | this.buttonExport.Enabled = false;
70 | this.buttonExport.Location = new System.Drawing.Point(858, 13);
71 | this.buttonExport.Name = "buttonExport";
72 | this.buttonExport.Size = new System.Drawing.Size(120, 23);
73 | this.buttonExport.TabIndex = 3;
74 | this.buttonExport.Text = "Export to CSV...";
75 | this.buttonExport.UseVisualStyleBackColor = true;
76 | this.buttonExport.Click += new System.EventHandler(this.buttonExport_Click);
77 | //
78 | // StockView
79 | //
80 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
81 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
82 | this.ClientSize = new System.Drawing.Size(990, 624);
83 | this.Controls.Add(this.buttonExport);
84 | this.Controls.Add(this.label1);
85 | this.Controls.Add(this.searchBox);
86 | this.Controls.Add(this.stockGridView);
87 | this.Name = "StockView";
88 | this.Text = "StockView";
89 | this.VisibleChanged += new System.EventHandler(this.stockView_VisibleChanged);
90 | ((System.ComponentModel.ISupportInitialize)(this.stockGridView)).EndInit();
91 | this.ResumeLayout(false);
92 | this.PerformLayout();
93 |
94 | }
95 |
96 | #endregion
97 |
98 | private System.Windows.Forms.DataGridView stockGridView;
99 | private System.Windows.Forms.TextBox searchBox;
100 | private System.Windows.Forms.Label label1;
101 | private System.Windows.Forms.Button buttonExport;
102 | }
103 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 | *.VC.VC.opendb
85 |
86 | # Visual Studio profiler
87 | *.psess
88 | *.vsp
89 | *.vspx
90 | *.sap
91 |
92 | # TFS 2012 Local Workspace
93 | $tf/
94 |
95 | # Guidance Automation Toolkit
96 | *.gpState
97 |
98 | # ReSharper is a .NET coding add-in
99 | _ReSharper*/
100 | *.[Rr]e[Ss]harper
101 | *.DotSettings.user
102 |
103 | # JustCode is a .NET coding add-in
104 | .JustCode
105 |
106 | # TeamCity is a build add-in
107 | _TeamCity*
108 |
109 | # DotCover is a Code Coverage Tool
110 | *.dotCover
111 |
112 | # NCrunch
113 | _NCrunch_*
114 | .*crunch*.local.xml
115 | nCrunchTemp_*
116 |
117 | # MightyMoose
118 | *.mm.*
119 | AutoTest.Net/
120 |
121 | # Web workbench (sass)
122 | .sass-cache/
123 |
124 | # Installshield output folder
125 | [Ee]xpress/
126 |
127 | # DocProject is a documentation generator add-in
128 | DocProject/buildhelp/
129 | DocProject/Help/*.HxT
130 | DocProject/Help/*.HxC
131 | DocProject/Help/*.hhc
132 | DocProject/Help/*.hhk
133 | DocProject/Help/*.hhp
134 | DocProject/Help/Html2
135 | DocProject/Help/html
136 |
137 | # Click-Once directory
138 | publish/
139 |
140 | # Publish Web Output
141 | *.[Pp]ublish.xml
142 | *.azurePubxml
143 | # TODO: Comment the next line if you want to checkin your web deploy settings
144 | # but database connection strings (with potential passwords) will be unencrypted
145 | *.pubxml
146 | *.publishproj
147 |
148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
149 | # checkin your Azure Web App publish settings, but sensitive information contained
150 | # in these scripts will be unencrypted
151 | PublishScripts/
152 |
153 | # NuGet Packages
154 | *.nupkg
155 | # The packages folder can be ignored because of Package Restore
156 | **/packages/*
157 | # except build/, which is used as an MSBuild target.
158 | !**/packages/build/
159 | # Uncomment if necessary however generally it will be regenerated when needed
160 | #!**/packages/repositories.config
161 | # NuGet v3's project.json files produces more ignoreable files
162 | *.nuget.props
163 | *.nuget.targets
164 |
165 | # Microsoft Azure Build Output
166 | csx/
167 | *.build.csdef
168 |
169 | # Microsoft Azure Emulator
170 | ecf/
171 | rcf/
172 |
173 | # Windows Store app package directories and files
174 | AppPackages/
175 | BundleArtifacts/
176 | Package.StoreAssociation.xml
177 | _pkginfo.txt
178 |
179 | # Visual Studio cache files
180 | # files ending in .cache can be ignored
181 | *.[Cc]ache
182 | # but keep track of directories ending in .cache
183 | !*.[Cc]ache/
184 |
185 | # Others
186 | ClientBin/
187 | ~$*
188 | *~
189 | *.dbmdl
190 | *.dbproj.schemaview
191 | *.pfx
192 | *.publishsettings
193 | node_modules/
194 | orleans.codegen.cs
195 |
196 | # Since there are multiple workflows, uncomment next line to ignore bower_components
197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
198 | #bower_components/
199 |
200 | # RIA/Silverlight projects
201 | Generated_Code/
202 |
203 | # Backup & report files from converting an old project file
204 | # to a newer Visual Studio version. Backup files are not needed,
205 | # because we have git ;-)
206 | _UpgradeReport_Files/
207 | Backup*/
208 | UpgradeLog*.XML
209 | UpgradeLog*.htm
210 |
211 | # SQL Server files
212 | *.mdf
213 | *.ldf
214 |
215 | # Business Intelligence projects
216 | *.rdl.data
217 | *.bim.layout
218 | *.bim_*.settings
219 |
220 | # Microsoft Fakes
221 | FakesAssemblies/
222 |
223 | # GhostDoc plugin setting file
224 | *.GhostDoc.xml
225 |
226 | # Node.js Tools for Visual Studio
227 | .ntvs_analysis.dat
228 |
229 | # Visual Studio 6 build log
230 | *.plg
231 |
232 | # Visual Studio 6 workspace options file
233 | *.opt
234 |
235 | # Visual Studio LightSwitch build output
236 | **/*.HTMLClient/GeneratedArtifacts
237 | **/*.DesktopClient/GeneratedArtifacts
238 | **/*.DesktopClient/ModelManifest.xml
239 | **/*.Server/GeneratedArtifacts
240 | **/*.Server/ModelManifest.xml
241 | _Pvt_Extensions
242 |
243 | # Paket dependency manager
244 | .paket/paket.exe
245 | paket-files/
246 |
247 | # FAKE - F# Make
248 | .fake/
249 |
250 | # JetBrains Rider
251 | .idea/
252 | *.sln.iml
253 | /MKMTool/config.xml
254 |
--------------------------------------------------------------------------------
/MKMTool/MKMPriceAsFormula.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.Collections.Generic;
3 | using System.Data;
4 |
5 | namespace MKMTool
6 | {
7 | // Defines price as a formula (string) made of any number of operands and operations.
8 | // Supported operands are: numbers (double), price guides (codes according to MKMHelpers.PriceGuides)
9 | // Supported operations are: * for multiplication, + for addition and - for subtraction.
10 | // Any white spaces are stripped from the formula before processing.
11 | // Operations are evaluated in the order they are written, not based on classic operator precedence.
12 | public class MKMPriceAsFormula
13 | {
14 | /// Sets this from string.
15 | /// The formula as string.
16 | /// True if parsing finished successfully, false if some of the operands were neither numbers nor price guides.
17 | public bool Parse(string formula)
18 | {
19 | string formulaOrig = formula;
20 | formula = formula.Trim();
21 | var separators = new char[] { '*', '-', '+' };
22 | // parse the first operand, there must be at least one and the formula cannot start with an operand
23 | string operand = formula.Split(separators, 2)[0];
24 | if (!parseAndAddOperand(operand.Trim()))
25 | {
26 | MKMHelpers.LogError("parsing price formula", "failed to parse operand " + operand + " in formula " + formulaOrig
27 | + ", it cannot be used.", true);
28 | return false;
29 | }
30 | formula = formula.Substring(operand.Length);
31 | while (formula.Length > 0)
32 | {
33 | char oper = formula[0]; // the next symbol is surely the operand
34 | switch (oper)
35 | {
36 | case '*':
37 | operators.Add(mult);
38 | break;
39 | case '-':
40 | operators.Add(subtract);
41 | break;
42 | case '+':
43 | operators.Add(adding);
44 | break;
45 | }
46 | formula = formula.Substring(1);
47 | // there must be another operand after operator, otherwise it is an error
48 | operand = formula.Split(separators, 2)[0];
49 | if (!parseAndAddOperand(operand.Trim()))
50 | {
51 | MKMHelpers.LogError("parsing price formula", "failed to parse operand " + operand + " in formula " + formulaOrig
52 | + ", it cannot be used.", false);
53 | return false;
54 | }
55 | formula = formula.Substring(operand.Length);
56 | formula.Trim();
57 | }
58 | return true;
59 | }
60 |
61 | /// Uses the provided price guides to compute the price according to the formula.
62 | /// Row from the priceGuides table containing guides for the card for which to evaluate this formula.
63 | /// If this formula UsesPriceGuides, must be set to contain all the columns, otherwise exception is thrown.
64 | /// Our current sale price of the card (can be used as a guide).
65 | /// The final price this formula evaluates to. NaN if the necessary guides are not found.
66 | public double Evaluate(DataRow priceGuides, double currentPriceSingle)
67 | {
68 | double term;
69 | foreach (var guideTerm in guidesToResolve)
70 | {
71 | if (guideTerm.Value == "CURRENT")
72 | term = currentPriceSingle;
73 | else
74 | term = MKMHelpers.ConvertDoubleAnySep(priceGuides[guideTerm.Value].ToString());
75 | if (double.IsNaN(term))
76 | return term;
77 | operands[guideTerm.Key] = term;
78 | }
79 | double val = operands[0];
80 | for (int i = 0; i < operators.Count; i++)
81 | {
82 | val = operators[i](val, operands[i + 1]);
83 | }
84 | return val;
85 | }
86 |
87 | /// Determines if this formula uses price guides.
88 | /// True if at least one operand is a price guide, otherwise false.
89 | public bool UsesPriceGuides()
90 | {
91 | return guidesToResolve.Count > 0;
92 | }
93 |
94 | /// Converts the operand to number or price guide and stores it
95 | /// Trimmed string representation of the operand.
96 | /// False if the parsing failed.
97 | private bool parseAndAddOperand(string operand)
98 | {
99 | double number = MKMHelpers.ConvertDoubleAnySep(operand);
100 | if (double.IsNaN(number))
101 | {
102 | foreach (var guide in MKMHelpers.PriceGuides)
103 | {
104 | if (guide.Value.Code == operand)
105 | {
106 | guidesToResolve.Add(new KeyValuePair(operands.Count, operand));
107 | operands.Add(-9999);
108 | return true;
109 | }
110 | }
111 | }
112 | else
113 | {
114 | operands.Add(number);
115 | return true;
116 | }
117 | return false;
118 | }
119 |
120 | private delegate double formulaOperation(double lhs, double rhs);
121 |
122 | private double adding(double lhs, double rhs) { return lhs + rhs; }
123 | private double subtract(double lhs, double rhs) { return lhs - rhs; }
124 | private double mult(double lhs, double rhs) { return lhs * rhs; }
125 |
126 | // the indices of operands in the formula that are guide codes and need to be resolved
127 | private readonly List> guidesToResolve = new List>();
128 | private readonly List operands = new List();
129 | private readonly List operators = new List();
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/MKMTool/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/MKMTool/StockView.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/MKMTool/AccountInfo.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/MKMTool/PopupListbox.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/MKMTool/WantlistEditorView.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/MKMTool/checkDisplayPrices.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/MKMTool/PriceExternalList.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/MKMTool/CheckWantsView.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | 17, 17
125 |
126 |
--------------------------------------------------------------------------------
/MKMTool/PopupListbox.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace MKMTool
2 | {
3 | partial class PopupListbox
4 | {
5 | /// Required designer variable.
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | /// Clean up any resources being used.
9 | /// true if managed resources should be disposed; otherwise, false.
10 | protected override void Dispose(bool disposing)
11 | {
12 | if (disposing && (components != null))
13 | {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | /// Required method for Designer support - do not modify
22 | /// the contents of this method with the code editor.
23 | private void InitializeComponent()
24 | {
25 | this.listBoxContent = new System.Windows.Forms.ListBox();
26 | this.buttonConfirm = new System.Windows.Forms.Button();
27 | this.panelForLabel = new System.Windows.Forms.Panel();
28 | this.labelTitle = new System.Windows.Forms.Label();
29 | this.panelForHint = new System.Windows.Forms.Panel();
30 | this.labelHint = new System.Windows.Forms.Label();
31 | this.panelForLabel.SuspendLayout();
32 | this.panelForHint.SuspendLayout();
33 | this.SuspendLayout();
34 | //
35 | // listBoxContent
36 | //
37 | this.listBoxContent.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
38 | | System.Windows.Forms.AnchorStyles.Left)
39 | | System.Windows.Forms.AnchorStyles.Right)));
40 | this.listBoxContent.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
41 | this.listBoxContent.FormattingEnabled = true;
42 | this.listBoxContent.ItemHeight = 18;
43 | this.listBoxContent.Location = new System.Drawing.Point(12, 38);
44 | this.listBoxContent.Name = "listBoxContent";
45 | this.listBoxContent.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
46 | this.listBoxContent.Size = new System.Drawing.Size(258, 652);
47 | this.listBoxContent.TabIndex = 0;
48 | this.listBoxContent.SelectedValueChanged += new System.EventHandler(this.listBoxContent_SelectedValueChanged);
49 | //
50 | // buttonConfirm
51 | //
52 | this.buttonConfirm.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
53 | | System.Windows.Forms.AnchorStyles.Right)));
54 | this.buttonConfirm.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
55 | this.buttonConfirm.Location = new System.Drawing.Point(12, 726);
56 | this.buttonConfirm.Name = "buttonConfirm";
57 | this.buttonConfirm.Size = new System.Drawing.Size(258, 34);
58 | this.buttonConfirm.TabIndex = 2;
59 | this.buttonConfirm.Text = "OK";
60 | this.buttonConfirm.UseVisualStyleBackColor = true;
61 | this.buttonConfirm.Click += new System.EventHandler(this.buttonConfirm_Click);
62 | //
63 | // panelForLabel
64 | //
65 | this.panelForLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
66 | | System.Windows.Forms.AnchorStyles.Right)));
67 | this.panelForLabel.Controls.Add(this.labelTitle);
68 | this.panelForLabel.Location = new System.Drawing.Point(12, 0);
69 | this.panelForLabel.Name = "panelForLabel";
70 | this.panelForLabel.Size = new System.Drawing.Size(258, 33);
71 | this.panelForLabel.TabIndex = 3;
72 | //
73 | // labelTitle
74 | //
75 | this.labelTitle.Dock = System.Windows.Forms.DockStyle.Fill;
76 | this.labelTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
77 | this.labelTitle.Location = new System.Drawing.Point(0, 0);
78 | this.labelTitle.Name = "labelTitle";
79 | this.labelTitle.Size = new System.Drawing.Size(258, 33);
80 | this.labelTitle.TabIndex = 1;
81 | this.labelTitle.Text = "List title";
82 | this.labelTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
83 | //
84 | // panelForHint
85 | //
86 | this.panelForHint.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
87 | | System.Windows.Forms.AnchorStyles.Right)));
88 | this.panelForHint.Controls.Add(this.labelHint);
89 | this.panelForHint.Location = new System.Drawing.Point(12, 713);
90 | this.panelForHint.Name = "panelForHint";
91 | this.panelForHint.Size = new System.Drawing.Size(257, 10);
92 | this.panelForHint.TabIndex = 4;
93 | //
94 | // labelHint
95 | //
96 | this.labelHint.Dock = System.Windows.Forms.DockStyle.Fill;
97 | this.labelHint.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
98 | this.labelHint.Location = new System.Drawing.Point(0, 0);
99 | this.labelHint.Name = "labelHint";
100 | this.labelHint.Size = new System.Drawing.Size(257, 10);
101 | this.labelHint.TabIndex = 0;
102 | this.labelHint.Text = "Hold CTRL to select multiple";
103 | this.labelHint.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
104 | //
105 | // PopupListbox
106 | //
107 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
108 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
109 | this.ClientSize = new System.Drawing.Size(282, 761);
110 | this.Controls.Add(this.panelForHint);
111 | this.Controls.Add(this.buttonConfirm);
112 | this.Controls.Add(this.listBoxContent);
113 | this.Controls.Add(this.panelForLabel);
114 | this.Name = "PopupListbox";
115 | this.Text = "PopupListbox";
116 | this.panelForLabel.ResumeLayout(false);
117 | this.panelForHint.ResumeLayout(false);
118 | this.ResumeLayout(false);
119 |
120 | }
121 |
122 | #endregion
123 |
124 | private System.Windows.Forms.ListBox listBoxContent;
125 | private System.Windows.Forms.Button buttonConfirm;
126 | private System.Windows.Forms.Panel panelForLabel;
127 | private System.Windows.Forms.Label labelTitle;
128 | private System.Windows.Forms.Panel panelForHint;
129 | private System.Windows.Forms.Label labelHint;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # To learn more about .editorconfig see https://aka.ms/editorconfigdocs
2 | ###############################
3 | # Core EditorConfig Options #
4 | ###############################
5 | # All files
6 | [*]
7 | indent_style = space
8 | # Code files
9 | [*.{cs,csx,vb,vbx}]
10 | indent_size = 2
11 | insert_final_newline = true
12 | charset = utf-8-bom
13 | ###############################
14 | # .NET Coding Conventions #
15 | ###############################
16 | [*.{cs,vb}]
17 | # Organize usings
18 | dotnet_sort_system_directives_first = true
19 | # this. preferences
20 | dotnet_style_qualification_for_field = false:silent
21 | dotnet_style_qualification_for_property = false:silent
22 | dotnet_style_qualification_for_method = false:silent
23 | dotnet_style_qualification_for_event = false:silent
24 | # Language keywords vs BCL types preferences
25 | dotnet_style_predefined_type_for_locals_parameters_members = true:silent
26 | dotnet_style_predefined_type_for_member_access = true:silent
27 | # Parentheses preferences
28 | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
29 | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
30 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
31 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
32 | # Modifier preferences
33 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
34 | dotnet_style_readonly_field = true:suggestion
35 | # Expression-level preferences
36 | dotnet_style_object_initializer = true:suggestion
37 | dotnet_style_collection_initializer = true:suggestion
38 | dotnet_style_explicit_tuple_names = true:suggestion
39 | dotnet_style_null_propagation = true:suggestion
40 | dotnet_style_coalesce_expression = true:suggestion
41 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
42 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
43 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
44 | dotnet_style_prefer_auto_properties = true:silent
45 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent
46 | dotnet_style_prefer_conditional_expression_over_return = true:silent
47 | ###############################
48 | # Naming Conventions #
49 | ###############################
50 | # Style Definitions
51 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case
52 | dotnet_naming_style.camel_case_style.capitalization = camel_case
53 | # Use PascalCase for constant fields
54 | dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
55 | dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
56 | dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
57 | dotnet_naming_symbols.constant_fields.applicable_kinds = field
58 | dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
59 | dotnet_naming_symbols.constant_fields.required_modifiers = const
60 | # use camelCase for non-public fields
61 | dotnet_naming_symbols.private_symbols.applicable_kinds = property,method,field,event,delegate
62 | dotnet_naming_symbols.private_symbols.applicable_accessibilities = private, protected
63 | dotnet_naming_rule.private_symbols_camelcase.symbols = private_symbols
64 | dotnet_naming_rule.private_symbols_camelcase.style = camel_case_style
65 | dotnet_naming_rule.private_symbols_camelcase.severity = warning
66 | # use PascalCase for public fields
67 | dotnet_naming_symbols.public_symbols.applicable_kinds = property,method,field,event,delegate
68 | dotnet_naming_symbols.public_symbols.applicable_accessibilities = public
69 | dotnet_naming_rule.public_symbols_pascalcase.symbols = public_symbols
70 | dotnet_naming_rule.public_symbols_pascalcase.style = pascal_case_style
71 | dotnet_naming_rule.public_symbols_pascalcase.severity = warning
72 | ###############################
73 | # C# Coding Conventions #
74 | ###############################
75 | [*.cs]
76 | # var preferences
77 | csharp_style_var_for_built_in_types = true:silent
78 | csharp_style_var_when_type_is_apparent = true:silent
79 | csharp_style_var_elsewhere = true:silent
80 | # Expression-bodied members
81 | csharp_style_expression_bodied_methods = false:silent
82 | csharp_style_expression_bodied_constructors = false:silent
83 | csharp_style_expression_bodied_operators = false:silent
84 | csharp_style_expression_bodied_properties = true:silent
85 | csharp_style_expression_bodied_indexers = true:silent
86 | csharp_style_expression_bodied_accessors = true:silent
87 | # Pattern matching preferences
88 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
89 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
90 | # Null-checking preferences
91 | csharp_style_throw_expression = true:suggestion
92 | csharp_style_conditional_delegate_call = true:suggestion
93 | # Modifier preferences
94 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
95 | # Expression-level preferences
96 | csharp_prefer_braces = true:silent
97 | csharp_style_deconstructed_variable_declaration = true:suggestion
98 | csharp_prefer_simple_default_expression = true:suggestion
99 | csharp_style_pattern_local_over_anonymous_function = true:suggestion
100 | csharp_style_inlined_variable_declaration = true:suggestion
101 | ###############################
102 | # C# Formatting Rules #
103 | ###############################
104 | # New line preferences
105 | csharp_new_line_before_open_brace = all
106 | csharp_new_line_before_else = true
107 | csharp_new_line_before_catch = true
108 | csharp_new_line_before_finally = true
109 | csharp_new_line_before_members_in_object_initializers = true
110 | csharp_new_line_before_members_in_anonymous_types = true
111 | csharp_new_line_between_query_expression_clauses = true
112 | # Indentation preferences
113 | csharp_indent_case_contents = true
114 | csharp_indent_switch_labels = true
115 | csharp_indent_labels = flush_left
116 | # Space preferences
117 | csharp_space_after_cast = false
118 | csharp_space_after_keywords_in_control_flow_statements = true
119 | csharp_space_between_method_call_parameter_list_parentheses = false
120 | csharp_space_between_method_declaration_parameter_list_parentheses = false
121 | csharp_space_between_parentheses = false
122 | csharp_space_before_colon_in_inheritance_clause = true
123 | csharp_space_after_colon_in_inheritance_clause = true
124 | csharp_space_around_binary_operators = before_and_after
125 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
126 | csharp_space_between_method_call_name_and_opening_parenthesis = false
127 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
128 | # Wrapping preferences
129 | csharp_preserve_single_line_statements = true
130 | csharp_preserve_single_line_blocks = true
131 | ###############################
132 | # VB Coding Conventions #
133 | ###############################
134 | [*.vb]
135 | # Modifier preferences
136 | visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
137 |
--------------------------------------------------------------------------------
/MKMTool/MKMAuth.cs:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of MKMTool
3 |
4 | MKMTool is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | MKMTool is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with MKMTool. If not, see .
16 |
17 | Diese Datei ist Teil von MKMTool.
18 |
19 | MKMTool ist Freie Software: Sie können es unter den Bedingungen
20 | der GNU General Public License, wie von der Free Software Foundation,
21 | Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
22 | veröffentlichten Version, weiterverbreiten und/oder modifizieren.
23 |
24 | MKMTool wird in der Hoffnung, dass es nützlich sein wird, aber
25 | OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
26 | Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
27 | Siehe die GNU General Public License für weitere Details.
28 |
29 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
30 | Programm erhalten haben. Wenn nicht, siehe .
31 | */
32 | using System;
33 | using System.Collections.Generic;
34 | using System.Security.Cryptography;
35 | using System.Text;
36 | using System.Xml;
37 |
38 | public class MKMAuth
39 | {
40 | /// Class encapsulates tokens and secret to create OAuth signatures and return Authorization headers for web requests.
41 | public class OAuthHeader
42 | {
43 | /// Access Token Secret (Class should also implement an AccessToken property to set the value)
44 | protected string accessSecret = "";
45 |
46 | /// Access Token (Class should also implement an AccessToken property to set the value)
47 | protected string accessToken = "";
48 |
49 | /// App Secret
50 | protected string appSecret = "";
51 |
52 |
53 | /// App Token
54 | protected string appToken = "";
55 |
56 | /// Header params deduced from config
57 | protected Dictionary configHeaderParams;
58 |
59 | /// OAuth Signature Method
60 | protected string signatureMethod = "HMAC-SHA1";
61 |
62 | /// OAuth Version
63 | protected string version = "1.0";
64 |
65 | /// Constructor
66 | public OAuthHeader()
67 | {
68 | var xConfigFile = new XmlDocument();
69 |
70 | xConfigFile.Load(@".//config.xml");
71 |
72 | appToken = xConfigFile["config"]["appToken"].InnerText;
73 | appSecret = xConfigFile["config"]["appSecret"].InnerText;
74 | accessToken = xConfigFile["config"]["accessToken"].InnerText;
75 | accessSecret = xConfigFile["config"]["accessSecret"].InnerText;
76 |
77 | // String nonce = Guid.NewGuid().ToString("n");
78 | var nonce = "53eb1f44909d6";
79 | // String timestamp = (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString();
80 | var timestamp = "1407917892";
81 | /// Initialize all class members
82 | configHeaderParams = new Dictionary();
83 | configHeaderParams.Add("oauth_consumer_key", appToken);
84 | configHeaderParams.Add("oauth_token", accessToken);
85 | configHeaderParams.Add("oauth_nonce", nonce);
86 | configHeaderParams.Add("oauth_timestamp", timestamp);
87 | configHeaderParams.Add("oauth_signature_method", signatureMethod);
88 | configHeaderParams.Add("oauth_version", version);
89 | }
90 |
91 | public static SortedDictionary ParseQueryString(string query)
92 | {
93 | var queryParameters = new SortedDictionary();
94 | var querySegments = query.Split('&');
95 | foreach (var segment in querySegments)
96 | {
97 | var parts = segment.Split('=');
98 | if (parts.Length > 0)
99 | {
100 | var key = parts[0].Trim('?', ' ');
101 | var val = parts[1].Trim();
102 |
103 | queryParameters.Add(key, val);
104 | }
105 | }
106 |
107 | return queryParameters;
108 | }
109 |
110 | /// Pass request method and URI parameters to get the Authorization header value
111 | /// Request Method
112 | /// Request URI
113 | /// Authorization header value
114 | public string GetAuthorizationHeader(string method, string url)
115 | {
116 | var uri = new Uri(url);
117 | var baseUri = uri.GetLeftPart(UriPartial.Path);
118 |
119 | //MessageBox.Show(baseUri);
120 | Dictionary headerParams = new Dictionary(configHeaderParams)
121 | {
122 | { "realm", baseUri }
123 | };
124 |
125 | /// Start composing the base string from the method and request URI
126 | var baseString = method.ToUpper()
127 | + "&"
128 | + Uri.EscapeDataString(baseUri)
129 | + "&";
130 |
131 | var index = url.IndexOf("?");
132 |
133 | if (index > 0)
134 | {
135 | var urlParams = url.Substring(index).Remove(0, 1);
136 |
137 | var args = ParseQueryString(urlParams);
138 |
139 | foreach (var k in args)
140 | {
141 | headerParams.Add(k.Key, k.Value);
142 | }
143 | }
144 |
145 | /// Gather, encode, and sort the base string parameters
146 | var encodedParams = new SortedDictionary();
147 | foreach (var parameter in headerParams)
148 | {
149 | if (false == parameter.Key.Equals("realm"))
150 | {
151 | encodedParams.Add(Uri.EscapeDataString(parameter.Key), Uri.EscapeDataString(parameter.Value));
152 | }
153 | }
154 |
155 | /// Expand the base string by the encoded parameter=value pairs
156 | var paramStrings = new List();
157 | foreach (var parameter in encodedParams)
158 | {
159 | paramStrings.Add(parameter.Key + "=" + parameter.Value);
160 | }
161 | var paramString = Uri.EscapeDataString(string.Join("&", paramStrings));
162 | baseString += paramString;
163 |
164 | /// Create the OAuth signature
165 | var signatureKey = Uri.EscapeDataString(appSecret) + "&" + Uri.EscapeDataString(accessSecret);
166 | var hasher = HMAC.Create();
167 | hasher.Key = Encoding.UTF8.GetBytes(signatureKey);
168 | var rawSignature = hasher.ComputeHash(Encoding.UTF8.GetBytes(baseString));
169 | var oAuthSignature = Convert.ToBase64String(rawSignature);
170 |
171 | /// Include the OAuth signature parameter in the header parameters array
172 | headerParams.Add("oauth_signature", oAuthSignature);
173 |
174 | /// Construct the header string
175 | var headerParamStrings = new List();
176 | foreach (var parameter in headerParams)
177 | {
178 | headerParamStrings.Add(parameter.Key + "=\"" + parameter.Value + "\"");
179 | }
180 | var authHeader = "OAuth " + string.Join(", ", headerParamStrings);
181 |
182 | return authHeader;
183 | }
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/MKMTool/SettingPresetStore.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace MKMTool
2 | {
3 | partial class SettingPresetStore
4 | {
5 | /// Required designer variable.
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | /// Clean up any resources being used.
9 | /// true if managed resources should be disposed; otherwise, false.
10 | protected override void Dispose(bool disposing)
11 | {
12 | if (disposing && (components != null))
13 | {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | /// Required method for Designer support - do not modify
22 | /// the contents of this method with the code editor.
23 | private void InitializeComponent()
24 | {
25 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingPresetStore));
26 | this.buttonStore = new System.Windows.Forms.Button();
27 | this.textBoxFileName = new System.Windows.Forms.TextBox();
28 | this.panel1 = new System.Windows.Forms.Panel();
29 | this.labelChooseName = new System.Windows.Forms.Label();
30 | this.buttonCancel = new System.Windows.Forms.Button();
31 | this.panelDescription = new System.Windows.Forms.Panel();
32 | this.labelDescription = new System.Windows.Forms.Label();
33 | this.textBoxDescription = new System.Windows.Forms.TextBox();
34 | this.panel1.SuspendLayout();
35 | this.panelDescription.SuspendLayout();
36 | this.SuspendLayout();
37 | //
38 | // buttonStore
39 | //
40 | this.buttonStore.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
41 | this.buttonStore.Location = new System.Drawing.Point(153, 169);
42 | this.buttonStore.Name = "buttonStore";
43 | this.buttonStore.Size = new System.Drawing.Size(79, 34);
44 | this.buttonStore.TabIndex = 0;
45 | this.buttonStore.Text = "Store";
46 | this.buttonStore.UseVisualStyleBackColor = true;
47 | this.buttonStore.Click += new System.EventHandler(this.buttonStore_Click);
48 | //
49 | // textBoxFileName
50 | //
51 | this.textBoxFileName.CharacterCasing = System.Windows.Forms.CharacterCasing.Lower;
52 | this.textBoxFileName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
53 | this.textBoxFileName.Location = new System.Drawing.Point(12, 46);
54 | this.textBoxFileName.Multiline = true;
55 | this.textBoxFileName.Name = "textBoxFileName";
56 | this.textBoxFileName.Size = new System.Drawing.Size(260, 29);
57 | this.textBoxFileName.TabIndex = 2;
58 | //
59 | // panel1
60 | //
61 | this.panel1.Controls.Add(this.labelChooseName);
62 | this.panel1.Location = new System.Drawing.Point(12, 6);
63 | this.panel1.Name = "panel1";
64 | this.panel1.Size = new System.Drawing.Size(260, 34);
65 | this.panel1.TabIndex = 3;
66 | //
67 | // labelChooseName
68 | //
69 | this.labelChooseName.Dock = System.Windows.Forms.DockStyle.Fill;
70 | this.labelChooseName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
71 | this.labelChooseName.Location = new System.Drawing.Point(0, 0);
72 | this.labelChooseName.Name = "labelChooseName";
73 | this.labelChooseName.Size = new System.Drawing.Size(260, 34);
74 | this.labelChooseName.TabIndex = 3;
75 | this.labelChooseName.Text = "Preset Name";
76 | this.labelChooseName.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
77 | //
78 | // buttonCancel
79 | //
80 | this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
81 | this.buttonCancel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
82 | this.buttonCancel.Location = new System.Drawing.Point(56, 169);
83 | this.buttonCancel.Name = "buttonCancel";
84 | this.buttonCancel.Size = new System.Drawing.Size(79, 34);
85 | this.buttonCancel.TabIndex = 4;
86 | this.buttonCancel.Text = "Cancel";
87 | this.buttonCancel.UseVisualStyleBackColor = true;
88 | this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
89 | //
90 | // panelDescription
91 | //
92 | this.panelDescription.Controls.Add(this.labelDescription);
93 | this.panelDescription.Location = new System.Drawing.Point(12, 78);
94 | this.panelDescription.Name = "panelDescription";
95 | this.panelDescription.Size = new System.Drawing.Size(260, 34);
96 | this.panelDescription.TabIndex = 5;
97 | //
98 | // labelDescription
99 | //
100 | this.labelDescription.Dock = System.Windows.Forms.DockStyle.Fill;
101 | this.labelDescription.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
102 | this.labelDescription.Location = new System.Drawing.Point(0, 0);
103 | this.labelDescription.Name = "labelDescription";
104 | this.labelDescription.Size = new System.Drawing.Size(260, 34);
105 | this.labelDescription.TabIndex = 4;
106 | this.labelDescription.Text = "Preset Description";
107 | this.labelDescription.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
108 | //
109 | // textBoxDescription
110 | //
111 | this.textBoxDescription.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
112 | this.textBoxDescription.Location = new System.Drawing.Point(9, 115);
113 | this.textBoxDescription.Multiline = true;
114 | this.textBoxDescription.Name = "textBoxDescription";
115 | this.textBoxDescription.Size = new System.Drawing.Size(260, 48);
116 | this.textBoxDescription.TabIndex = 4;
117 | //
118 | // SettingPresetStore
119 | //
120 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
121 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
122 | this.CancelButton = this.buttonCancel;
123 | this.ClientSize = new System.Drawing.Size(284, 210);
124 | this.Controls.Add(this.panelDescription);
125 | this.Controls.Add(this.textBoxDescription);
126 | this.Controls.Add(this.buttonCancel);
127 | this.Controls.Add(this.panel1);
128 | this.Controls.Add(this.textBoxFileName);
129 | this.Controls.Add(this.buttonStore);
130 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
131 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
132 | this.Name = "SettingPresetStore";
133 | this.Text = "Store Settings Preset";
134 | this.panel1.ResumeLayout(false);
135 | this.panelDescription.ResumeLayout(false);
136 | this.ResumeLayout(false);
137 | this.PerformLayout();
138 |
139 | }
140 |
141 | #endregion
142 |
143 | private System.Windows.Forms.Button buttonStore;
144 | private System.Windows.Forms.TextBox textBoxFileName;
145 | private System.Windows.Forms.Button buttonCancel;
146 | private System.Windows.Forms.Panel panel1;
147 | private System.Windows.Forms.Label labelChooseName;
148 | private System.Windows.Forms.Panel panelDescription;
149 | private System.Windows.Forms.Label labelDescription;
150 | private System.Windows.Forms.TextBox textBoxDescription;
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/MKMTool/StockView.cs:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of MKMTool
3 |
4 | MKMTool is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | MKMTool is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with MKMTool. If not, see .
16 |
17 | Diese Datei ist Teil von MKMTool.
18 |
19 | MKMTool ist Freie Software: Sie können es unter den Bedingungen
20 | der GNU General Public License, wie von der Free Software Foundation,
21 | Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
22 | veröffentlichten Version, weiterverbreiten und/oder modifizieren.
23 |
24 | MKMTool wird in der Hoffnung, dass es nützlich sein wird, aber
25 | OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
26 | Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
27 | Siehe die GNU General Public License für weitere Details.
28 |
29 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
30 | Programm erhalten haben. Wenn nicht, siehe .
31 | */
32 | using System;
33 | using System.Data;
34 | using System.Windows.Forms;
35 |
36 | namespace MKMTool
37 | {
38 | public partial class StockView : Form
39 | {
40 | public StockView()
41 | {
42 | InitializeComponent();
43 |
44 | stockGridView.ReadOnly = true;
45 | }
46 |
47 | // reload data each time the form is made visible in case the user's stock has changed so they can reload the stockview this way
48 | private void stockView_VisibleChanged(object sender, EventArgs e)
49 | {
50 | if (Visible)
51 | {
52 | var articles = new DataTable();
53 | try
54 | {
55 | // getAllStockSingles creates a DataTable and converts it to list of cards, so theoretically we are wasting some work
56 | // but it also filters out non-singles and converting to MKMcard will make sure we use the primary column names rather than synonyms
57 | var cards = MKMInteract.RequestHelper.GetAllStockSingles(MainView.Instance.Config.UseStockGetFile);
58 | if (cards.Count == 0)
59 | {
60 | MainView.Instance.LogMainWindow("Stock is empty. Did you select correct idGame in config.xml?");
61 | return;
62 | }
63 | foreach (var card in cards)
64 | {
65 | card.WriteItselfIntoTable(articles, true, MCFormat.MKM, true);
66 | }
67 | // Remove columns we don't want showing
68 | // TODO - what is and isn't shown should probably be customizable and left to the user to choose in some way
69 | if (articles.Columns.Contains(MCAttribute.ArticleID))
70 | articles.Columns.Remove(MCAttribute.ArticleID);
71 | if (articles.Columns.Contains(MCAttribute.LanguageID))
72 | articles.Columns.Remove(MCAttribute.LanguageID);
73 | if (articles.Columns.Contains(MCAttribute.MetaproductID))
74 | articles.Columns.Remove(MCAttribute.MetaproductID);
75 | if (articles.Columns.Contains("onSale"))
76 | articles.Columns.Remove("onSale"); // don't even know what this one is supposed to be, it's not even in the API documentation
77 | if (articles.Columns.Contains(MCAttribute.MKMCurrencyCode))
78 | articles.Columns.Remove(MCAttribute.MKMCurrencyCode);
79 | if (articles.Columns.Contains(MCAttribute.MKMCurrencyId))
80 | articles.Columns.Remove(MCAttribute.MKMCurrencyId);
81 |
82 | var dj = MKMDbManager.JoinDataTables(articles, MKMDbManager.Instance.Expansions,
83 | (row1, row2) => row1.Field(MCAttribute.ExpansionID) == row2.Field(MKMDbManager.ExpansionsFields.ExpansionID));
84 |
85 | if (dj.Columns.Contains(MCAttribute.ExpansionID))
86 | dj.Columns.Remove(MCAttribute.ExpansionID); // duplicated
87 | if (dj.Columns.Contains(MKMDbManager.ExpansionsFields.ExpansionID))
88 | dj.Columns.Remove(MKMDbManager.ExpansionsFields.ExpansionID); // ...and we don't want it anyway
89 | if (dj.Columns.Contains(MKMDbManager.ExpansionsFields.Name))
90 | dj.Columns.Remove(MKMDbManager.ExpansionsFields.Name); // duplicated
91 |
92 | // use the same order with or without UseStockGetFile
93 | System.Collections.Generic.List attsOrdered = new System.Collections.Generic.List
94 | {
95 | MCAttribute.Name, MCAttribute.Expansion, MCAttribute.Language, MCAttribute.ProductID,
96 | MCAttribute.MKMPrice, MCAttribute.Condition, MCAttribute.Comments, MCAttribute.Foil,
97 | MCAttribute.Altered, MCAttribute.Signed, MCAttribute.Playset, MCAttribute.Count,
98 | MCAttribute.Rarity, MCAttribute.ExpansionAbb
99 | };
100 | int ordinal = 0;
101 | foreach (string att in attsOrdered)
102 | {
103 | if (dj.Columns.Contains(att))
104 | dj.Columns[dj.Columns.IndexOf(att)].SetOrdinal(ordinal++);
105 | }
106 |
107 | // convert columns with numerical data from string so that sorting works correctly
108 | if (dj.Columns.Contains(MCAttribute.ProductID))
109 | convertNumberColumn(dj, MCAttribute.ProductID, false);
110 | if (dj.Columns.Contains(MCAttribute.Count))
111 | convertNumberColumn(dj, MCAttribute.Count, false);
112 | if (dj.Columns.Contains(MCAttribute.MKMPrice))
113 | convertNumberColumn(dj, MCAttribute.MKMPrice, true);
114 |
115 | stockGridView.DataSource = dj;
116 |
117 | buttonExport.Enabled = true;
118 | }
119 | catch (Exception eError)
120 | {
121 | MKMHelpers.LogError("listing stock in Stock View", eError.Message, true);
122 | }
123 | }
124 | }
125 |
126 | private void convertNumberColumn(DataTable table, string columnName, bool isFloat)
127 | {
128 | string tempName = columnName + "convertNumberColumnTemp";
129 | DataColumn convertedCol = new DataColumn(tempName, isFloat ? typeof(float) : typeof(int))
130 | {
131 | DefaultValue = -9999 // this is default we use in price external list as well, so should be recognizable
132 | };
133 | table.Columns.Add(convertedCol);
134 | foreach (DataRow row in table.Rows)
135 | {
136 | if (isFloat)
137 | row[tempName] = Convert.ToSingle(row[columnName],
138 | System.Globalization.CultureInfo.InvariantCulture);
139 | else
140 | row[tempName] = Convert.ToInt32(row[columnName],
141 | System.Globalization.CultureInfo.InvariantCulture);
142 | }
143 | table.Columns.Remove(columnName);
144 | convertedCol.ColumnName = columnName;
145 | }
146 |
147 | ///
148 | /// Instead of closing the window when the user presses (X) or ALT+F4, just hide it.
149 | /// Basically the intended behaviour is for the window to act as kind of a singleton object within the scope of its owner.
150 | ///
151 | /// The instance containing the event data.
152 | protected override void OnFormClosing(FormClosingEventArgs e)
153 | {
154 | base.OnFormClosing(e);
155 | if (e.CloseReason == CloseReason.UserClosing)
156 | {
157 | e.Cancel = true;
158 | Hide();
159 | }
160 | }
161 |
162 | private void button1_Click(object sender, EventArgs e)
163 | {
164 | string searchString = searchBox.Text.Replace("'", "");
165 | try
166 | {
167 | (stockGridView.DataSource as DataTable).DefaultView.RowFilter =
168 | string.Format("Name LIKE '%{0}%'", searchString);
169 | }
170 | catch (Exception eError)
171 | {
172 | MKMHelpers.LogError("searching for " + searchString + " in Stock View", eError.Message, true);
173 | }
174 |
175 | }
176 |
177 | private void buttonExport_Click(object sender, EventArgs e)
178 | {
179 | SaveFileDialog sf = new SaveFileDialog
180 | {
181 | Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*"
182 | };
183 | if (sf.ShowDialog() == DialogResult.OK)
184 | {
185 | MainView.Instance.LogMainWindow("Exporting inventory...");
186 | MKMCsvUtils.WriteTableAsCSV(sf.FileName, (DataTable)stockGridView.DataSource);
187 | MainView.Instance.LogMainWindow("Inventory exported.");
188 | }
189 | }
190 | }
191 | }
--------------------------------------------------------------------------------
/MKMTool/MKMCsvUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data;
4 | using System.IO;
5 | using System.Linq;
6 | using static MKMTool.MKMHelpers;
7 |
8 | namespace MKMTool
9 | {
10 | /// Helper class for processing CSV files.
11 | class MKMCsvUtils
12 | {
13 |
14 | /// Parses a row in a CSV file.
15 | /// The row from a CSV file. Each value can be enclosed by double quotes (i.e. the character ")
16 | /// and if a double quote is part of the value, it is escaped by another double quote.
17 | /// If a field contains an even number of double quotes and nothing else, it will be considered as not enclosed, so a field that contains """""" will
18 | /// be parsed as """. The only exception is when there are exactly two double quotes, in that case it will be considered an enclosed empty string.
19 | /// This is done as in practice, excel and similar might enclose the empty fields and the user probably wants to keep them empty.
20 | /// The character used as separator between columns.
21 | /// A list of the individual parsed values in the order they appear on the row. All enclosing quotes are trimmed
22 | /// from the value and all escape characters are removed.
23 | private static List parseCSVRow(string rowToParse, char separator)
24 | {
25 | List ret = new List();
26 | string[] split = rowToParse.Split(separator);
27 |
28 | for (int i = 0; i < split.Length; i++)
29 | {
30 | string columnValue = split[i];
31 | // we need to account for entires that have commas in their own name (so the split will split them among multiple
32 | // columns, even though they should be in one) and also for entries that can contain quotes.
33 | // MKM escapes the double quotes by another double quote, so the ending double quote is really ending only if it is not preceded by
34 | // something else.
35 | // So far worst case scenario is a card from the Force of Will game called: "I", the pilot. This in the database looks like this:
36 | // "304732","""I"", the Pilot","1018","Force of Will Single","1775","229401","2017-10-04 17:48:59"
37 | // so it has a comma, double quote precedes it, so it looks like the entry should end there, but it does not, it is in the middle of the name.
38 | // in general, double quote is to be considered opening/ending only if there is an odd number of them, otherwise they are escaped
39 | bool quoteEnclosed = false;
40 | for (int j = 0; j < columnValue.Length; j++)
41 | {
42 | if (columnValue[j] == '"')
43 | quoteEnclosed = !quoteEnclosed;
44 | else break;
45 | }
46 | if (quoteEnclosed) // starts by a double quote -> can contain comma itself, merge until the last double quote is found
47 | {
48 | while (true)
49 | {
50 | quoteEnclosed = false;
51 | for (int j = columnValue.Length - 1; j >= 0; j--) // check if it ends with an odd number of double quotes
52 | {
53 | if (columnValue[j] == '"')
54 | quoteEnclosed = !quoteEnclosed;
55 | else break;
56 | }
57 | if (!quoteEnclosed) // the closing quote was not found yet
58 | columnValue += separator + split[++i]; // append the next column value
59 | else break;
60 | }
61 | }
62 | if (quoteEnclosed)
63 | columnValue = columnValue.Substring(1, columnValue.Length - 2);
64 | columnValue = columnValue.Replace("\"\"", "\""); // un-escape double quotes
65 | // let's handle one corner case: if somebody is exporting a list from excel and says "enclose each field in double quotes",
66 | // empty fields will have the value "". Since that is an even number of double quotes, our algorithm will evaluate it as
67 | // not being quoteEnclosed even though it actually is an enclosed empty string. After the above replacement, we will now
68 | // have a string that is a single double quote. If that is the case, replace it with actual empty string.
69 | // Note that this still does not handle all corner cases, in general, if there is an even number X of double quotes in the field and no other text,
70 | // it can either be X/2 not-enclosed double quotes, or (X-1)/2 enclosed double quotes, there is no way to tell since we are allowing
71 | // mixed format (i.e. enclosed and unenclosed in the same file). Hopefully this never has any practical impact.
72 | if (!quoteEnclosed && columnValue == "\"")
73 | columnValue = "";
74 | columnValue = columnValue.Trim();
75 | ret.Add(columnValue);
76 | }
77 | return ret;
78 | }
79 |
80 | /// Writes the table as CSV.
81 | /// Path to the file as which to write the table.
82 | /// The data table to write.
83 | public static void WriteTableAsCSV(string filePath, DataTable dt)
84 | {
85 | try
86 | {
87 | string separ = MainView.Instance.Config.CSVExportSeparator + "\"";
88 | using (StreamWriter exp = new StreamWriter(filePath))
89 | {
90 | // we know there will be at least one column, otherwise there would be no valid imported items and therefore no export enabled
91 | string row = "\"" + (dt.Columns[0].ColumnName).Replace("\"", "\"\"") + "\""; // don't forget to escape all " by doubling them
92 | for (int i = 1; i < dt.Columns.Count; i++)
93 | row += separ + (dt.Columns[i].ColumnName).Replace("\"", "\"\"") + "\"";
94 | exp.WriteLine(row);
95 | foreach (DataRow card in dt.Rows)
96 | {
97 | row = "\"" + card[0].ToString().Replace("\"", "\"\"") + "\"";
98 | for (int i = 1; i < dt.Columns.Count; i++)
99 | row += separ + card[i].ToString().Replace("\"", "\"\"") + "\"";
100 | exp.WriteLine(row);
101 | }
102 | exp.Flush();
103 | }
104 | }
105 | catch (Exception eError)
106 | {
107 | LogError("writing CSV file " + filePath, eError.Message, true);
108 | }
109 | }
110 |
111 | /// Converts the csv to DataTable.
112 | /// The string file path.
113 | /// Each row of the file as a row in the returned DataTable.
114 | public static DataTable ConvertCSVtoDataTable(string strFilePath)
115 | {
116 | using (var sr = new StreamReader(strFilePath))
117 | {
118 | return ConvertCSVtoDataTable(sr);
119 | }
120 | }
121 |
122 | /// Converts the csv to DataTable.
123 | /// Raw data containing the csv file.
124 | /// Each row of the file as a row in the returned DataTable.
125 | public static DataTable ConvertCSVtoDataTable(byte[] data)
126 | {
127 | MemoryStream ms = new MemoryStream(data);
128 | using (var sr = new StreamReader(ms))
129 | {
130 | return ConvertCSVtoDataTable(sr);
131 | }
132 | }
133 |
134 | /// Converts a CSV file to a DataTable.
135 | /// http://stackoverflow.com/questions/1050112/how-to-read-a-csv-file-into-a-net-datatable
136 | /// Stream with the CSV file. It is assumed that the file has a header on the first line with names of the columns.
137 | /// See parseCSVRow on details on the format of the CSV.
138 | /// Each row of the file as a row in the returned DataTable.
139 | ///
140 | /// Wrong format of the header of CSV file " + strFilePath + ": " + eError.Message
141 | /// or
142 | /// Wrong format of the CSV file on row " + (dt.Rows.Count + 1) + ": " + eError.Message
143 | ///
144 | public static DataTable ConvertCSVtoDataTable(StreamReader sr)
145 | {
146 | DataTable dt = new DataTable();
147 | char separator = ',';
148 | try
149 | {
150 | // detect the separator - this assumes it's ether semicolon or comma and that semicolon cannot be part of column names
151 | string firstLine = sr.ReadLine();
152 | if (firstLine.Contains(';'))
153 | separator = ';';
154 | List headers = parseCSVRow(firstLine, separator);
155 | foreach (string header in headers)
156 | dt.Columns.Add(header);
157 | }
158 | catch (Exception eError)
159 | {
160 | throw new FormatException("Wrong format of the header of CSV file: " + eError.Message);
161 | }
162 | while (!sr.EndOfStream)
163 | {
164 | try
165 | {
166 | List row = parseCSVRow(sr.ReadLine(), separator);
167 | DataRow dr = dt.NewRow();
168 | for (int i = 0; i < row.Count; i++)
169 | dr[i] = row[i];
170 | dt.Rows.Add(dr);
171 | }
172 | catch (Exception eError)
173 | {
174 | // technically it is the (dt.Rows.Count + 1)th row, but in the file the first row is the header so this should
175 | // give the user the number of the row in the actual file
176 | throw new FormatException("Wrong format of the CSV file on row " + (dt.Rows.Count + 2) + ": " + eError.Message);
177 | }
178 | }
179 | return dt;
180 | }
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/MKMTool/checkDisplayPrices.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace MKMTool
2 | {
3 | partial class CheckDisplayPrices
4 | {
5 | /// Required designer variable.
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | /// Clean up any resources being used.
9 | /// true if managed resources should be disposed; otherwise, false.
10 | protected override void Dispose(bool disposing)
11 | {
12 | if (disposing && (components != null))
13 | {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | /// Required method for Designer support - do not modify
22 | /// the contents of this method with the code editor.
23 | private void InitializeComponent()
24 | {
25 | this.editionBox = new System.Windows.Forms.ComboBox();
26 | this.checkDisplayPrice = new System.Windows.Forms.Button();
27 | this.mythicPerRareText = new System.Windows.Forms.TextBox();
28 | this.label1 = new System.Windows.Forms.Label();
29 | this.labelxy = new System.Windows.Forms.Label();
30 | this.raremythicPerPackText = new System.Windows.Forms.TextBox();
31 | this.label3 = new System.Windows.Forms.Label();
32 | this.uncommonPerPackText = new System.Windows.Forms.TextBox();
33 | this.label2 = new System.Windows.Forms.Label();
34 | this.mythicNotInBoosterText = new System.Windows.Forms.TextBox();
35 | this.label4 = new System.Windows.Forms.Label();
36 | this.rareNotInBoosterText = new System.Windows.Forms.TextBox();
37 | this.label5 = new System.Windows.Forms.Label();
38 | this.uncommonNotInBoosterText = new System.Windows.Forms.TextBox();
39 | this.boosterPerBoxText = new System.Windows.Forms.TextBox();
40 | this.label6 = new System.Windows.Forms.Label();
41 | this.SuspendLayout();
42 | //
43 | // editionBox
44 | //
45 | this.editionBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
46 | this.editionBox.FormattingEnabled = true;
47 | this.editionBox.Location = new System.Drawing.Point(12, 12);
48 | this.editionBox.Name = "editionBox";
49 | this.editionBox.Size = new System.Drawing.Size(260, 21);
50 | this.editionBox.TabIndex = 27;
51 | //
52 | // checkDisplayPrice
53 | //
54 | this.checkDisplayPrice.Location = new System.Drawing.Point(12, 221);
55 | this.checkDisplayPrice.Name = "checkDisplayPrice";
56 | this.checkDisplayPrice.Size = new System.Drawing.Size(260, 45);
57 | this.checkDisplayPrice.TabIndex = 28;
58 | this.checkDisplayPrice.Text = "Check expected sale value of singles in a display";
59 | this.checkDisplayPrice.UseVisualStyleBackColor = true;
60 | this.checkDisplayPrice.Click += new System.EventHandler(this.checkDisplayPrice_Click);
61 | //
62 | // mythicPerRareText
63 | //
64 | this.mythicPerRareText.Location = new System.Drawing.Point(12, 39);
65 | this.mythicPerRareText.Name = "mythicPerRareText";
66 | this.mythicPerRareText.Size = new System.Drawing.Size(57, 20);
67 | this.mythicPerRareText.TabIndex = 29;
68 | this.mythicPerRareText.Text = "8";
69 | //
70 | // label1
71 | //
72 | this.label1.AutoSize = true;
73 | this.label1.Location = new System.Drawing.Point(75, 42);
74 | this.label1.Name = "label1";
75 | this.label1.Size = new System.Drawing.Size(105, 13);
76 | this.label1.TabIndex = 31;
77 | this.label1.Text = "Mythic per Rare (1:x)";
78 | //
79 | // labelxy
80 | //
81 | this.labelxy.AutoSize = true;
82 | this.labelxy.Location = new System.Drawing.Point(75, 68);
83 | this.labelxy.Name = "labelxy";
84 | this.labelxy.Size = new System.Drawing.Size(133, 13);
85 | this.labelxy.TabIndex = 35;
86 | this.labelxy.Text = "Rare or Mythic per Booster";
87 | //
88 | // raremythicPerPackText
89 | //
90 | this.raremythicPerPackText.Location = new System.Drawing.Point(12, 65);
91 | this.raremythicPerPackText.Name = "raremythicPerPackText";
92 | this.raremythicPerPackText.Size = new System.Drawing.Size(57, 20);
93 | this.raremythicPerPackText.TabIndex = 34;
94 | this.raremythicPerPackText.Text = "1";
95 | //
96 | // label3
97 | //
98 | this.label3.AutoSize = true;
99 | this.label3.Location = new System.Drawing.Point(75, 94);
100 | this.label3.Name = "label3";
101 | this.label3.Size = new System.Drawing.Size(118, 13);
102 | this.label3.TabIndex = 37;
103 | this.label3.Text = "Uncommon per Booster";
104 | //
105 | // uncommonPerPackText
106 | //
107 | this.uncommonPerPackText.Location = new System.Drawing.Point(12, 91);
108 | this.uncommonPerPackText.Name = "uncommonPerPackText";
109 | this.uncommonPerPackText.Size = new System.Drawing.Size(57, 20);
110 | this.uncommonPerPackText.TabIndex = 36;
111 | this.uncommonPerPackText.Text = "3";
112 | //
113 | // label2
114 | //
115 | this.label2.AutoSize = true;
116 | this.label2.Location = new System.Drawing.Point(75, 146);
117 | this.label2.Name = "label2";
118 | this.label2.Size = new System.Drawing.Size(111, 13);
119 | this.label2.TabIndex = 41;
120 | this.label2.Text = "Mythic not in Boosters";
121 | //
122 | // mythicNotInBoosterText
123 | //
124 | this.mythicNotInBoosterText.Location = new System.Drawing.Point(12, 143);
125 | this.mythicNotInBoosterText.Name = "mythicNotInBoosterText";
126 | this.mythicNotInBoosterText.Size = new System.Drawing.Size(57, 20);
127 | this.mythicNotInBoosterText.TabIndex = 40;
128 | this.mythicNotInBoosterText.Text = "2";
129 | //
130 | // label4
131 | //
132 | this.label4.AutoSize = true;
133 | this.label4.Location = new System.Drawing.Point(75, 120);
134 | this.label4.Name = "label4";
135 | this.label4.Size = new System.Drawing.Size(103, 13);
136 | this.label4.TabIndex = 39;
137 | this.label4.Text = "Rare not in Boosters";
138 | //
139 | // rareNotInBoosterText
140 | //
141 | this.rareNotInBoosterText.Location = new System.Drawing.Point(12, 117);
142 | this.rareNotInBoosterText.Name = "rareNotInBoosterText";
143 | this.rareNotInBoosterText.Size = new System.Drawing.Size(57, 20);
144 | this.rareNotInBoosterText.TabIndex = 38;
145 | this.rareNotInBoosterText.Text = "2";
146 | //
147 | // label5
148 | //
149 | this.label5.AutoSize = true;
150 | this.label5.Location = new System.Drawing.Point(75, 172);
151 | this.label5.Name = "label5";
152 | this.label5.Size = new System.Drawing.Size(134, 13);
153 | this.label5.TabIndex = 43;
154 | this.label5.Text = "Uncommon not in Boosters";
155 | //
156 | // uncommonNotInBoosterText
157 | //
158 | this.uncommonNotInBoosterText.Location = new System.Drawing.Point(13, 169);
159 | this.uncommonNotInBoosterText.Name = "uncommonNotInBoosterText";
160 | this.uncommonNotInBoosterText.Size = new System.Drawing.Size(57, 20);
161 | this.uncommonNotInBoosterText.TabIndex = 42;
162 | this.uncommonNotInBoosterText.Text = "2";
163 | //
164 | // boosterPerBoxText
165 | //
166 | this.boosterPerBoxText.Location = new System.Drawing.Point(12, 195);
167 | this.boosterPerBoxText.Name = "boosterPerBoxText";
168 | this.boosterPerBoxText.Size = new System.Drawing.Size(57, 20);
169 | this.boosterPerBoxText.TabIndex = 44;
170 | this.boosterPerBoxText.Text = "36";
171 | //
172 | // label6
173 | //
174 | this.label6.AutoSize = true;
175 | this.label6.Location = new System.Drawing.Point(75, 198);
176 | this.label6.Name = "label6";
177 | this.label6.Size = new System.Drawing.Size(82, 13);
178 | this.label6.TabIndex = 45;
179 | this.label6.Text = "Booster per Box";
180 | //
181 | // CheckDisplayPrices
182 | //
183 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
184 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
185 | this.ClientSize = new System.Drawing.Size(284, 275);
186 | this.Controls.Add(this.label6);
187 | this.Controls.Add(this.boosterPerBoxText);
188 | this.Controls.Add(this.label5);
189 | this.Controls.Add(this.uncommonNotInBoosterText);
190 | this.Controls.Add(this.label2);
191 | this.Controls.Add(this.mythicNotInBoosterText);
192 | this.Controls.Add(this.label4);
193 | this.Controls.Add(this.rareNotInBoosterText);
194 | this.Controls.Add(this.label3);
195 | this.Controls.Add(this.uncommonPerPackText);
196 | this.Controls.Add(this.labelxy);
197 | this.Controls.Add(this.raremythicPerPackText);
198 | this.Controls.Add(this.label1);
199 | this.Controls.Add(this.mythicPerRareText);
200 | this.Controls.Add(this.checkDisplayPrice);
201 | this.Controls.Add(this.editionBox);
202 | this.MaximizeBox = false;
203 | this.Name = "CheckDisplayPrices";
204 | this.ShowIcon = false;
205 | this.Text = "Check Expected Display Value";
206 | this.VisibleChanged += new System.EventHandler(this.checkDisplayPrices_VisibleChanged);
207 | this.ResumeLayout(false);
208 | this.PerformLayout();
209 |
210 | }
211 |
212 | #endregion
213 |
214 | private System.Windows.Forms.ComboBox editionBox;
215 | private System.Windows.Forms.Button checkDisplayPrice;
216 | private System.Windows.Forms.TextBox mythicPerRareText;
217 | private System.Windows.Forms.Label label1;
218 | private System.Windows.Forms.Label labelxy;
219 | private System.Windows.Forms.TextBox raremythicPerPackText;
220 | private System.Windows.Forms.Label label3;
221 | private System.Windows.Forms.TextBox uncommonPerPackText;
222 | private System.Windows.Forms.Label label2;
223 | private System.Windows.Forms.TextBox mythicNotInBoosterText;
224 | private System.Windows.Forms.Label label4;
225 | private System.Windows.Forms.TextBox rareNotInBoosterText;
226 | private System.Windows.Forms.Label label5;
227 | private System.Windows.Forms.TextBox uncommonNotInBoosterText;
228 | private System.Windows.Forms.TextBox boosterPerBoxText;
229 | private System.Windows.Forms.Label label6;
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/MKMTool/CheckDisplayPrices.cs:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of MKMTool
3 |
4 | MKMTool is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | MKMTool is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with MKMTool. If not, see .
16 |
17 | Diese Datei ist Teil von MKMTool.
18 |
19 | MKMTool ist Freie Software: Sie können es unter den Bedingungen
20 | der GNU General Public License, wie von der Free Software Foundation,
21 | Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
22 | veröffentlichten Version, weiterverbreiten und/oder modifizieren.
23 |
24 | MKMTool wird in der Hoffnung, dass es nützlich sein wird, aber
25 | OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
26 | Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
27 | Siehe die GNU General Public License für weitere Details.
28 |
29 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
30 | Programm erhalten haben. Wenn nicht, siehe .
31 | */
32 | using System;
33 | using System.Globalization;
34 | using System.Threading.Tasks;
35 | using System.Windows.Forms;
36 | using System.Xml;
37 |
38 | namespace MKMTool
39 | {
40 | public partial class CheckDisplayPrices : Form
41 | {
42 |
43 | public CheckDisplayPrices()
44 | {
45 | InitializeComponent();
46 | }
47 |
48 | /// Instead of closing the window when the user presses (X) or ALT+F4, just hide it.
49 | /// Basically the intended behaviour is for the window to act as kind of a singleton object within the scope of its owner.
50 | /// The instance containing the event data.
51 | protected override void OnFormClosing(FormClosingEventArgs e)
52 | {
53 | base.OnFormClosing(e);
54 | if (e.CloseReason == CloseReason.UserClosing)
55 | {
56 | e.Cancel = true;
57 | Hide();
58 | }
59 | }
60 |
61 | // reload the expansion each time the form is made visible for the corner case that the expansion database changed in between
62 | private void checkDisplayPrices_VisibleChanged(object sender, EventArgs e)
63 | {
64 | if (Visible)
65 | {
66 | editionBox.Items.Clear();
67 | MKMDbManager.Instance.PopulateExpansionsComboBox(editionBox);
68 |
69 | editionBox.Sorted = true;
70 | editionBox.SelectedIndex = 135; // currently Gatecrash
71 | }
72 | }
73 |
74 | private async void checkDisplayPrice_Click(object sender, EventArgs e)
75 | {
76 | checkDisplayPrice.Enabled = false;
77 |
78 | // the window controls can't be accessed from a different thread -> have to parse them here and send as arguments
79 | var fMythicFactor = Convert.ToSingle(mythicPerRareText.Text, CultureInfo.InvariantCulture); // 1 out of 8 packs has a Mythic
80 | var fPackUncommon = Convert.ToSingle(uncommonPerPackText.Text, CultureInfo.InvariantCulture);
81 | var fPackRareMythic = Convert.ToSingle(raremythicPerPackText.Text, CultureInfo.InvariantCulture);
82 |
83 | var fRareCardsNotinPacks = Convert.ToSingle(rareNotInBoosterText.Text, CultureInfo.InvariantCulture); //rare and Mythic
84 | var fMythicCardsNotinPacks = Convert.ToSingle(mythicNotInBoosterText.Text, CultureInfo.InvariantCulture); //rare and Mythic
85 | var fUncommonCardsNotinPacks = Convert.ToSingle(uncommonNotInBoosterText.Text, CultureInfo.InvariantCulture); //rare and Mythic
86 |
87 | var fBoxContent = Convert.ToSingle(boosterPerBoxText.Text, CultureInfo.InvariantCulture); //36 Packs
88 | string editionID = (editionBox.SelectedItem as MKMHelpers.ComboboxItem).Value.ToString();
89 |
90 | // run the check in a separate thread so that the main GUI is correctly updated
91 | await Task.Run(() => checkDisplayPrice_run(fMythicFactor, fPackUncommon, fPackRareMythic, fRareCardsNotinPacks, fMythicCardsNotinPacks,
92 | fUncommonCardsNotinPacks, fBoxContent, editionID));
93 | checkDisplayPrice.Enabled = true;
94 | }
95 |
96 | /// Checks the expected ROI of a given display. Expected to be run in a separate thread
97 | private void checkDisplayPrice_run(float fMythicFactor, float fPackUncommon, float fPackRareMythic, float fRareCardsNotinPacks,
98 | float fMythicCardsNotinPacks, float fUncommonCardsNotinPacks, float fBoxContent, string editionID)
99 | {
100 | try
101 | {
102 | //used to determine index of best start edition
103 | //MessageBox.Show((editionBox.SelectedIndex.ToString()));
104 |
105 | var doc = MKMInteract.RequestHelper.GetExpansionsSingles(editionID);
106 | //would be easier if MKM would deliver detailed info with this call but ...
107 |
108 | MainView.Instance.LogMainWindow("====== Expansion Stats ======");
109 |
110 | //Multiplier
111 | float fCardsInSet = doc.SelectNodes("response/single").Count;
112 | MainView.Instance.LogMainWindow("Cards in set: " + fCardsInSet);
113 |
114 |
115 | var xRares = doc.SelectNodes("response/single/rarity[. = \"Rare\"]");
116 | var xMythic = doc.SelectNodes("response/single/rarity[. = \"Mythic\"]");
117 | var xUncommon = doc.SelectNodes("response/single/rarity[. = \"Uncommon\"]");
118 |
119 | var iCountRares = xRares.Count - fRareCardsNotinPacks; //53F;
120 | var iCountMythics = xMythic.Count - fMythicCardsNotinPacks; //15F;
121 | var iCountUncommons = xUncommon.Count - fUncommonCardsNotinPacks; //80F;
122 |
123 | MainView.Instance.LogMainWindow("Rares in set: " + iCountRares);
124 | MainView.Instance.LogMainWindow("Mythic in set: " + iCountMythics);
125 | MainView.Instance.LogMainWindow("Uncommon in set: " + iCountUncommons);
126 |
127 | //factors per booster
128 | var fFactorUncommon = fPackUncommon / iCountUncommons; //0,0375
129 | var fFactorMythicRareCombined = fPackRareMythic / (iCountRares + iCountMythics); // 0,014
130 | var fFactorMythic = fFactorMythicRareCombined / fMythicFactor; //chance is 1:8 for Mythic
131 | var fFactorRare = fFactorMythicRareCombined / fMythicFactor * (fMythicFactor - 1);
132 |
133 | MainView.Instance.LogMainWindow("====== Calculated Booster Factors ======");
134 | MainView.Instance.LogMainWindow("Uncommon: " + fFactorUncommon);
135 | MainView.Instance.LogMainWindow("MR Combo: " + fFactorMythicRareCombined);
136 | MainView.Instance.LogMainWindow("Rare:" + fFactorRare);
137 | MainView.Instance.LogMainWindow("Mythic:" + fFactorMythic);
138 |
139 | var fFactorUncommonBox = fFactorUncommon * fBoxContent;
140 | var fFactorMythicRareCombinedBox = fFactorMythicRareCombined * fBoxContent;
141 | var fFactorMythicBox = fFactorMythic * fBoxContent;
142 | var fFactorRareBox = fFactorRare * fBoxContent;
143 |
144 | MainView.Instance.LogMainWindow("====== Calculated Box Factors ======");
145 | MainView.Instance.LogMainWindow("Uncommon: " + fFactorUncommonBox);
146 | MainView.Instance.LogMainWindow("MR Combo: " + fFactorMythicRareCombinedBox);
147 | MainView.Instance.LogMainWindow("Rare:" + fFactorRareBox);
148 | MainView.Instance.LogMainWindow("Mythic:" + fFactorMythicBox);
149 |
150 | xRares = doc.SelectNodes("response/single");
151 |
152 | float fBoxValue = 0;
153 |
154 | foreach (XmlNode xn in xRares)
155 | {
156 | if (xn["rarity"].InnerText == "Rare")
157 | {
158 | MainView.Instance.LogMainWindow("Checking (R): " + xn["enName"].InnerText);
159 |
160 | var doc2 =
161 | MKMInteract.RequestHelper.MakeRequest(
162 | "https://api.cardmarket.com/ws/v2.0/products/" + xn["idProduct"].InnerText, "GET");
163 |
164 | if (doc2.HasChildNodes)
165 | {
166 | var fCardPrice =
167 | (float)Convert.ToDouble(
168 | doc2.SelectSingleNode("response/product/priceGuide/SELL").InnerText, CultureInfo.InvariantCulture);
169 |
170 | MainView.Instance.LogMainWindow("Current SELL Price: " + fCardPrice);
171 |
172 | fBoxValue += fCardPrice * fFactorMythicRareCombinedBox;
173 | //changed cause it's actually a rare + Mythic not rare or mythic I think? was fFactorRareBox;
174 | }
175 | }
176 |
177 | if (xn["rarity"].InnerText == "Mythic")
178 | {
179 | MainView.Instance.LogMainWindow("Checking (M): " + xn["enName"].InnerText);
180 |
181 | var doc2 =
182 | MKMInteract.RequestHelper.MakeRequest(
183 | "https://api.cardmarket.com/ws/v2.0/products/" + xn["idProduct"].InnerText, "GET");
184 |
185 | if (doc2.HasChildNodes)
186 | {
187 | var fCardPrice = Convert.ToSingle(
188 | doc2.SelectSingleNode("response/product/priceGuide/SELL").InnerText, CultureInfo.InvariantCulture);
189 | MainView.Instance.LogMainWindow("Current SELL Price: " + fCardPrice);
190 |
191 | fBoxValue += fCardPrice * fFactorMythicBox;
192 | }
193 | }
194 |
195 | if (xn["rarity"].InnerText == "Uncommon")
196 | {
197 | MainView.Instance.LogMainWindow("Checking (U): " + xn["enName"].InnerText);
198 |
199 | var doc2 =
200 | MKMInteract.RequestHelper.MakeRequest(
201 | "https://api.cardmarket.com/ws/v2.0/products/" + xn["idProduct"].InnerText, "GET");
202 |
203 | if (doc2.HasChildNodes)
204 | {
205 | var fCardPrice =
206 | (float)Convert.ToDouble(
207 | doc2.SelectSingleNode("response/product/priceGuide/SELL").InnerText, CultureInfo.InvariantCulture);
208 |
209 | MainView.Instance.LogMainWindow("Current SELL Price: " + fCardPrice);
210 |
211 | fBoxValue += fCardPrice * fFactorUncommonBox;
212 | }
213 | }
214 | }
215 | MainView.Instance.LogMainWindow("Calculated Result *: " + fBoxValue);
216 |
217 | MainView.Instance.LogMainWindow(
218 | "* Estimated average booster box singles value at MKM SELL Pricing (EUR)\n");
219 | }
220 | catch (Exception eError)
221 | {
222 | MKMHelpers.LogError("checking display prices", eError.Message, true);
223 | }
224 | }
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/MKMTool/MKMTool.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {EF8BE2AC-A470-4EBA-9147-0840DFE9DCE2}
8 | WinExe
9 | Properties
10 | MKMTool
11 | MKMTool
12 | v4.6.1
13 | 512
14 | true
15 | false
16 | publish\
17 | true
18 | Disk
19 | false
20 | Foreground
21 | 7
22 | Days
23 | false
24 | false
25 | true
26 | 0
27 | 1.0.0.%2a
28 | false
29 | true
30 |
31 |
32 |
33 |
34 |
35 | AnyCPU
36 | true
37 | full
38 | false
39 | bin\Debug\
40 | DEBUG;TRACE
41 | prompt
42 | 4
43 | false
44 |
45 |
46 | AnyCPU
47 | none
48 | true
49 | bin\Release\
50 | TRACE
51 | prompt
52 | 4
53 | false
54 | false
55 |
56 |
57 | mkmt.ico
58 |
59 |
60 |
61 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll
62 |
63 |
64 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | ..\packages\System.Data.SQLite.Core.1.0.105.2\lib\net451\System.Data.SQLite.dll
73 |
74 |
75 | ..\packages\System.Data.SQLite.EF6.1.0.105.2\lib\net451\System.Data.SQLite.EF6.dll
76 |
77 |
78 | ..\packages\System.Data.SQLite.Linq.1.0.105.2\lib\net451\System.Data.SQLite.Linq.dll
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | Form
90 |
91 |
92 | AccountInfo.cs
93 |
94 |
95 | Form
96 |
97 |
98 | CheckDisplayPrices.cs
99 |
100 |
101 | Form
102 |
103 |
104 | CheckWantsView.cs
105 |
106 |
107 |
108 |
109 |
110 | Form
111 |
112 |
113 | PopupListbox.cs
114 |
115 |
116 |
117 | Form
118 |
119 |
120 | PriceExternalList.cs
121 |
122 |
123 | Form
124 |
125 |
126 | SettingPresetStore.cs
127 |
128 |
129 | Form
130 |
131 |
132 | MainView.cs
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | Form
142 |
143 |
144 | StockView.cs
145 |
146 |
147 | Form
148 |
149 |
150 | UpdatePriceSettings.cs
151 |
152 |
153 | Form
154 |
155 |
156 | WantlistEditorView.cs
157 |
158 |
159 | AccountInfo.cs
160 |
161 |
162 | CheckDisplayPrices.cs
163 |
164 |
165 | CheckWantsView.cs
166 |
167 |
168 | PopupListbox.cs
169 |
170 |
171 | PriceExternalList.cs
172 |
173 |
174 | SettingPresetStore.cs
175 |
176 |
177 | MainView.cs
178 |
179 |
180 | ResXFileCodeGenerator
181 | Resources.Designer.cs
182 | Designer
183 |
184 |
185 | True
186 | Resources.resx
187 | True
188 |
189 |
190 | StockView.cs
191 |
192 |
193 | UpdatePriceSettings.cs
194 |
195 |
196 | WantlistEditorView.cs
197 |
198 |
199 |
200 |
201 | SettingsSingleFileGenerator
202 | Settings.Designer.cs
203 |
204 |
205 | True
206 | Settings.settings
207 | True
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 | Always
216 |
217 |
218 | Always
219 |
220 |
221 |
222 |
223 |
224 | False
225 | Microsoft .NET Framework 4.5.2 %28x86 and x64%29
226 | true
227 |
228 |
229 | False
230 | .NET Framework 3.5 SP1
231 | false
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 | Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".
240 |
241 |
242 |
243 |
244 | XCOPY "$(SolutionDir)Presets" "$(TargetDir)Presets\" /S /Y
245 |
246 |
253 |
--------------------------------------------------------------------------------
/MKMTool/WantlistEditorView.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace MKMTool
2 | {
3 | partial class WantlistEditorView
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.searchBox = new System.Windows.Forms.TextBox();
32 | this.wantListsBox = new System.Windows.Forms.ComboBox();
33 | this.cardView = new System.Windows.Forms.ListView();
34 | this.addButton = new System.Windows.Forms.Button();
35 | this.wantsView = new System.Windows.Forms.DataGridView();
36 | this.deleteItemButton = new System.Windows.Forms.Button();
37 | this.conditionCombo = new System.Windows.Forms.ComboBox();
38 | this.conditionBox = new System.Windows.Forms.Label();
39 | this.langCombo = new System.Windows.Forms.ComboBox();
40 | this.label1 = new System.Windows.Forms.Label();
41 | this.foilBox = new System.Windows.Forms.CheckBox();
42 | this.playsetBox = new System.Windows.Forms.CheckBox();
43 | this.alteredBox = new System.Windows.Forms.CheckBox();
44 | this.signedBox = new System.Windows.Forms.CheckBox();
45 | this.editionBox = new System.Windows.Forms.ComboBox();
46 | ((System.ComponentModel.ISupportInitialize)(this.wantsView)).BeginInit();
47 | this.SuspendLayout();
48 | //
49 | // searchBox
50 | //
51 | this.searchBox.Location = new System.Drawing.Point(2, 10);
52 | this.searchBox.Margin = new System.Windows.Forms.Padding(2);
53 | this.searchBox.Name = "searchBox";
54 | this.searchBox.Size = new System.Drawing.Size(279, 20);
55 | this.searchBox.TabIndex = 0;
56 | this.searchBox.TextChanged += new System.EventHandler(this.searchBox_TextChanged);
57 | //
58 | // wantListsBox
59 | //
60 | this.wantListsBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
61 | this.wantListsBox.FormattingEnabled = true;
62 | this.wantListsBox.Location = new System.Drawing.Point(460, 9);
63 | this.wantListsBox.Margin = new System.Windows.Forms.Padding(2);
64 | this.wantListsBox.Name = "wantListsBox";
65 | this.wantListsBox.Size = new System.Drawing.Size(695, 21);
66 | this.wantListsBox.TabIndex = 3;
67 | this.wantListsBox.SelectedIndexChanged += new System.EventHandler(this.wantListsBox_SelectedIndexChanged);
68 | //
69 | // cardView
70 | //
71 | this.cardView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
72 | | System.Windows.Forms.AnchorStyles.Left)));
73 | this.cardView.Location = new System.Drawing.Point(2, 36);
74 | this.cardView.Name = "cardView";
75 | this.cardView.Size = new System.Drawing.Size(454, 503);
76 | this.cardView.TabIndex = 13;
77 | this.cardView.UseCompatibleStateImageBehavior = false;
78 | this.cardView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.cardView_ColumnClick);
79 | //
80 | // addButton
81 | //
82 | this.addButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
83 | this.addButton.Location = new System.Drawing.Point(2, 594);
84 | this.addButton.Name = "addButton";
85 | this.addButton.Size = new System.Drawing.Size(454, 23);
86 | this.addButton.TabIndex = 15;
87 | this.addButton.Text = "Add selected cards to MKM Wantlist";
88 | this.addButton.UseVisualStyleBackColor = true;
89 | this.addButton.Click += new System.EventHandler(this.addButton_Click);
90 | //
91 | // wantsView
92 | //
93 | this.wantsView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
94 | | System.Windows.Forms.AnchorStyles.Left)
95 | | System.Windows.Forms.AnchorStyles.Right)));
96 | this.wantsView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
97 | this.wantsView.Location = new System.Drawing.Point(462, 36);
98 | this.wantsView.Name = "wantsView";
99 | this.wantsView.Size = new System.Drawing.Size(693, 550);
100 | this.wantsView.TabIndex = 16;
101 | //
102 | // deleteItemButton
103 | //
104 | this.deleteItemButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
105 | this.deleteItemButton.Location = new System.Drawing.Point(460, 594);
106 | this.deleteItemButton.Margin = new System.Windows.Forms.Padding(2);
107 | this.deleteItemButton.Name = "deleteItemButton";
108 | this.deleteItemButton.Size = new System.Drawing.Size(179, 23);
109 | this.deleteItemButton.TabIndex = 17;
110 | this.deleteItemButton.Text = "Delete Item";
111 | this.deleteItemButton.UseVisualStyleBackColor = true;
112 | this.deleteItemButton.Click += new System.EventHandler(this.deleteItemButton_Click);
113 | //
114 | // conditionCombo
115 | //
116 | this.conditionCombo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
117 | this.conditionCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
118 | this.conditionCombo.FormattingEnabled = true;
119 | this.conditionCombo.Items.AddRange(new object[] {
120 | "MT",
121 | "NM ",
122 | "EX",
123 | "GD",
124 | "LP",
125 | "PL",
126 | "PO"});
127 | this.conditionCombo.Location = new System.Drawing.Point(2, 544);
128 | this.conditionCombo.Margin = new System.Windows.Forms.Padding(2);
129 | this.conditionCombo.Name = "conditionCombo";
130 | this.conditionCombo.Size = new System.Drawing.Size(90, 21);
131 | this.conditionCombo.TabIndex = 18;
132 | //
133 | // conditionBox
134 | //
135 | this.conditionBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
136 | this.conditionBox.AutoSize = true;
137 | this.conditionBox.Location = new System.Drawing.Point(93, 547);
138 | this.conditionBox.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
139 | this.conditionBox.Name = "conditionBox";
140 | this.conditionBox.Size = new System.Drawing.Size(95, 13);
141 | this.conditionBox.TabIndex = 19;
142 | this.conditionBox.Text = "Minimum Condition";
143 | //
144 | // langCombo
145 | //
146 | this.langCombo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
147 | this.langCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
148 | this.langCombo.FormattingEnabled = true;
149 | this.langCombo.Location = new System.Drawing.Point(2, 570);
150 | this.langCombo.Margin = new System.Windows.Forms.Padding(2);
151 | this.langCombo.Name = "langCombo";
152 | this.langCombo.Size = new System.Drawing.Size(90, 21);
153 | this.langCombo.TabIndex = 20;
154 | //
155 | // label1
156 | //
157 | this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
158 | this.label1.AutoSize = true;
159 | this.label1.Location = new System.Drawing.Point(93, 573);
160 | this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
161 | this.label1.Name = "label1";
162 | this.label1.Size = new System.Drawing.Size(55, 13);
163 | this.label1.TabIndex = 21;
164 | this.label1.Text = "Language";
165 | //
166 | // foilBox
167 | //
168 | this.foilBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
169 | this.foilBox.AutoSize = true;
170 | this.foilBox.Location = new System.Drawing.Point(323, 549);
171 | this.foilBox.Margin = new System.Windows.Forms.Padding(2);
172 | this.foilBox.Name = "foilBox";
173 | this.foilBox.Size = new System.Drawing.Size(42, 17);
174 | this.foilBox.TabIndex = 22;
175 | this.foilBox.Text = "Foil";
176 | this.foilBox.UseVisualStyleBackColor = true;
177 | //
178 | // playsetBox
179 | //
180 | this.playsetBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
181 | this.playsetBox.AutoSize = true;
182 | this.playsetBox.Location = new System.Drawing.Point(323, 570);
183 | this.playsetBox.Margin = new System.Windows.Forms.Padding(2);
184 | this.playsetBox.Name = "playsetBox";
185 | this.playsetBox.Size = new System.Drawing.Size(60, 17);
186 | this.playsetBox.TabIndex = 23;
187 | this.playsetBox.Text = "Playset";
188 | this.playsetBox.UseVisualStyleBackColor = true;
189 | //
190 | // alteredBox
191 | //
192 | this.alteredBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
193 | this.alteredBox.AutoSize = true;
194 | this.alteredBox.Location = new System.Drawing.Point(396, 549);
195 | this.alteredBox.Margin = new System.Windows.Forms.Padding(2);
196 | this.alteredBox.Name = "alteredBox";
197 | this.alteredBox.Size = new System.Drawing.Size(59, 17);
198 | this.alteredBox.TabIndex = 24;
199 | this.alteredBox.Text = "Altered";
200 | this.alteredBox.UseVisualStyleBackColor = true;
201 | //
202 | // signedBox
203 | //
204 | this.signedBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
205 | this.signedBox.AutoSize = true;
206 | this.signedBox.Location = new System.Drawing.Point(396, 570);
207 | this.signedBox.Margin = new System.Windows.Forms.Padding(2);
208 | this.signedBox.Name = "signedBox";
209 | this.signedBox.Size = new System.Drawing.Size(59, 17);
210 | this.signedBox.TabIndex = 25;
211 | this.signedBox.Text = "Signed";
212 | this.signedBox.UseVisualStyleBackColor = true;
213 | //
214 | // editionBox
215 | //
216 | this.editionBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
217 | this.editionBox.FormattingEnabled = true;
218 | this.editionBox.Location = new System.Drawing.Point(286, 9);
219 | this.editionBox.Name = "editionBox";
220 | this.editionBox.Size = new System.Drawing.Size(170, 21);
221 | this.editionBox.TabIndex = 26;
222 | this.editionBox.SelectedIndexChanged += new System.EventHandler(this.editionBox_SelectedIndexChanged);
223 | //
224 | // WantlistEditorView
225 | //
226 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
227 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
228 | this.ClientSize = new System.Drawing.Size(1158, 623);
229 | this.Controls.Add(this.editionBox);
230 | this.Controls.Add(this.signedBox);
231 | this.Controls.Add(this.alteredBox);
232 | this.Controls.Add(this.playsetBox);
233 | this.Controls.Add(this.foilBox);
234 | this.Controls.Add(this.label1);
235 | this.Controls.Add(this.langCombo);
236 | this.Controls.Add(this.conditionBox);
237 | this.Controls.Add(this.conditionCombo);
238 | this.Controls.Add(this.deleteItemButton);
239 | this.Controls.Add(this.wantsView);
240 | this.Controls.Add(this.addButton);
241 | this.Controls.Add(this.wantListsBox);
242 | this.Controls.Add(this.searchBox);
243 | this.Controls.Add(this.cardView);
244 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
245 | this.Margin = new System.Windows.Forms.Padding(2);
246 | this.Name = "WantlistEditorView";
247 | this.ShowIcon = false;
248 | this.Text = "Wantlist Editor";
249 | this.Shown += new System.EventHandler(this.wantlistEditorView_Shown);
250 | this.VisibleChanged += new System.EventHandler(this.wantlistEditorView_VisibleChanged);
251 | ((System.ComponentModel.ISupportInitialize)(this.wantsView)).EndInit();
252 | this.ResumeLayout(false);
253 | this.PerformLayout();
254 |
255 | }
256 |
257 | #endregion
258 |
259 | private System.Windows.Forms.TextBox searchBox;
260 | private System.Windows.Forms.ComboBox wantListsBox;
261 | private System.Windows.Forms.ListView cardView;
262 | private System.Windows.Forms.Button addButton;
263 | private System.Windows.Forms.DataGridView wantsView;
264 | private System.Windows.Forms.Button deleteItemButton;
265 | private System.Windows.Forms.ComboBox conditionCombo;
266 | private System.Windows.Forms.Label conditionBox;
267 | private System.Windows.Forms.ComboBox langCombo;
268 | private System.Windows.Forms.Label label1;
269 | private System.Windows.Forms.CheckBox foilBox;
270 | private System.Windows.Forms.CheckBox playsetBox;
271 | private System.Windows.Forms.CheckBox alteredBox;
272 | private System.Windows.Forms.CheckBox signedBox;
273 | private System.Windows.Forms.ComboBox editionBox;
274 | }
275 | }
276 |
--------------------------------------------------------------------------------
/MKMTool/WantlistEditorView.cs:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of MKMTool
3 |
4 | MKMTool is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | MKMTool is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with MKMTool. If not, see .
16 |
17 | Diese Datei ist Teil von MKMTool.
18 |
19 | MKMTool ist Freie Software: Sie können es unter den Bedingungen
20 | der GNU General Public License, wie von der Free Software Foundation,
21 | Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
22 | veröffentlichten Version, weiterverbreiten und/oder modifizieren.
23 |
24 | MKMTool wird in der Hoffnung, dass es nützlich sein wird, aber
25 | OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
26 | Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
27 | Siehe die GNU General Public License für weitere Details.
28 |
29 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
30 | Programm erhalten haben. Wenn nicht, siehe .
31 | */
32 |
33 | using System;
34 | using System.Collections;
35 | using System.Data;
36 | using System.Drawing;
37 | using System.Windows.Forms;
38 | using System.Xml;
39 |
40 | namespace MKMTool
41 | {
42 | public partial class WantlistEditorView : Form
43 | {
44 | private DataTable dj;
45 | // Column Sort for listView Elements:
46 | // https://msdn.microsoft.com/en-us/library/ms996467.aspx?f=255&MSPPError=-2147217396
47 |
48 | private int sortColumn = -1;
49 |
50 | public WantlistEditorView()
51 | {
52 | InitializeComponent();
53 | }
54 |
55 | /// Instead of closing the window when the user presses (X) or ALT+F4, just hide it.
56 | /// Basically the intended behaviour is for the window to act as kind of a singleton object within the scope of its owner.
57 | /// The instance containing the event data.
58 | protected override void OnFormClosing(FormClosingEventArgs e)
59 | {
60 | base.OnFormClosing(e);
61 | if (e.CloseReason == CloseReason.UserClosing)
62 | {
63 | e.Cancel = true;
64 | Hide();
65 | }
66 | }
67 |
68 | // done only once - languages never change
69 | private void wantlistEditorView_Shown(object sender, EventArgs e)
70 | {
71 | foreach (var Lang in MKMHelpers.LanguagesNames)
72 | {
73 | var item = new MKMHelpers.ComboboxItem
74 | {
75 | Text = Lang.Value,
76 | Value = Lang.Key
77 | };
78 |
79 | langCombo.Items.Add(item);
80 | langCombo.SelectedIndex = 0;
81 | }
82 | }
83 |
84 | // Reload the tables based on database each time the form is made visible for the corner case that
85 | // the database changed in between reload want lists in case user added a new one through MKM.
86 | private void wantlistEditorView_VisibleChanged(object sender, EventArgs e)
87 | {
88 | if (Visible)
89 | {
90 | editionBox.Items.Clear();
91 | MKMDbManager.Instance.PopulateExpansionsComboBox(editionBox);
92 | editionBox.Sorted = true;
93 |
94 | InitCardView();
95 | InitWantLists();
96 |
97 | conditionCombo.SelectedIndex = 3;
98 | }
99 | }
100 |
101 | public void InitWantLists()
102 | {
103 | XmlDocument doc;
104 |
105 | try
106 | {
107 | doc = MKMInteract.RequestHelper.GetWantsLists();
108 | }
109 | catch (Exception eError)
110 | {
111 | MKMHelpers.LogError("initializing want list, editor will be disabled", eError.Message, true);
112 | addButton.Enabled = false;
113 | deleteItemButton.Enabled = false;
114 | return;
115 | }
116 |
117 | var node = doc.GetElementsByTagName("wantslist");
118 |
119 | if (node.Count > 0)
120 | {
121 | wantListsBox.Items.Clear();
122 | foreach (XmlNode nWantlist in node)
123 | {
124 | var item = new MKMHelpers.ComboboxItem();
125 |
126 | item.Text = nWantlist["name"].InnerText;
127 | item.Value = nWantlist["idWantsList"].InnerText;
128 |
129 | wantListsBox.Items.Add(item);
130 |
131 | wantListsBox.SelectedIndex = 0;
132 | }
133 | }
134 | }
135 |
136 | public void InitCardView()
137 | {
138 | cardView.Items.Clear();
139 | cardView.View = View.Details;
140 | cardView.GridLines = true;
141 | cardView.FullRowSelect = true;
142 |
143 | cardView.BackColor = Color.WhiteSmoke;
144 |
145 | cardView.Columns.Add("ProductID", 60);
146 | cardView.Columns.Add("Card Name", 220);
147 | cardView.Columns.Add("Edition", 120);
148 |
149 | dj = new DataTable();
150 |
151 | // note - we have expansions only for MTG cards, so non-mtg will not have the expansion name
152 | var inventorySinglesOnly = MKMDbManager.Instance.InventorySinglesOnly.CopyToDataTable();
153 | dj = MKMDbManager.JoinDataTables(inventorySinglesOnly, MKMDbManager.Instance.Expansions,
154 | (row1, row2) => row1.Field(MKMDbManager.InventoryFields.ExpansionID) == row2.Field(MKMDbManager.ExpansionsFields.ExpansionID));
155 |
156 | foreach (DataRow row in dj.Rows)
157 | {
158 | var item = new ListViewItem(row[MKMDbManager.InventoryFields.ProductID].ToString());
159 |
160 | item.SubItems.Add(row[MKMDbManager.InventoryFields.Name].ToString());
161 | item.SubItems.Add(row[MKMDbManager.ExpansionsFields.Name].ToString());
162 |
163 | cardView.Items.Add(item);
164 | }
165 | }
166 |
167 | public void ProcessSearchBox()
168 | {
169 | if ((searchBox.Text.Length > 3) || (editionBox.Text != ""))
170 | {
171 | cardView.Items.Clear();
172 |
173 | foreach (DataRow row in dj.Rows)
174 | {
175 | var item = new ListViewItem(row[MKMDbManager.InventoryFields.ProductID].ToString());
176 |
177 | if (row[MKMDbManager.InventoryFields.Name].ToString().Contains(searchBox.Text))
178 | {
179 | if (editionBox.Text != "")
180 | {
181 | if (row[MKMDbManager.ExpansionsFields.Name].ToString() != editionBox.Text)
182 | {
183 | continue;
184 | }
185 | }
186 |
187 | item.SubItems.Add(row[MKMDbManager.InventoryFields.Name].ToString());
188 | item.SubItems.Add(row[MKMDbManager.ExpansionsFields.Name].ToString());
189 |
190 | cardView.Items.Add(item);
191 | }
192 | }
193 | }
194 | }
195 |
196 | private void searchBox_TextChanged(object sender, EventArgs e)
197 | {
198 | ProcessSearchBox();
199 | }
200 |
201 |
202 | private void wantsListBoxReload()
203 | {
204 | var sListId = (wantListsBox.SelectedItem as MKMHelpers.ComboboxItem).Value.ToString();
205 |
206 | wantsView.Columns.Clear();
207 | DataTable dv;
208 | try
209 | {
210 |
211 | var doc = MKMInteract.RequestHelper.GetWantsListByID(sListId);
212 |
213 | var xmlReader = new XmlNodeReader(doc);
214 |
215 | var ds = new DataSet();
216 |
217 | ds.ReadXml(xmlReader);
218 |
219 | if (!ds.Tables.Contains("item"))
220 | return;
221 |
222 | dv = ds.Tables["item"];
223 | dv.Columns.Add("enName");
224 | dv.Columns.Add("expansionName");
225 | dv.Columns["enName"].SetOrdinal(0); // put the name and expansion at the beginning of the table
226 | dv.Columns["expansionName"].SetOrdinal(1);
227 | int itemCounter = 0;
228 | foreach (XmlNode child in doc["response"]["wantslist"].ChildNodes)
229 | {
230 | if (child.Name == "item")
231 | {
232 | if (child["type"].InnerText == "product")
233 | {
234 | dv.Rows[itemCounter]["enName"] = child["product"]["enName"].InnerText;
235 | dv.Rows[itemCounter]["expansionName"] = child["product"]["expansionName"].InnerText;
236 | }
237 | else // it is a metaproduct
238 | {
239 | dv.Rows[itemCounter]["enName"] = child["metaproduct"]["enName"].InnerText; // we don't care which child is the first, the name is the same for all
240 | // we would have to do an additional API call to get the list of expansions
241 | // given that the current code refreshes this view every time an item is added to wantlist, it is not very practical
242 | dv.Rows[itemCounter]["expansionName"] = "";
243 | }
244 | itemCounter++;
245 | }
246 | }
247 | dv = ds.Tables["item"];
248 | }
249 | catch (Exception eError)
250 | {
251 | MKMHelpers.LogError("processing wantlist " + sListId + ", it will be ignored", eError.Message, true);
252 | return;
253 | }
254 | if (dv.Select().Length > 0)
255 | {
256 | wantsView.AutoGenerateColumns = true;
257 | wantsView.DataSource = dv;
258 |
259 | wantsView.Refresh();
260 |
261 | if (wantsView.Columns.Contains("idProduct")) // if the wantlist has only metaproducts, there will be no idProduct entry
262 | wantsView.Columns["idProduct"].Visible = false;
263 | wantsView.Columns["idWant"].Visible = false;
264 | wantsView.Columns["type"].Visible = false;
265 | wantsView.Columns["wishPrice"].Visible = false;
266 | wantsView.Columns["count"].Visible = false;
267 |
268 | wantsView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
269 | wantsView.ReadOnly = true;
270 | }
271 | }
272 |
273 | private void wantListsBox_SelectedIndexChanged(object sender, EventArgs e)
274 | {
275 | wantsListBoxReload();
276 | }
277 |
278 | private void addButton_Click(object sender, EventArgs e)
279 | {
280 | foreach (ListViewItem item in cardView.SelectedItems)
281 | {
282 | var idProduct = item.Text;
283 |
284 | //MessageBox.Show(idProduct);
285 |
286 | //addWantsListBody(string idProduct, string minCondition, string idLanguage, string isFoil, string isAltered, string isPlayset, string isSigned)
287 | var sRequestXML = MKMInteract.RequestHelper.AddWantsListBody(idProduct,
288 | conditionCombo.Text,
289 | (langCombo.SelectedItem as MKMHelpers.ComboboxItem).Value.ToString(),
290 | foilBox.CheckState.ToString(),
291 | alteredBox.CheckState.ToString(),
292 | playsetBox.CheckState.ToString(),
293 | signedBox.CheckState.ToString());
294 |
295 | sRequestXML = MKMInteract.RequestHelper.GetRequestBody(sRequestXML);
296 |
297 | try
298 | {
299 | var sListId = (wantListsBox.SelectedItem as MKMHelpers.ComboboxItem).Value.ToString();
300 |
301 | MKMInteract.RequestHelper.MakeRequest("https://api.cardmarket.com/ws/v2.0/wantslist/" + sListId, "PUT",
302 | sRequestXML);
303 | }
304 | catch (Exception eError)
305 | {
306 | MKMHelpers.LogError("adding to wantlist, product id " + idProduct, eError.Message, true, sRequestXML);
307 | return;
308 | }
309 | }
310 | wantsListBoxReload();
311 | }
312 |
313 | private void deleteItemButton_Click(object sender, EventArgs e)
314 | {
315 | var iCellIndex = wantsView.Columns["idWant"].Index;
316 | if (wantsView.SelectedRows.Count == 0)
317 | {
318 | MessageBox.Show("Please select the row you want to delete!");
319 | return;
320 | }
321 |
322 | foreach (DataGridViewRow selectedRow in wantsView.SelectedRows)
323 | {
324 | string idWant = selectedRow.Cells[iCellIndex].Value.ToString();
325 |
326 | string sRequestXML = MKMInteract.RequestHelper.DeleteWantsListBody(idWant);
327 | sRequestXML = MKMInteract.RequestHelper.GetRequestBody(sRequestXML);
328 | string sListId = (wantListsBox.SelectedItem as MKMHelpers.ComboboxItem).Value.ToString();
329 |
330 | try
331 | {
332 | MKMInteract.RequestHelper.MakeRequest("https://api.cardmarket.com/ws/v2.0/wantslist/" + sListId, "PUT",
333 | sRequestXML);
334 | }
335 | catch (Exception eError)
336 | {
337 | MKMHelpers.LogError("deleting from wantlist item #" + idWant, eError.Message, true, sRequestXML);
338 | }
339 | }
340 | wantsListBoxReload();
341 | }
342 |
343 | private void cardView_ColumnClick(object sender, ColumnClickEventArgs e)
344 | {
345 | //prevent long loading clicks
346 | if (searchBox.Text.Length < 4)
347 | {
348 | return;
349 | }
350 |
351 | // Determine whether the column is the same as the last column clicked.
352 | if (e.Column != sortColumn)
353 | {
354 | // Set the sort column to the new column.
355 | sortColumn = e.Column;
356 | // Set the sort order to ascending by default.
357 | cardView.Sorting = SortOrder.Ascending;
358 | }
359 | else
360 | {
361 | // Determine what the last sort order was and change it.
362 | if (cardView.Sorting == SortOrder.Ascending)
363 | cardView.Sorting = SortOrder.Descending;
364 | else
365 | cardView.Sorting = SortOrder.Ascending;
366 | }
367 |
368 | // Call the sort method to manually sort.
369 | cardView.Sort();
370 | // Set the ListViewItemSorter property to a new ListViewItemComparer
371 | // object.
372 | cardView.ListViewItemSorter = new ListViewItemComparer(e.Column, cardView.Sorting);
373 | }
374 |
375 | private void editionBox_SelectedIndexChanged(object sender, EventArgs e)
376 | {
377 | ProcessSearchBox();
378 | }
379 |
380 | // Implements the manual sorting of items by columns.
381 | private class ListViewItemComparer : IComparer
382 | {
383 | private readonly int col;
384 | private readonly SortOrder order;
385 |
386 | public ListViewItemComparer()
387 | {
388 | col = 0;
389 | order = SortOrder.Ascending;
390 | }
391 |
392 | public ListViewItemComparer(int column, SortOrder order)
393 | {
394 | col = column;
395 | this.order = order;
396 | }
397 |
398 | public int Compare(object x, object y)
399 | {
400 | var returnVal = -1;
401 | returnVal = string.Compare(((ListViewItem)x).SubItems[col].Text,
402 | ((ListViewItem)y).SubItems[col].Text);
403 | // Determine whether the sort order is descending.
404 | if (order == SortOrder.Descending)
405 | // Invert the value returned by String.Compare.
406 | returnVal *= -1;
407 | return returnVal;
408 | }
409 | }
410 | }
411 | }
412 |
--------------------------------------------------------------------------------