First commit

This commit is contained in:
argonlefou 2024-07-07 09:22:24 +02:00
commit 5260319a91
35 changed files with 4936 additions and 0 deletions

673
.gitignore vendored Normal file
View File

@ -0,0 +1,673 @@
# Created by https://www.gitignore.io/api/visualstudio
### VisualStudio ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
#Licenced DLL for Unity plugin
Assembly-CSharp.dll
UnityEngine.dll
UnityEngine.Networking.dll
UnityEngine.UI.dll
UnityEngine*.dll
Virtuallyz*.dll
Unity*.dll
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
### VisualStudio Patch ###
# By default, sensitive information, such as encrypted password
# should be stored in the .pubxml.user file.
*.pubxml.user
# End of https://www.gitignore.io/api/visualstudio
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser

26
Transformers2.sln Normal file
View File

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C# Express 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Transformers2_Launcher", "Transformers2_Launcher\Transformers2_Launcher.csproj", "{5D726FF6-B1A8-43C7-BEE8-EFC9E1E88DE0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Transformers2_Configurator", "Transformers2_Configurator\Transformers2_Configurator.csproj", "{98C69C86-F8A8-4949-903C-B89D93B78A21}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5D726FF6-B1A8-43C7-BEE8-EFC9E1E88DE0}.Debug|x86.ActiveCfg = Release|x86
{5D726FF6-B1A8-43C7-BEE8-EFC9E1E88DE0}.Debug|x86.Build.0 = Release|x86
{5D726FF6-B1A8-43C7-BEE8-EFC9E1E88DE0}.Release|x86.ActiveCfg = Release|x86
{5D726FF6-B1A8-43C7-BEE8-EFC9E1E88DE0}.Release|x86.Build.0 = Release|x86
{98C69C86-F8A8-4949-903C-B89D93B78A21}.Debug|x86.ActiveCfg = Release|x86
{98C69C86-F8A8-4949-903C-B89D93B78A21}.Debug|x86.Build.0 = Release|x86
{98C69C86-F8A8-4949-903C-B89D93B78A21}.Release|x86.ActiveCfg = Release|x86
{98C69C86-F8A8-4949-903C-B89D93B78A21}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Transformers2_Configurator
{
static class Program
{
/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new WndMain());
}
}
}

View File

@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Les informations générales relatives à un assembly dépendent de
// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations
// associées à un assembly.
[assembly: AssemblyTitle("Transformers2_Configurator")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Transformers2_Configurator")]
[assembly: AssemblyCopyright("Argonlefou © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly
// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de
// COM, affectez la valeur true à l'attribut ComVisible sur ce type.
[assembly: ComVisible(false)]
// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM
[assembly: Guid("4366bc2d-3164-46cf-bd7f-ff5aee506506")]
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
//
// Version principale
// Version secondaire
// Numéro de build
// Révision
//
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
// en utilisant '*', comme indiqué ci-dessous :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Ce code a été généré par un outil.
// Version du runtime :4.0.30319.42000
//
// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
// le code est régénéré.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Transformers2_Configurator.Properties {
using System;
/// <summary>
/// Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées.
/// </summary>
// Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder
// à l'aide d'un outil, tel que ResGen ou Visual Studio.
// Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen
// avec l'option /str ou régénérez votre projet VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Retourne l'instance ResourceManager mise en cache utilisée par cette classe.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Transformers2_Configurator.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Remplace la propriété CurrentUICulture du thread actuel pour toutes
/// les recherches de ressources à l'aide de cette classe de ressource fortement typée.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Ce code a été généré par un outil.
// Version du runtime :4.0.30319.42000
//
// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
// le code est régénéré.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Transformers2_Configurator.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{98C69C86-F8A8-4949-903C-B89D93B78A21}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Transformers2_Configurator</RootNamespace>
<AssemblyName>Transformers2_Configurator</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>chip-processor-svgrepo-com.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="WndMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="WndMain.Designer.cs">
<DependentUpon>WndMain.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<EmbeddedResource Include="WndMain.resx">
<DependentUpon>WndMain.cs</DependentUpon>
</EmbeddedResource>
<None Include="app.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="chip-processor-svgrepo-com.ico" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,697 @@
namespace Transformers2_Configurator
{
partial class WndMain
{
/// <summary>
/// Variable nécessaire au concepteur.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Nettoyage des ressources utilisées.
/// </summary>
/// <param name="disposing">true si les ressources managées doivent être supprimées ; sinon, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Code généré par le Concepteur Windows Form
/// <summary>
/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
/// le contenu de cette méthode avec l'éditeur de code.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WndMain));
this.Cbox_EntryType = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.Cbox_FreePlay = new System.Windows.Forms.ComboBox();
this.panel2 = new System.Windows.Forms.Panel();
this.Cbox_EnglishSubtitles = new System.Windows.Forms.ComboBox();
this.label15 = new System.Windows.Forms.Label();
this.label21 = new System.Windows.Forms.Label();
this.Cbox_FirstMn = new System.Windows.Forms.ComboBox();
this.label20 = new System.Windows.Forms.Label();
this.Cbox_EnnemyBoost = new System.Windows.Forms.ComboBox();
this.Cbox_Language = new System.Windows.Forms.ComboBox();
this.label19 = new System.Windows.Forms.Label();
this.Cbox_Swipe = new System.Windows.Forms.ComboBox();
this.label10 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.Cbox_StageSelect = new System.Windows.Forms.ComboBox();
this.label6 = new System.Windows.Forms.Label();
this.Cbox_KidsMode = new System.Windows.Forms.ComboBox();
this.Cbox_ContinueCountdown = new System.Windows.Forms.ComboBox();
this.label7 = new System.Windows.Forms.Label();
this.Cbox_P2Recoil = new System.Windows.Forms.ComboBox();
this.label12 = new System.Windows.Forms.Label();
this.label13 = new System.Windows.Forms.Label();
this.Cbox_P1Recoil = new System.Windows.Forms.ComboBox();
this.label14 = new System.Windows.Forms.Label();
this.Cbox_Advertise = new System.Windows.Forms.ComboBox();
this.label8 = new System.Windows.Forms.Label();
this.Cbox_Difficulty = new System.Windows.Forms.ComboBox();
this.label9 = new System.Windows.Forms.Label();
this.Cbox_Revival = new System.Windows.Forms.ComboBox();
this.panel1 = new System.Windows.Forms.Panel();
this.Btn_Close = new System.Windows.Forms.Button();
this.Btn_Save = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label24 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.label16 = new System.Windows.Forms.Label();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.label3 = new System.Windows.Forms.Label();
this.Cbox_ScreenMode = new System.Windows.Forms.ComboBox();
this.label4 = new System.Windows.Forms.Label();
this.label11 = new System.Windows.Forms.Label();
this.Cbox_Resolution = new System.Windows.Forms.ComboBox();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox3.SuspendLayout();
this.SuspendLayout();
//
// Cbox_EntryType
//
this.Cbox_EntryType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.Cbox_EntryType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_EntryType.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_EntryType.FormattingEnabled = true;
this.Cbox_EntryType.Items.AddRange(new object[] {
"COIN",
"CARD",
"SWIPE"});
this.Cbox_EntryType.Location = new System.Drawing.Point(162, 62);
this.Cbox_EntryType.Name = "Cbox_EntryType";
this.Cbox_EntryType.Size = new System.Drawing.Size(86, 24);
this.Cbox_EntryType.TabIndex = 3;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(6, 65);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(88, 16);
this.label2.TabIndex = 2;
this.label2.Text = "ENTRY TYPE";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(6, 35);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(72, 16);
this.label1.TabIndex = 1;
this.label1.Text = "FREEPLAY";
//
// Cbox_FreePlay
//
this.Cbox_FreePlay.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.Cbox_FreePlay.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_FreePlay.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_FreePlay.FormattingEnabled = true;
this.Cbox_FreePlay.Items.AddRange(new object[] {
"OFF",
"ON"});
this.Cbox_FreePlay.Location = new System.Drawing.Point(162, 32);
this.Cbox_FreePlay.Name = "Cbox_FreePlay";
this.Cbox_FreePlay.Size = new System.Drawing.Size(86, 24);
this.Cbox_FreePlay.TabIndex = 0;
//
// panel2
//
this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.panel2.Location = new System.Drawing.Point(305, 21);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(4, 225);
this.panel2.TabIndex = 34;
//
// Cbox_EnglishSubtitles
//
this.Cbox_EnglishSubtitles.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_EnglishSubtitles.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_EnglishSubtitles.FormattingEnabled = true;
this.Cbox_EnglishSubtitles.Items.AddRange(new object[] {
"OFF",
"ON"});
this.Cbox_EnglishSubtitles.Location = new System.Drawing.Point(507, 157);
this.Cbox_EnglishSubtitles.Name = "Cbox_EnglishSubtitles";
this.Cbox_EnglishSubtitles.Size = new System.Drawing.Size(60, 24);
this.Cbox_EnglishSubtitles.TabIndex = 33;
//
// label15
//
this.label15.AutoSize = true;
this.label15.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label15.Location = new System.Drawing.Point(341, 160);
this.label15.Name = "label15";
this.label15.Size = new System.Drawing.Size(144, 16);
this.label15.TabIndex = 32;
this.label15.Text = "ENGLISH SUBTITLES";
//
// label21
//
this.label21.AutoSize = true;
this.label21.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label21.Location = new System.Drawing.Point(341, 65);
this.label21.Name = "label21";
this.label21.Size = new System.Drawing.Size(160, 16);
this.label21.TabIndex = 31;
this.label21.Text = "1ST MINUTE GAMEPLAY";
//
// Cbox_FirstMn
//
this.Cbox_FirstMn.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_FirstMn.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_FirstMn.FormattingEnabled = true;
this.Cbox_FirstMn.Items.AddRange(new object[] {
"OFF",
"90s",
"120s",
"180s"});
this.Cbox_FirstMn.Location = new System.Drawing.Point(507, 62);
this.Cbox_FirstMn.Name = "Cbox_FirstMn";
this.Cbox_FirstMn.Size = new System.Drawing.Size(60, 24);
this.Cbox_FirstMn.TabIndex = 30;
//
// label20
//
this.label20.AutoSize = true;
this.label20.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label20.Location = new System.Drawing.Point(341, 35);
this.label20.Name = "label20";
this.label20.Size = new System.Drawing.Size(104, 16);
this.label20.TabIndex = 29;
this.label20.Text = "ENNEMY BOOST";
//
// Cbox_EnnemyBoost
//
this.Cbox_EnnemyBoost.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_EnnemyBoost.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_EnnemyBoost.FormattingEnabled = true;
this.Cbox_EnnemyBoost.Items.AddRange(new object[] {
"OFF",
"MID",
"HIGH"});
this.Cbox_EnnemyBoost.Location = new System.Drawing.Point(507, 32);
this.Cbox_EnnemyBoost.Name = "Cbox_EnnemyBoost";
this.Cbox_EnnemyBoost.Size = new System.Drawing.Size(60, 24);
this.Cbox_EnnemyBoost.TabIndex = 28;
//
// Cbox_Language
//
this.Cbox_Language.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_Language.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_Language.FormattingEnabled = true;
this.Cbox_Language.Items.AddRange(new object[] {
"ENGLISH",
"CHINESE",
"SPANISH",
"PORTUGUESE",
"ITALIAN",
"TURKISH",
"RUSSIAN"});
this.Cbox_Language.Location = new System.Drawing.Point(153, 32);
this.Cbox_Language.Name = "Cbox_Language";
this.Cbox_Language.Size = new System.Drawing.Size(121, 24);
this.Cbox_Language.TabIndex = 27;
//
// label19
//
this.label19.AutoSize = true;
this.label19.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label19.Location = new System.Drawing.Point(19, 35);
this.label19.Name = "label19";
this.label19.Size = new System.Drawing.Size(72, 16);
this.label19.TabIndex = 26;
this.label19.Text = "LANGUAGE";
//
// Cbox_Swipe
//
this.Cbox_Swipe.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_Swipe.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_Swipe.FormattingEnabled = true;
this.Cbox_Swipe.Items.AddRange(new object[] {
"OFF",
"ON"});
this.Cbox_Swipe.Location = new System.Drawing.Point(507, 187);
this.Cbox_Swipe.Name = "Cbox_Swipe";
this.Cbox_Swipe.Size = new System.Drawing.Size(60, 24);
this.Cbox_Swipe.TabIndex = 25;
//
// label10
//
this.label10.AutoSize = true;
this.label10.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label10.Location = new System.Drawing.Point(341, 190);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(152, 16);
this.label10.TabIndex = 24;
this.label10.Text = "SWIPE CARD TO PLAY";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label5.Location = new System.Drawing.Point(341, 130);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(104, 16);
this.label5.TabIndex = 23;
this.label5.Text = "SELECT STAGE";
//
// Cbox_StageSelect
//
this.Cbox_StageSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_StageSelect.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_StageSelect.FormattingEnabled = true;
this.Cbox_StageSelect.Items.AddRange(new object[] {
"OFF",
"ON"});
this.Cbox_StageSelect.Location = new System.Drawing.Point(507, 127);
this.Cbox_StageSelect.Name = "Cbox_StageSelect";
this.Cbox_StageSelect.Size = new System.Drawing.Size(60, 24);
this.Cbox_StageSelect.TabIndex = 22;
//
// label6
//
this.label6.AutoSize = true;
this.label6.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label6.Location = new System.Drawing.Point(341, 97);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(80, 16);
this.label6.TabIndex = 8;
this.label6.Text = "KIDS MODE";
//
// Cbox_KidsMode
//
this.Cbox_KidsMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_KidsMode.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_KidsMode.FormattingEnabled = true;
this.Cbox_KidsMode.Items.AddRange(new object[] {
"OFF",
"ON"});
this.Cbox_KidsMode.Location = new System.Drawing.Point(507, 94);
this.Cbox_KidsMode.Name = "Cbox_KidsMode";
this.Cbox_KidsMode.Size = new System.Drawing.Size(60, 24);
this.Cbox_KidsMode.TabIndex = 7;
//
// Cbox_ContinueCountdown
//
this.Cbox_ContinueCountdown.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_ContinueCountdown.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_ContinueCountdown.FormattingEnabled = true;
this.Cbox_ContinueCountdown.Items.AddRange(new object[] {
"10",
"20",
"30"});
this.Cbox_ContinueCountdown.Location = new System.Drawing.Point(214, 214);
this.Cbox_ContinueCountdown.Name = "Cbox_ContinueCountdown";
this.Cbox_ContinueCountdown.Size = new System.Drawing.Size(60, 24);
this.Cbox_ContinueCountdown.TabIndex = 18;
//
// label7
//
this.label7.AutoSize = true;
this.label7.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label7.Location = new System.Drawing.Point(19, 217);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(152, 16);
this.label7.TabIndex = 6;
this.label7.Text = "CONTINUE COUNTDOWN";
//
// Cbox_P2Recoil
//
this.Cbox_P2Recoil.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_P2Recoil.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_P2Recoil.FormattingEnabled = true;
this.Cbox_P2Recoil.Items.AddRange(new object[] {
"OFF",
"ON"});
this.Cbox_P2Recoil.Location = new System.Drawing.Point(214, 184);
this.Cbox_P2Recoil.Name = "Cbox_P2Recoil";
this.Cbox_P2Recoil.Size = new System.Drawing.Size(60, 24);
this.Cbox_P2Recoil.TabIndex = 16;
//
// label12
//
this.label12.AutoSize = true;
this.label12.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label12.Location = new System.Drawing.Point(19, 187);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(168, 16);
this.label12.TabIndex = 12;
this.label12.Text = "PLAYER2 GUN REACTION";
//
// label13
//
this.label13.AutoSize = true;
this.label13.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label13.Location = new System.Drawing.Point(19, 157);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(168, 16);
this.label13.TabIndex = 11;
this.label13.Text = "PLAYER1 GUN REACTION";
//
// Cbox_P1Recoil
//
this.Cbox_P1Recoil.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_P1Recoil.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_P1Recoil.FormattingEnabled = true;
this.Cbox_P1Recoil.Items.AddRange(new object[] {
"OFF",
"ON"});
this.Cbox_P1Recoil.Location = new System.Drawing.Point(214, 154);
this.Cbox_P1Recoil.Name = "Cbox_P1Recoil";
this.Cbox_P1Recoil.Size = new System.Drawing.Size(60, 24);
this.Cbox_P1Recoil.TabIndex = 15;
//
// label14
//
this.label14.AutoSize = true;
this.label14.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label14.Location = new System.Drawing.Point(19, 127);
this.label14.Name = "label14";
this.label14.Size = new System.Drawing.Size(64, 16);
this.label14.TabIndex = 10;
this.label14.Text = "REVIVAL";
//
// Cbox_Advertise
//
this.Cbox_Advertise.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_Advertise.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_Advertise.FormattingEnabled = true;
this.Cbox_Advertise.Items.AddRange(new object[] {
"NORMAL",
"3/4",
"1/2",
"1/4",
"OFF"});
this.Cbox_Advertise.Location = new System.Drawing.Point(153, 94);
this.Cbox_Advertise.Name = "Cbox_Advertise";
this.Cbox_Advertise.Size = new System.Drawing.Size(121, 24);
this.Cbox_Advertise.TabIndex = 5;
//
// label8
//
this.label8.AutoSize = true;
this.label8.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label8.Location = new System.Drawing.Point(19, 97);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(128, 16);
this.label8.TabIndex = 4;
this.label8.Text = "ADVERTISE SOUND";
//
// Cbox_Difficulty
//
this.Cbox_Difficulty.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_Difficulty.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_Difficulty.FormattingEnabled = true;
this.Cbox_Difficulty.Items.AddRange(new object[] {
"VERY EASY",
"EASY",
"NORMAL",
"HARD",
"VERY HARD"});
this.Cbox_Difficulty.Location = new System.Drawing.Point(153, 62);
this.Cbox_Difficulty.Name = "Cbox_Difficulty";
this.Cbox_Difficulty.Size = new System.Drawing.Size(121, 24);
this.Cbox_Difficulty.TabIndex = 3;
//
// label9
//
this.label9.AutoSize = true;
this.label9.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label9.Location = new System.Drawing.Point(19, 65);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(128, 16);
this.label9.TabIndex = 2;
this.label9.Text = "GAME DIFFICULTY";
//
// Cbox_Revival
//
this.Cbox_Revival.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_Revival.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_Revival.FormattingEnabled = true;
this.Cbox_Revival.Items.AddRange(new object[] {
"OFF",
"ON"});
this.Cbox_Revival.Location = new System.Drawing.Point(214, 124);
this.Cbox_Revival.Name = "Cbox_Revival";
this.Cbox_Revival.Size = new System.Drawing.Size(60, 24);
this.Cbox_Revival.TabIndex = 9;
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.Transparent;
this.panel1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("panel1.BackgroundImage")));
this.panel1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.panel1.Location = new System.Drawing.Point(12, 24);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(329, 89);
this.panel1.TabIndex = 27;
//
// Btn_Close
//
this.Btn_Close.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.Btn_Close.Location = new System.Drawing.Point(482, 428);
this.Btn_Close.Name = "Btn_Close";
this.Btn_Close.Size = new System.Drawing.Size(113, 36);
this.Btn_Close.TabIndex = 26;
this.Btn_Close.Text = "Close";
this.Btn_Close.UseVisualStyleBackColor = true;
this.Btn_Close.Click += new System.EventHandler(this.Btn_Close_Click);
//
// Btn_Save
//
this.Btn_Save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.Btn_Save.Location = new System.Drawing.Point(344, 428);
this.Btn_Save.Name = "Btn_Save";
this.Btn_Save.Size = new System.Drawing.Size(113, 36);
this.Btn_Save.TabIndex = 25;
this.Btn_Save.Text = "Save";
this.Btn_Save.UseVisualStyleBackColor = true;
this.Btn_Save.Click += new System.EventHandler(this.Btn_Save_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.label24);
this.groupBox1.Controls.Add(this.Cbox_EntryType);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.Cbox_FreePlay);
this.groupBox1.Location = new System.Drawing.Point(12, 393);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(260, 97);
this.groupBox1.TabIndex = 2;
this.groupBox1.TabStop = false;
//
// label24
//
this.label24.AutoSize = true;
this.label24.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label24.Location = new System.Drawing.Point(74, -1);
this.label24.Name = "label24";
this.label24.Size = new System.Drawing.Size(136, 16);
this.label24.TabIndex = 22;
this.label24.Text = "COIN ASSIGNMENTS";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.panel2);
this.groupBox2.Controls.Add(this.Cbox_EnglishSubtitles);
this.groupBox2.Controls.Add(this.label15);
this.groupBox2.Controls.Add(this.label21);
this.groupBox2.Controls.Add(this.Cbox_FirstMn);
this.groupBox2.Controls.Add(this.label20);
this.groupBox2.Controls.Add(this.Cbox_EnnemyBoost);
this.groupBox2.Controls.Add(this.Cbox_Language);
this.groupBox2.Controls.Add(this.label19);
this.groupBox2.Controls.Add(this.label16);
this.groupBox2.Controls.Add(this.Cbox_Swipe);
this.groupBox2.Controls.Add(this.label10);
this.groupBox2.Controls.Add(this.label5);
this.groupBox2.Controls.Add(this.Cbox_StageSelect);
this.groupBox2.Controls.Add(this.label6);
this.groupBox2.Controls.Add(this.Cbox_KidsMode);
this.groupBox2.Controls.Add(this.Cbox_ContinueCountdown);
this.groupBox2.Controls.Add(this.label7);
this.groupBox2.Controls.Add(this.Cbox_P2Recoil);
this.groupBox2.Controls.Add(this.label12);
this.groupBox2.Controls.Add(this.label13);
this.groupBox2.Controls.Add(this.Cbox_P1Recoil);
this.groupBox2.Controls.Add(this.label14);
this.groupBox2.Controls.Add(this.Cbox_Advertise);
this.groupBox2.Controls.Add(this.label8);
this.groupBox2.Controls.Add(this.Cbox_Difficulty);
this.groupBox2.Controls.Add(this.label9);
this.groupBox2.Controls.Add(this.Cbox_Revival);
this.groupBox2.Location = new System.Drawing.Point(12, 133);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(595, 252);
this.groupBox2.TabIndex = 11;
this.groupBox2.TabStop = false;
//
// label16
//
this.label16.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.label16.AutoSize = true;
this.label16.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label16.Location = new System.Drawing.Point(226, 0);
this.label16.Name = "label16";
this.label16.Size = new System.Drawing.Size(136, 16);
this.label16.TabIndex = 21;
this.label16.Text = "GAME ASSIGNMENTS";
//
// groupBox3
//
this.groupBox3.Controls.Add(this.label3);
this.groupBox3.Controls.Add(this.Cbox_ScreenMode);
this.groupBox3.Controls.Add(this.label4);
this.groupBox3.Controls.Add(this.label11);
this.groupBox3.Controls.Add(this.Cbox_Resolution);
this.groupBox3.Location = new System.Drawing.Point(347, 17);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(260, 97);
this.groupBox3.TabIndex = 23;
this.groupBox3.TabStop = false;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(74, -1);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(112, 16);
this.label3.TabIndex = 22;
this.label3.Text = "VIDEO OPTIONS";
//
// Cbox_ScreenMode
//
this.Cbox_ScreenMode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.Cbox_ScreenMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_ScreenMode.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_ScreenMode.FormattingEnabled = true;
this.Cbox_ScreenMode.Items.AddRange(new object[] {
"WINDOWED",
"FULLSCREEN"});
this.Cbox_ScreenMode.Location = new System.Drawing.Point(135, 62);
this.Cbox_ScreenMode.Name = "Cbox_ScreenMode";
this.Cbox_ScreenMode.Size = new System.Drawing.Size(113, 24);
this.Cbox_ScreenMode.TabIndex = 3;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label4.Location = new System.Drawing.Point(6, 65);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(96, 16);
this.label4.TabIndex = 2;
this.label4.Text = "SCREEN MODE";
//
// label11
//
this.label11.AutoSize = true;
this.label11.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label11.Location = new System.Drawing.Point(6, 35);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(88, 16);
this.label11.TabIndex = 1;
this.label11.Text = "RESOLUTION";
//
// Cbox_Resolution
//
this.Cbox_Resolution.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.Cbox_Resolution.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.Cbox_Resolution.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Cbox_Resolution.FormattingEnabled = true;
this.Cbox_Resolution.Location = new System.Drawing.Point(135, 32);
this.Cbox_Resolution.Name = "Cbox_Resolution";
this.Cbox_Resolution.Size = new System.Drawing.Size(113, 24);
this.Cbox_Resolution.TabIndex = 0;
//
// WndMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(615, 497);
this.Controls.Add(this.groupBox3);
this.Controls.Add(this.panel1);
this.Controls.Add(this.Btn_Close);
this.Controls.Add(this.Btn_Save);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "WndMain";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Transformers SHadow Rising - Configurator";
this.Load += new System.EventHandler(this.WndMain_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox Cbox_EntryType;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox Cbox_FreePlay;
private System.Windows.Forms.ComboBox Cbox_Swipe;
private System.Windows.Forms.Label label10;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.ComboBox Cbox_StageSelect;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.ComboBox Cbox_KidsMode;
private System.Windows.Forms.ComboBox Cbox_ContinueCountdown;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.ComboBox Cbox_P2Recoil;
private System.Windows.Forms.Label label12;
private System.Windows.Forms.Label label13;
private System.Windows.Forms.ComboBox Cbox_P1Recoil;
private System.Windows.Forms.Label label14;
private System.Windows.Forms.ComboBox Cbox_Advertise;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.ComboBox Cbox_Difficulty;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.ComboBox Cbox_Revival;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button Btn_Close;
private System.Windows.Forms.Button Btn_Save;
private System.Windows.Forms.ComboBox Cbox_Language;
private System.Windows.Forms.Label label19;
private System.Windows.Forms.Label label20;
private System.Windows.Forms.ComboBox Cbox_EnnemyBoost;
private System.Windows.Forms.Label label21;
private System.Windows.Forms.ComboBox Cbox_FirstMn;
private System.Windows.Forms.ComboBox Cbox_EnglishSubtitles;
private System.Windows.Forms.Label label15;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Label label24;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Label label16;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox Cbox_ScreenMode;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.ComboBox Cbox_Resolution;
}
}

View File

@ -0,0 +1,374 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace Transformers2_Configurator
{
public partial class WndMain : Form
{
#region WIN32
[DllImport("user32.dll")]
public static extern bool EnumDisplaySettings(
string deviceName, int modeNum, ref DEVMODE devMode);
const int ENUM_CURRENT_SETTINGS = -1;
const int ENUM_REGISTRY_SETTINGS = -2;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public ScreenOrientation dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
#endregion
private const string GAMESETTINGS_INI_PATH = @"..\ShellData\GameSettings.ini";
private const string SHELLDATA_INI_PATH =@"..\ShellData\ShellData.ini";
private const string LAUNCHER_INI_PATH = @".\Transformers2_Launcher.ini";
private INIFile _GameSettings_IniFile;
private INIFile _ShellData_IniFile;
private INIFile _Launcher_IniFile;
public WndMain()
{
InitializeComponent();
this.Text = "Transformers Shadow Rising - System Menu v" + System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
_GameSettings_IniFile = new INIFile(GAMESETTINGS_INI_PATH);
_ShellData_IniFile = new INIFile(SHELLDATA_INI_PATH);
_Launcher_IniFile = new INIFile(LAUNCHER_INI_PATH);
ListAvailableScreenResolutions();
}
#region Resolution Listing
private void ListAvailableScreenResolutions()
{
DEVMODE vDevMode = new DEVMODE();
int i = 0;
while (EnumDisplaySettings(null, i, ref vDevMode))
{
string res = vDevMode.dmPelsWidth + "x" + vDevMode.dmPelsHeight;
if (!CheckIfResolutionAlreadyExists(res))
Cbox_Resolution.Items.Add(res);
i++;
}
}
private bool CheckIfResolutionAlreadyExists(string Resolution)
{
for (int i = 0; i < Cbox_Resolution.Items.Count; i++)
{
if (Cbox_Resolution.Items[i].ToString().Equals(Resolution))
return true;
}
return false;
}
#endregion
private void WndMain_Load(object sender, EventArgs e)
{
DisplayDefaultValues();
if (File.Exists(_GameSettings_IniFile.FInfo.FullName))
{
DisplayGameSettings();
}
else
{
MessageBox.Show("TEST MENU config file not found :\n\n" + _GameSettings_IniFile.FInfo.FullName, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
if (File.Exists(_ShellData_IniFile.FInfo.FullName))
{
DisplayShellSettings();
}
else
{
MessageBox.Show("SHELL config file not found :\n\n" + _ShellData_IniFile.FInfo.FullName, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
if (File.Exists(_Launcher_IniFile.FInfo.FullName))
{
DisplayLauncherSettings();
}
else
{
MessageBox.Show("LAUNCHER config file not found :\n\n" + _Launcher_IniFile.FInfo.FullName, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void DisplayDefaultValues()
{
DisplayComboBoxValue(Cbox_Language, Cbox_Language.Items[0].ToString());
DisplayComboBoxValue(Cbox_Difficulty, Cbox_Difficulty.Items[2].ToString());
DisplayComboBoxValue(Cbox_Advertise, Cbox_Advertise.Items[0].ToString());
DisplayComboBoxValue(Cbox_Revival, Cbox_Revival.Items[0].ToString());
DisplayComboBoxValue(Cbox_P1Recoil, Cbox_P1Recoil.Items[1].ToString());
DisplayComboBoxValue(Cbox_P2Recoil, Cbox_P2Recoil.Items[1].ToString());
DisplayComboBoxValue(Cbox_ContinueCountdown, Cbox_ContinueCountdown.Items[1].ToString());
DisplayComboBoxValue(Cbox_EnnemyBoost, Cbox_EnnemyBoost.Items[0].ToString());
DisplayComboBoxValue(Cbox_FirstMn, Cbox_FirstMn.Items[0].ToString());
DisplayComboBoxValue(Cbox_KidsMode, Cbox_KidsMode.Items[0].ToString());
DisplayComboBoxValue(Cbox_StageSelect, Cbox_StageSelect.Items[1].ToString());
DisplayComboBoxValue(Cbox_EnglishSubtitles, Cbox_EnglishSubtitles.Items[1].ToString());
DisplayComboBoxValue(Cbox_Swipe, Cbox_Swipe.Items[0].ToString());
Cbox_FreePlay.Text = Cbox_FreePlay.Items[1].ToString();
Cbox_EntryType.Text = Cbox_EntryType.Items[0].ToString();
Cbox_Resolution.Text = Cbox_Resolution.Items[Cbox_Resolution.Items.Count - 1].ToString();
Cbox_ScreenMode.Text = Cbox_ScreenMode.Items[1].ToString();
}
private void DisplayGameSettings()
{
try
{
DisplayComboBoxValue(Cbox_Language, _GameSettings_IniFile.IniReadValue("GameSettings", "LANGUAGE"));
DisplayComboBoxValue(Cbox_Difficulty, _GameSettings_IniFile.IniReadValue("GameSettings", "GAME DIFFICULTY"));
DisplayComboBoxValue(Cbox_Advertise, _GameSettings_IniFile.IniReadValue("GameSettings", "ADVERTISE SOUND"));
DisplayComboBoxValue(Cbox_Revival, _GameSettings_IniFile.IniReadValue("GameSettings", "REVIVAL"));
DisplayComboBoxValue(Cbox_P1Recoil, _GameSettings_IniFile.IniReadValue("GameSettings", "PLAYER1 CONTROLLER REACTION"));
DisplayComboBoxValue(Cbox_P2Recoil, _GameSettings_IniFile.IniReadValue("GameSettings", "PLAYER2 CONTROLLER REACTION"));
DisplayComboBoxValue(Cbox_ContinueCountdown, _GameSettings_IniFile.IniReadValue("GameSettings", "CONTINUE COUNTDOWN"));
DisplayComboBoxValue(Cbox_EnnemyBoost, _GameSettings_IniFile.IniReadValue("GameSettings", "ENEMY BOOST"));
DisplayComboBoxValue(Cbox_FirstMn, _GameSettings_IniFile.IniReadValue("GameSettings", "1ST MIN GAME PLAY"));
DisplayComboBoxValue(Cbox_KidsMode, _GameSettings_IniFile.IniReadValue("GameSettings", "KIDS MODE"));
DisplayComboBoxValue(Cbox_StageSelect, _GameSettings_IniFile.IniReadValue("GameSettings", "SELECT STAGE"));
DisplayComboBoxValue(Cbox_EnglishSubtitles, _GameSettings_IniFile.IniReadValue("GameSettings", "ENGLISH SUBTITLES"));
DisplayComboBoxValue(Cbox_Swipe, _GameSettings_IniFile.IniReadValue("GameSettings", "SWIPE CARD TO PLAY"));
}
catch (Exception Ex)
{
MessageBox.Show("GameSettings : Invalid value found: \n\n" + Ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DisplayShellSettings()
{
try
{
int iIndex = int.Parse(_ShellData_IniFile.IniReadValue("Credit", "Freeplay"));
Cbox_FreePlay.Text = Cbox_FreePlay.Items[iIndex].ToString();
}
catch (Exception Ex)
{
MessageBox.Show(SHELLDATA_INI_PATH + "\n: Invalid value found for Freeplay : \n\n" + Ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
int iIndex = int.Parse(_ShellData_IniFile.IniReadValue("Credit", "EntryType"));
Cbox_EntryType.Text = Cbox_EntryType.Items[iIndex].ToString();
}
catch (Exception Ex)
{
MessageBox.Show(SHELLDATA_INI_PATH + "\n: Invalid value found for EntryType: \n\n" + Ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DisplayLauncherSettings()
{
try
{
//Resolution:
string res = _Launcher_IniFile.IniReadValue("Video", "WIDTH") + "x" + _Launcher_IniFile.IniReadValue("Video", "HEIGHT");
if (CheckIfResolutionAlreadyExists(res))
Cbox_Resolution.Text = res;
//Mode
int iIndex = int.Parse(_Launcher_IniFile.IniReadValue("Video", "FULLSCREEN"));
Cbox_ScreenMode.Text = Cbox_ScreenMode.Items[iIndex].ToString();
}
catch (Exception Ex)
{
MessageBox.Show("Launcher Settings : Invalid value found: \n\n" + Ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DisplayComboBoxValue(ComboBox Target, String sValue)
{
for (int i = 0; i < Target.Items.Count; i++)
{
if (Target.Items[i].ToString().Equals(sValue))
{
Target.Text = sValue;
return;
}
}
MessageBox.Show(GAMESETTINGS_INI_PATH + "\n: Invalid value found for " + Target.Name + " : \n\n" + sValue, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void DisplayTrackBarValue(TrackBar Target, String sValue)
{
int iValue = 0;
if (int.TryParse(sValue, out iValue))
{
if (iValue >= Target.Minimum && iValue <= Target.Maximum)
{
Target.Value = iValue;
}
else
{
MessageBox.Show(SHELLDATA_INI_PATH + " :\n" + sValue + " out of bound for " + Target.Name, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show(SHELLDATA_INI_PATH + " :\n" + sValue + " is not valid value for " + Target.Name, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SaveGameSettings()
{
if (!_GameSettings_IniFile.FInfo.Exists)
Directory.CreateDirectory(_GameSettings_IniFile.FInfo.Directory.FullName);
try
{
_GameSettings_IniFile.IniWriteValue("GameSettings", "LANGUAGE", Cbox_Language.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "GAME DIFFICULTY", Cbox_Difficulty.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "ADVERTISE SOUND", Cbox_Advertise.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "REVIVAL", Cbox_Revival.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "PLAYER1 CONTROLLER REACTION", Cbox_P1Recoil.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "PLAYER2 CONTROLLER REACTION", Cbox_P2Recoil.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "CONTINUE COUNTDOWN", Cbox_ContinueCountdown.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "ENEMY BOOST", Cbox_EnnemyBoost.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "1ST MIN GAME PLAY", Cbox_FirstMn.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "KIDS MODE", Cbox_KidsMode.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "SELECT STAGE", Cbox_StageSelect.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "ENGLISH SUBTITLES", Cbox_EnglishSubtitles.Text);
_GameSettings_IniFile.IniWriteValue("GameSettings", "SWIPE CARD TO PLAY", Cbox_Swipe.Text);
}
catch (Exception Ex)
{
MessageBox.Show("Error saving GameSettings to disk : " + _GameSettings_IniFile.FInfo.FullName + "\n\n" + Ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
MessageBox.Show("GameSettings successfully saved to : \n\n" + _GameSettings_IniFile.FInfo.FullName, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
private void SaveShellSettings()
{
if (!_ShellData_IniFile.FInfo.Exists)
Directory.CreateDirectory(_ShellData_IniFile.FInfo.Directory.FullName);
try
{
_ShellData_IniFile.IniWriteValue("Credit", "Freeplay", Cbox_FreePlay.SelectedIndex.ToString());
_ShellData_IniFile.IniWriteValue("Credit", "EntryType", Cbox_EntryType.SelectedIndex.ToString());
}
catch (Exception Ex)
{
MessageBox.Show("Error saving ShellSettings to disk : " + _ShellData_IniFile.FInfo.FullName + "\n\n" + Ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
MessageBox.Show("ShellData successfully saved to : \n\n" + _ShellData_IniFile.FInfo.FullName, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
private void SaveLauncherSettings()
{
if (!_Launcher_IniFile.FInfo.Exists)
Directory.CreateDirectory(_Launcher_IniFile.FInfo.Directory.FullName);
try
{
string[] sBuffer = Cbox_Resolution.Text.Split('x');
_Launcher_IniFile.IniWriteValue("Video", "WIDTH", sBuffer[0]);
_Launcher_IniFile.IniWriteValue("Video", "HEIGHT", sBuffer[1]);
_Launcher_IniFile.IniWriteValue("Video", "FULLSCREEN", Cbox_ScreenMode.SelectedIndex.ToString());
}
catch (Exception Ex)
{
MessageBox.Show("Error saving Launcher Settings to disk : " + _Launcher_IniFile.FInfo.FullName + "\n\n" + Ex.Message.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
MessageBox.Show("Launcher Settings successfully saved to : \n\n" + _Launcher_IniFile.FInfo.FullName, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
private void Btn_Save_Click(object sender, EventArgs e)
{
SaveGameSettings();
SaveShellSettings();
SaveLauncherSettings();
}
private void Btn_Close_Click(object sender, EventArgs e)
{
Application.Exit();
}
#region INI class
public class INIFile
{
private string _RelativePath = string.Empty;
public FileInfo FInfo { get; private set; }
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
public INIFile(string INIPath)
{
_RelativePath = INIPath;
FInfo = new FileInfo(_RelativePath);
}
public long IniWriteValue(string Section, string Key, string Value)
{
return WritePrivateProfileString(Section, Key, Value, this._RelativePath);
}
public string IniReadValue(string Section, string Key)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, Key, "", temp, 255, this._RelativePath);
return temp.ToString();
}
}
#endregion
}
}

View File

@ -0,0 +1,894 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="panel1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAAAAAAAEAIADLLQAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAEAAAABAAgGAAAAXHKoZgAAAAFv
ck5UAc+id5oAAC2FSURBVHja7Z3pW1RXtv9J+r755cXt/gNyu+/txNznud2doWOSTtJJJ53ETiex80Tj
hBMzVUAN59QpZHJGRQVEHBBwRozzSJwnZFIREZmUQTSKitFEE3OfvLh51m+vXVVYYM0T55xa9TzfB0Q2
dWqfvT5n7b3XWjsiwoOXZm9cROL2uAjNDvaVSbsr4Wn29TmmSUxFTLVMvUz/y/QLE6C0exIg5Wst6I8m
g3BSD+JpA5iqjGCqlr3uM5Uy/QdTBIpe6n7Z7rP1npdax4DcxuUvTD8x3WSqYSpimsj0nKlKeNruM0RI
VQb/OyVpdxI3es1Oi+Gz759hX0cwlTJ1MP1sM3abNDvjIblCA4ZjKSBWGpRg7K60g+k3vFOrRLISlb7E
qn7D+Y31nitpjP7M1MFUwjSC6Rl7EJhqTb51itXgLV93xv2b1fD3MT0abPRcO+O44RtP6JTylPdE/8c0
ATtSJACoGACCzWAmWu+5UsfrI6Z9TB8x/coeBF692FOcK9ECgGeZCpkeODR8q6tvOJqiJsO3Vx5NA8LG
/c9XyZh9wLSU6VmvIaDZEc9lNf63meqcGT4qeb8GhFN6NRq+TStMtTgFIACEAQBWqmzs1jK95TEEEnda
jD9hRywa/7+Yrrky/pQDWsvCnnqNnwBAAFC6ephGSjVuIJCALv/OhIjE7f3Gf8ut8Vep3vgJAAQANegW
QsD2OcXBENDv0kRotsfZu/09Lt3+Ck04PPkJAAQAtXkCfDogMRnrjPbzfpvxxz/rbs6v3ZsAQqU+XIyf
AEAAUNuawLMDpgKa3ZZ9fu2u+H+zrvY7NX7c4zccTwkn4ycAEADUpqW2LUKxRojgEX5W13+Eq60+Pu//
Whtuxo/aINUanjLVEABUDYAq8Sn2dWMYjOcH1jgBixegeRzht8/l039XPA/nDUMAoNv079hZhjodWYvK
XlKdaHv64z2uC5MxvdcWMWj/9H/kbtU/DI0f9QPTB/1u4mmCgFpeQq1g7/5/aL3X4TCmH9m8AIz4e9oa
2+9y7s9DfD3442K1AYRq/QDhzxTeYRX9OQEUFaiOJ3+1wd74f2O9x7IZcyGwoxKp2vh0hDWrr9MVAJL2
Jrrd9rNd3Iy6TCioz4e1F9bA+sb1sKqhCBacnQfTaiQlgwCzsJYPhgAuopCUpwHJMpZ7utx6j2Vh+Kis
2gxYUp8Hay6s5nZU3LAKFp5dAGk15kDZESYQ/T7CmtL7s0v3/6DW7UWj4X/V9BWcu3IeLnd1QGd3N3R1
X4WO7i5o7myFY23HYWl9AUjVgpIhUGF1FX9tqhaeMlfqIlJJyhKbwpmqDU9Z7iF3gyvkZPyZtelQdrEM
zlw+C+1dV/rtCL+2drbBybZTsOL8cjDXiP6CALMIIyOs+fzgSpja6+qic87Oh6r2an6htou1F/6su7sH
Wrva4auLm7k3oPA1AVwsKrPmY5OUpzLrPfxRTi5/9pk5zMBPDjD6wUI7QjDsuLQD0mtS/YXAyghrMQ+f
Vv/xzeeemQ11l8/wC3N0wYNBcKW7EzZfLFeyJ0AiBdz4Z9ZNh9PtVR7ZUacVDggB9AT8eO+aCGslH+eR
f7sTnBb2SK0xwYGWAx5e9GMItDBXBuc3KlgcJJH8Fj4Md1/a7fSp7wwC6AmsOL/MHzu6EWEt4wWucv0d
LQDim+adWwxtzK33/KIfuzGHWg8zeploAJDC/umPi+SXOlu8BIDFjnBNABcGfXz/nyLsa/g53QGocgyA
7U3b2EX3eA0A/KBNnZf49IG8AFK4A6CscaPXxm8TetO4O+CjHf0S4W4B0BkA8Ol9vO24V+6/va50dUJh
fQHf36SBQApn99/bafRg4Rahr3bkMwDQ7bCs/A/NhZNIahAu4vnzIEXPYX3jutADILVGglNtlT5fOMYH
4H4mAYAU7h7A4dbDfnkAqy+Uhh4AqH3N+3y+cJy7YPwArQGQwn0NYJuPa2ko3AnIr88LPQDwDYsaVvJ9
fe/dlh6+54mBDDQISOENAD0PnbdF/Xnr/mPEIIYN+/og9RkAlrDFNL4O4K0XgO4/ui309CeRLOtpx9tO
+ORNl13c6Jcd+TUFwDfG+H6M9fd0GwN/D2MA0ujpTyL129Hic4vgYsclj+0IYXGi7STPHRgyANhUeqGE
QaDFJcFseQJIull10+npTyINEi6KX+xo8siOcAodiDiagAAAtYTNY061V/JMQPwA9sILRrrhYoc/8xUS
Se1afG4h3xbENYEuB3aEEYO7Lu2CmXVZAbGjgAEALya9dhoP7tl+aTscaT3CU4ArWip4PvO8M3MH1A0g
kUiO7QjXBHBhcGvTVr5FiHb0dcsBHjGIYcO4dRgoOwoYAOx3B/Di8CLN1WL/SicZPonk3e5Avx3ViP1G
H2g7CjgASCSSckQAIJEIAAQA2arGKl/bDVVbuncEAJJ/hm88YQRdhQC6rwUQTnpnWIYjAqTsF0B/kM0d
Kz1sy35HPG0E/SFLW/wbpirPr1c4ZeTXitdsPE73kABA8m0BiBld4mYRIrMlGJtu5po4XwLtdvflnwQG
jdgSE4yfydqmmWFcphmm5Ju4YbqEAPs/hMXUAhOMyzLztuNnSBCzymQxZjcASdopwKQc9p4ZluuNnCNB
QpnIgUL3lABA8kKJ5SKMmWaGL01MkkWj2fdoXEk7RKfGiMYWvcJkaTOobeRcCQyHnUCA/cxwVOCQwd/t
b2v9fupSk8WLcAKO5N0Ch8Zou/fEdmNSzZCwQaR7SgAgeSp82qKx2huwvSFPWiiBeMqJIe4R+JN7cDub
QcaWmpwCIH6d6PA9UQgjfMI7aovQmZJnGmj8du85YZbE4ULrAgQAkgfz6JR9ro14XJbjJ7mERrzBuRHj
zycvkhy75GzKgdOE0S7axq1x4HngOgUzbpxuuIIHeggEAAIAyQMA4FOcu/+SY+GcXn9AcGiMcWtdA2DS
AsmhK49QmLxYctk2ptjk8D0RRuOmuwCA2TJtkQgABACSWgFgdg6AVAJA2ADA/vcIGgQAAkAYAWBarQkW
XJoLhR15UHglD+Y3zYHUWqr7TwAgAKgeAOlnUqH46nLYercMtn9bzrW1rwxWdS+DtDNm6mgCAAFArQCQ
agRY1rGEG/22u5sGaPvdcljKvAHqaAIAAUClAMg8Ow023Vr7hPHbALCxdw33EKizCQB0j1UGAH6q6flM
+OrOBocAQG2+vR6m11MVIAIA3d8w9AA2QRnzADLIAyAAEADUuwawvLPA8RoA+9myjnyQqKMJAAQA9e4C
ZDAvoLRnRb/R22CAOwM0/ycAEADCIQ6gToKc5mzmDSzhyrmUzX9GnUwAIABQJCCJAED3l3IBSAQAEgGA
RAAgEQBIBAASAYBEACCpZRHQdnoJQcN7icxIkna7BsBYBMBB4QmDkrwAwBNxGVYAuKoIFMsA4Og9sXKw
KwB8aTaDxkUdQ5JKAJBaK0L2xVmwpH0x0yKY2ziTH2lEneyB4fN0agMsa0qGospkGJ8mOTQmNNApMyTY
dVEDp76Jh5PXH6vyRjzk79Y5NeJRohmMBQIc7U4Y0A51vCcBzCuM/Hectc3ZqoNTNwa2w2vY15II0bOd
lxMby2C24JAO5tTr+eek+61CAGDKb1F3IU8BtgUCbenbCCu6CigWwAPjX3BeB1XMuG4/jIL26zEQP1d0
aFBoiEKuANf7ouC7H6fCfTt9/9MUOHo2AcamOjbEL1jbgs0pcO+Hge1Q+LdW7Ujmv+OsrFdFVSJ/j8Ht
bt6LgmlLHcMDP0P0TBNc7IqFK/diYENrEnso0D1XHQCwAAhm/jnKByi4vJg62oXx5zDjb+mL4QaFxnn3
4VQoYsY4yjSwzDZ+j4a4+ZAW7rHf/faHgcKf9dyJhvRlxicMGY1z6nQT1FyK5+8zuC3+7Fx7HMTOMj1h
yPi3TPlG6OyNdvq+O09oOHgGQ2uUFTp3Hlje4/aDKNh6RUOh4WoCAIYBl/W6SAe+uRrSqSiI40IqzO2v
uxk3wCjRoK7ejob8TTqITJf6QTA5S4JVO5PhBnviOjJEW9uGK7GQVmjkBjnKapAJzKPYezqRw8VRO5sO
1iaCdr7Yb7xjGXDMS4xwtjXO6Xuieu9Hwdq9SRwyeK34vhPYNCZnvW4AOBBwN76PgmUXk/nhJzQGwiYd
OJ3SgQdJYAaw6lIy3Hno2JBvfRcFVU3xsPmwFrYc0cIZZoT4JHVliPaewOEzCbDpgBZ2n9RA89VYl23s
27Zei4E9lRooY20RCN23oj16z74HFi9i61Et91IqG+P59GBwW4QdTndSaSqgBgAYIfNcGmy6tc4pANA7
QC+BOvvJvjt4NcGhS95vLI8GyhMjthmkfTt3Bhyotp5cL3oB3fejYe45WhRUTTrwyq6lTtOBMTEIf4c6
e6BwMax2kPsfLup9EAX5jSncC6KxoIJFQPQC1lwveiIdePW1lfT0d7ZtygBwtjc8AYCLgUsvEgBUFQeA
C32LWxfw7UDU4pb5VBGYAEAACKtIQLuFPlr0IwAQACgXgEQAIAAQAEgEAAIAAYBEACAAEABIBAACgFrT
gW0Kh0XAGt81rdYI9bfi4PtHU54IoFG77jAIFDalWAKBfO1DMl55AQBTf2dfmA65rTlMC2BWw3T1BgCx
AYh59ZgLr/uaqcJ7GVi7fY2J0NgRy+P3w0UXmM5djoN5J/SQ7EO/YX/rDwkgnLCDMBny0AIAU34x4m/L
nY08AQhPBML8ADwURFVHhLPBZjxuhIQykRfQGD9DgrEZZhib7psmZUowJSs8NT5D8rnfsCpSZLYEMUUm
0O2nKNMhB0DB5VynuQD57YtUY/wpewWYuEDqr5LjtAqOFxptCk/522+2/kcYYCUkR6XOSCFJB07l5/85
qgeAP9twc7XyIwKxVt9ugT/xA2H0pADKZCk7ht4AQYDSgYNi/DjXj5xLxi9nYbEUnJrRmkCIAZB1Lg3K
XaQD48nBSk8Iii0xkfErwBOYMEvisCYIhHAKYK4RYFX3MqfpwJgqrNjdAFz0OybwgUUAUIbICwgxAHAv
F138dd8UW3YArOnA+P3ab1ZxD0HRc/9drst0k+QjXFycutQEJgowCn0cALr5uOJf0rOCK79tIV8gVHLn
YN37xM0iGZeCpgGTcqSwXwy0RVim1Rp43UlXCngoMLr7agkAQgCgS0nGpRwATJwngXAqfMvMZdQZYHVL
Ehy/Fg8Nt2Oh6Y5rUS4AAYAAoKIS82d646Dv4ZNnPzgS1nskABAACAAqMP559Tpotp4v4U1iFgGAAEAA
UEFmKR7V5ktmKQGAAEAAUPLTv8oIuRdS+IEr934YYgDYTgVWSzowAYAAoIQV/82XtT4Zf0ABgCv/GBa8
sHkeUzbMYN8rfTeAAEAAUIIHsL8r0efCMgEBAKb8Lr2Sx+P+7XMAMEsQjw0nAAySOfWxwtVYg/H5wxEA
TF93DzEAMADIWS5AblsOAWBAtJoEI5OS4B9To+CDyEj4YMIEB4qEDyMnwoeTJjFNho/UpsmTYQT7/J8m
JMIoo0AAUDIA0s+k8hOAnaUDr79RCml1ZgIA0+c6Hbw3Zgy8MWIEvPbBB/Da3/8+QMPx64cf8v9/4+OP
4S8q15uffALvjhoFn8QnMOOVCABKA4Da04EDCYDPk1Pg7ZEjLcaOxu9Ar3/0kcU4/vnP8BGC4NNP4ePo
aAKAEgGQdS4dym+7TgfOVGg6cKAAMEoQ4d0vRrk0fv7kDzfjt9Nbn30Gn2m0/q0LEABCPwXAYqDFV5c7
TQfGcwLluBsgWrdQXElkAIjfKPq92PXP2Dh4nRm4U+PHpz9z+8PV+G2ewPtjx/I1En8AEMkAYDzJ7p8n
95cAEJh0YNzy23Cz9HEqsFXrb5Qw9z9DVh0tVluO5l5wXgdrW5Jgy2UNbLviWNs7NTB/t97vWgA4sIe7
evozvfGPf4Q3ANALYFOkz3V6v9KBExeJUN6idXpPtzJtatdC4cUUyKwzKB4CstgFQGHeP24F4jHhqKWX
c/mx4XLrrOx6PRy9lgDXvouGu6wD7rnQ9z9NgZ0nNH4VsRwtmuCdzz936/7/JYzdf5twUdCfacAo0Qzm
AiPcvBdlSXZxcl9x4N96EAUX78RCaXMSfyAQAAIUCmyuFbnk2FGLGh4nTHgSOfXdo6mww08A4Pz/r//6
FwHAEzEAfJqY6B8AlhjhxreehcXiOEAQoGegVAjIDgBy7aSsMwY4fyvWq466TwBQNQC+tXoEvQwCJc3J
PKqOAKBCAOCCT1mblrv83nQOAUD9ALB5Alg8A4tpEADkAACbO1blv5DqZva3am9azuG7pzQPgBmFYqUQ
AOCYuP0wCpY0poBwOjDjrr8uYQ0BwDtVWQ7hiF5pgil5/msyU1S+CbLX6WHv6US4fjfKYwgMKQDYv4e/
/z688vZfmd5WnIa/9573cQ1DMQVgY+HGvSioqE4EoViAyblSQMYdKnqFCZJ2CUGdWqgLAKyj4jeI/Py3
QB9FhYMDD4+Yv1YPV29HewSBoQIAxgT88eVX4PnfPwfP/e4/FSm89j+89JIlulGmAMAxgA+E3DIdjE3F
HRtLLEEgx93YNOvRZVUEAI/O3sPDNoNZgx9vyrp9SbL2AP7051cVa/gD9NvfcZB5vL4xBADYfFgb9BRl
hAB6AsGYDqgKAKE4gQcHiZArwLU+917AUAAAv39h2DB1AIBp2HPP888oRwBgvMC0QiNvF+zzCnBKSx6A
G0UVmgJzcqy7aLFsETpuxMgPAMwAcN6vZNf/ianAf/0eXn3vPc8WBUMIALz3OBXU5QgwKgRjbkp+cA4s
UZUHELdGDIkHkFpghG88GCRD4QHgnPmFF15QDQBeeH4Y+4wfytID6L0fBVkrDEH3AHBMxxSbaArgDgC6
rwUYPz145/ChIeNC4LajWlkvAr742muqAcCfXh0u60jAvZUaGJdqDp7nyf7uuEwzpOyjNQCPpN0qwvgZ
VggEYBX2S7tdgIkZEhTtSOZzv3syXgTExKAXh7/G1wLQhVai8MmPxv+GN1mOQ7ANeOu7KFizNwkmZ0oD
xksgxh03fvZAw+PlaBvQC+kPCpCwQYSYVSaIKfJP0UyJxSKs2pMM1U3xcPt7hcQBWBcEX/3be0x/U5je
89ztl0EcwJ0HU6G2OQ5mbdFDVJH/Y46Ljd349SLoDwgUCORTJGCAhB0086weOu9H8+QexYUCh0sU4BBG
AtruNZbXFgI8/igSUAax0giAjm+jfRoUlAug/lwAW1JQebu2/2RdygUgABAACAAEAAIAAYAAQAAYmg8Y
wDWAjnvRXmUCEgDCEACBXgMgAPiRw3/SCMajAhgCoIyTBmi8Hgt3H06ldGBaBHS4E4BjY11jEuiPBGbM
4djFMUwA8MHw49eJvLwzxgMEQhNmSpCcI8KS8hS42BWrnG3Av38Af37nXaZ3FKZ3eRHUvygkHbilJwYK
t6RA3HwTjJsRuHEXmS3x6FbhRPA8AlUBQKw0QtQyU38EVSCF8d5fsAGiXyR4DIEhCwQaMYJnBGIizfP/
+V/wnMKE14zX/sdXXvGu3PkQZAO2MuM35Rv52BhtCvy4Q00tMAXNG1BVKLB2mwhjUoMbl403On+TDvoe
yjgdePhw1YQC//HPf5a1B7Bie3LwcwHMZks0IIUCuxamTAY7GxA9gRQ2Hei+Jc904Nd5OrB6koGG8WQg
+aUD24qBiHlCSNKBMdOVPAB36cDLQpMOrJ0nQufNaEoHDlU68N/kmQ7ccyeaTwlDkQ48dQmlA7udAiRs
FIPrilmnADNXGXgSiBynAOQBhG4KgDkAWCLuixCkA2NZMJoCuAGA8ZgAE+dLltpsQaoFMDlLguP1CR51
2JCtAbxKawChSgeuuhgPUTNMQZsG4NiJnCuB4TClA3tcE2ByronXUcPFk0AIawCMT5O4u4fVX+8+lPc2
IO0ChDYO4PDZBF4mDsdIoMYcCsfw5EUSpOwXaBvQGwiIp4y8gIJ2u+i/tokg7DLCwfOJ0NUbrahAIGyj
zDiAdxQTB2BbD+i+HQ2FJ1IgcZsYmHHHhGOYH1VeQ4FAPoFACoDw78w6p4eu+9FedxJFAoZPOjCvEHxZ
y4+ElwI49igSkJKBKBeAkoEIAAQAAgABgABAACAAEAAIAKFfA+hU6hoAASCkawACrQHIYBeg0gi6CgGS
djLt8E/aHSKIe4xw+EKCx2cC0iJg+KUDY1Tg8lMpoGHjxd8xx8XGrm6/wHe0aBfAC+PHKqp4igoeEIqJ
QYFSZLrE93oP1sk/DkD5VYH/ppiqwKhj9Qkg5RthPBsjXwZwzOEYxtOG8WFGcQCeRgIukIKWD4ADZMp0
CU42xMs6ElA95wK8KutzAXAM1FyKh5iZQYwEZH8X6wIYjlAkoPtcgLLQ5ALMLtbLNhdAfScDvSpbAGAu
QM660OQCYJEbAoC7bMDlIcwG7JVpOjCeDTiMzgZUXTZgAWUDUj0AOh1YXvUA+qL4uhDVA5BLRaCtoakI
lFemg74H8lwDeI2nAw9TTzrwc8/LNh34LtPyrSmhqQhUTlMA9x/mlBGmFganJuBoa03AlBwBLnTIuyYg
ZgKqAgC//R388eVXPI9xGIKagM1XY7gXEMyagLirRTUBPfQCsIIqVlLFlVM8KnxcADSBSTtfhFz25PfU
+IcSAJhCi4YzTMFTAZzG/OGll/mahtyrAl/qjuUVo2OyTQEZbygcu1gHILbUBMbjVBXY+/LgDAS4dYKF
FPhXH6Vn7dNPGKDhWizcfaCgcwHYv3E94JW3/8r0tuI0nM3731BQOjDGhqy9kAQ6P8eb/Zjl5cApEpBO
BgrLSEBfogHpZCACACUDUS4AJQMRAAgABAACAAGAAEAAIACEHwBqAitbSbDvHhEACADO7/XmKwFeAwjB
WoAqAaA/JPC8gNgSE8QU+y9NqQir9ydDXUscj/9WyuGgjw1DYVIQAPD3MCjsbFsczNmmh+jiwIw5HLt4
zoX+oEAA8EZYxXf8LCmgwUCjrZqUKUHJrmS4ed/DbLEhBgDuoQ9//+98O1Bp8mr/fwgBgElh6/cn8SzR
gAcCsWvCU4I1W0QCgKe1ALDDvjQFLyZ7rNkM249r5H06MPv+pdffgP9+4b95QI0S9QK79hdfe52nNss5
HXhfVSKMm2YOXg4K+7vjssxBOxtAVQDACMAvg50MxAZJ6lLPBslQAQCNnx+y8dvfKT4cGOsayBUAt5gn
OH2lIfi5AGz84LSAAOAuHbgwNOnAidkidNyIkW06MD751WD8PB142DDL55NhOjCWiNMtDE06MOYDUDqw
Gw8AKRkKDwCTP671UTpwOKcDo27ci4JpzBsMRTpw9ApKB3YLgOQ9Aq+jFkwI4M1YszdJtrsAPB34eZWl
A+MxYTLNBtx0UAujg+z+j0kz8yKhNAVwJ+Yixa8X+aGKtpX7QK3I2iifvVrvUTGQIVsD+Pif/FBNVUwB
2GfAjEA5pwOjJ7hog44vDvNTqQO88zRmmhniVosgnqZdAI8hkLRL4C7T5MWBkgQZJQbYfVLjkes/5OnA
H30Ef3jxJe4+K9n1/58/vej5/H8I04G/Yb+/85QGNMtFmMTGSqDGHZa4wxLhwTJ+dUcC4oc7HRgJTOVt
Wt5JSkkHxu0zLK/98ptvwst/edPyVQmyXuur777r3RbgEEYC4ri41BcLmXWGgI25fqOnSEB5xEvPOKOH
xtuxXnXUkEcCKjkVWCHpwPh7tx9EwZqWJD5OlDi2CQAedlTehRRovxtj8QQoFyDscwFwHNx+OBV2dyaC
uUa545oA4EVn5ZzXwalv4uHG91H9g8CZvv9pCuwkACgLAAVGuHkvyuV9RTjcYYbf0hcD61uTILVG2WOa
AOBlh+ENz2XewKZ2LaO/BvawJ4Aj7WUdu2iPzq9tSQJA6ACAoNYsEmF7G7unXYlO7+u2KxooupTMp4Wi
CsYzAcCXjqsy8txvVxIZKOI3+nda0WjRBO98/jkBwAO9yQDwmUbrMwAQ1JHzJDCetBiG2/urkgcaASBI
kgJ0XNn7Y8fCcFcAYPJ6xVyFenvkSPhcp/cr6GYiA4BwKnzGKAFA7gBgT7NPYuPgdfaUdwWA1705RFON
Yh4QgnK0SSIAEADU5QHgOsC7X4xyOw14I4ynAW999pl/7j8BgAAgVwCgPk9O4S6uKwjwIhrhBgH2ed/8
9FP4ODo6IHH3BAACgCwBwCGg08F7Y8bAG8zd50aPMLCTbZ0A/597AyoXLvq9O2oUfBKfwIxXIgAQANQN
AMtWlQQjk5LgH1Oj4IPISPhgwgQHYj+PnAgfTprENBk+UpsmT4YR7PPjlt8ooxDQzDsCAAFA1gCwLQxa
5rqpwa1EI2f194GZAEAACDMAkIKWex92AKgywv4uAgABgBSWAMCAps2XtV6fg0AAIAAQAFTiAWBYO+a2
3CMAEAAIAOEFAJM1t+XE9XifpgEEAAIAAUAFC4Hz6nXQ3BfjNQQCBgCx2sAMRoD0M2Yu/B5/RgAgEQBC
l+p+pjcO+h66TnPvT4v+MYAAmH1hOqy6ugw29q6BjTdXQ1F3IcxqyCIAkAgAIYRARp0BVrckwfFr8dBw
Oxaa7riW3wDAp/ycxplQfmsdbP+2HLbf3cRUzr/fdGstB4NSPQEEQGI5AUBJAJiUI4FYGZ4AsN8ZwK9p
tQZIdyO/AZBaa4LV14q4wW9jxm8v/FlJzwow14rK7Ew8q2CXwEs7k4HJX1gQZOrS4JzAo1b5BQB8sk+v
z4DNt9c/Yfw2oWeQeS5NmV4AA4DxmAATZklBP7GIFBjhlM1UQ4YdMgDMOJ8JX93Z4BQACIfp9emKXhDE
s94JAPJ3/xHUhiMCASBUAODzjDozrL9Ryuf9jqYA674phml1knI7iQ0mHFSRc8kLkLPGpNLTf0gAgFrU
Mh+29pUNgAB+v6VvI+Q0Zyu/o3AtYLcA42cQBOT45P/SbIaYIlPYL/4NGQDMNQIsbl3AtwARBFuYcCsQ
wYDxAKroLAaBlL0CTFwgPR54psAsXIWjAmL4TOMyzRC3ViTjH0oA2JRxNhXmXJjBlX4mVX0dhouCJ4yQ
sEnk5w2iRzA2w8xPNPZFkzIlmJIVnhqfIfncb2j0kdkSf+rr9gtkyHIBgCU5waD+0GEGAnzi4NqA7mum
Cu9lYO32NSZCY0csNFwJH11gOnc5Duad0EOyD/2G/a0/JIBwIjRn7xEAwjgXwKNDTH3UtFoj1N+Kg+8f
TeFHkIWT7vwwFQqbUix1+X3tQxp/BAClZ3Cd7Y3zuZCDkoWHcS69mNIfsUYiABAACAAkAgABgABAUiQA
eDpwtcCDfmyBP0pPByYAEAAIAB4CYOb5TFjRtZRHBa6/UQIrOgtgRn0GdTIBgACgZgDgU352w3Qo611j
TQcu708HxmCgmeezyBNwGDxlhLqb4QmAXgaAJY0EAFUAILVWhNJrK52mAxdfXc4Gu0id7UCHexLCDgBY
uPLq/WjIrter4nhuSgeuT/cwHZg6e3DRhpLmJLjz0LmxDN4/99jIfhzY7t6PoWl7/0f314u/U8s8n1Ta
y6d04HCWrXzTOQfrAGh0t7+LgtrmONh2TAM7jmugvj0O+h64N0j8/2t90XCsPgG+OqKFfacTofVajMfG
3/5NDOyvToSvDmvhyNkEuHo72v17Mt1lIMNIv50nNLD1qBaqm+Kh937UgLb3rO7/yqZkXs6axoEa0oHP
mGHDTRfpwDdKlJ0OHGQILG7QQfvdx9Vc0WB67kRDweYUmJQh9SfPTJ1ugtLdyXDznvP679i2sTMWMlcY
YNy0x0k3mnkiVDCjvusGAIeZwScvEGGMNUlpbKoZpi01cvi4gsAtBqsNFUkQNcPUf72R6RIs3qiDrlsW
gOA1o7ezq1PD1z/o/qtoFyC3dQFsvVs20PgZEDAzEDMCqaNdQ2BRg6Waq206ULwr+YmsOfx+jNkMW9hT
/TsHFV7xZ9f7oiBzuQG+EAdmzo1i/0bjrGu2hh4Paos/O385FuJmm/jv2rfFv2VeYoRuZsjfPXLwvuxn
u09pYFzqoOu1vm/hlhS4wzyXznvRsLldS66/KtOBa0XIb1/Ii4AiCFD4fV5bDi0AeggBLNBY1JwMWxs1
EDvH5DBlFg1Kt1iAE13xUMPm0TU3HquOAaS8UssN0VH6LLadt1E/oI1NOCdfvEX3hPH3F9tg4Fl3LIm/
x4C2rN2pq/EgLBEctuWeCwNPcV0yzDuvo3ut9kjArHNpMO/ibC5c+KMO9h4ESXtcFyHFVFjjIYG70QNU
a4T4daLTGgVojJMWSiCdNj7RVmLz8Sm5Jqd5+vjzuFITf4/BbYWjRteFUhiQNDtFEOnJr34AiHbpwLTq
72PlITcAGMsAoD/goO4d+zcWxnBqiAiABY5LZosMCljfwFXbmGKTw/c0HBZg3HTnxVHQe0jaIfIS63SP
KReA5CcAxikNAKkEAAIAiQBAACAAkAgAJAIAiQBAUl86sC03wMTzA6hzCQAEgDACAIb7LuvIh7XXV8Ea
psIreXxbkDqZAEAAUHk6MNYC2HBztSUd2E5YGwBrAtCWIAGAAKBSAGCkX0nPcqfpwKu6l6nncBACAAGA
ADDw6Z91Lh3KXaQDb8J04LPTqLMJAHR/1QiAmZQOTAAgAITvFACPAMPSXw7Tge9a1gHwBGHqbAIA3WOV
7gLkty106gFgqjB1NAGAAKBiAODef8Hl3AGlwXBdYEn7Yp4qTB1NACAAqDwOAFf6ccsv51I201w278/g
5wRQJxMACABhkw5ssEsHpkU/AgABgHIBSAQAAgABgBSmAKCCIAQAkucASNknwNg054Y4LkviRjfYGNHA
4je4BsDkRRI39ifeF0uC5TsvCYZt41aLDgFgPCrA+JmSSw8gebcDYJEIAKQnZTxmhAlzHBuUra6feMqF
9+ACHrElJqfgceU9WNx4x0bMvYdcyTE82M8QDoYjBICwAQDmBpgp9t8vJW4SudENMEis059uBu120akx
oTFGLTNZ2g0qKR7JoKI/5MQQ0ZVnRjpx3iBDtv6dqQUmx9CxgWeXwKcmg9viZ4hfT9vAYQEAjPcvuLyY
nxNY2rMSlrQvggzKAfBJaMgIATRanA6g4aNxareK3F13NYUQThghZpWJV+rFtYSxGcz1zzWBrsLNU5j9
n+6AwKcCaMzYdtx0CaJXmphX4v4JjvP8ifMlfq3ohUyYLUECm5I4nHKQ1JQObOR7/ngk+IB04LvlsPab
Yp4sRB3t43TguGVNQLdf4IbtsRtdZVmcS9krcKPmC381nq1B4O/iIiO25WsNVZ63FU4aOWjwmjk06B6G
RzrwqqvLnKYDr+xaSunAfi4M+jR/rlFgW5IS04HToPz2OhfpwGtpKkAiUTow7SSQSOpMB+5d4zQdGE8O
xhOEqbNJJJXuAiy5vNipB5DXtpA6mkTydieIecxCtZ5LtPsqSwBMq5N4RWD7qQB+j5WBMVWYbiiJ5Lnh
49eZddNh2flC2Ni4AcovlsPaC2sg79xiyKidFtDpdEDTgWc1ZMHilgVM8/n3tPpPInln/DPqMmFL0xY4
f6UBrnR1Qlf3Va7O7m5o67oMVe3VUNywClJrpICAgNKBSSSZGP/8s9lwur1qgNEPVld3D1zu6oA9zXsC
4g1QLgCJJAPjn103E2ou10I3M3BHhu9Iu5t3M0/ARAAgkZQsc7UIe5v3On3qOxN6AkUNK/3yAggAJNIQ
P/0Xnl0AzZ2tXgMAvYXK9kpIq0lVBwAGrCF4+Z7+tCWRhhIAmy5u8tr4bWrtaodFZ3N89gJkAwAsIIpR
hYta5kNuaw7MuTDDq4rCWJDU1nZu40zafiQpQjjuD7Qc9GruP1glDcU8TkCxAMCEIkwftpUVxwjCLX0b
oai7ENLdRBHiVmNeW05/PoKlbRkUX11OOQgk+c//2dg/3nbcZwCg57C+cb2yAbCweR5sZUbrKJtweecS
p/EE6PYsaJrDYeGoLQIEO5gGGknOHsDh1sN+eQCrL5T6BYBfhhIA6Kqvub7KYTqx5YCRdU6TidC4sfiI
s7YYjYjTCopJIMl5DWBr0xaf1wDau65A3rlcX8OEf0EA/K8rAGj3JIB4OngGlHE2Fcp61zrNJUDPAOf0
jiCEZw5ucHIuoU3zmmbToiBJ1gDIr8/jUX6+uP91l89AZq3P2bY/IQB6XQJgNwNAZfAMKK1Ogg03Sp0a
MX+KN2Q5NGL0HrDqkDMPAKcGuJhIACDJWdNqJDjaetSnaQDO//3wcG8gAGpdAUCzKx6Ek/qgdsDSK3lO
KwqtvlbkckUfFw8dGT+2RTggYGiQkZQQC3Cho9HjqQCGBB9tPeZvOHANAqDI3UKg4VhKUDsApwFYTNRm
uDbhseOYVCS68iDOmPmK/+C2Zb1rYE7jjGBc7w9MdUwbmYpIilSZ9R7+KCcIFNYXQAODgCtPwJYncKLt
JA8f9nN9ayUCYBLTz64AkHJQG/QOQEPGPfySnhUcBkuv5EJWvWcFRTEdeXHrAijuWc7bYhoyxgUE+Bp/
Yapg+pDp36Ua41Pm07qI1EqSkmQ+rY8w1RieYvfw19Z7WWG9t7KAQM7Z+XxXAAN80NARBjYhABo7mmBb
0zaYXpvhr/H/zBSJAHiOqdPtTsBpQ0g6ALf8bFt3ol9tDYE2/mVMv2GKsEmsEUgKlP09tN7T5XKCAKb6
5p5bBOUXN0FFSwUcajkEe5v38JoA2WdmB2p8dzD9PkKzI/5pZuSlLtcBdsaD8YQunOdpFQOMv8YYQS9l
v0xVT0CgQm7rAjYjx1gB/GqpChSwB1sJ09PoAaBGMD1yOQ04oA1X48c5/wf9g4W5/fRSx0uoHeANfGi9
1+Ewph8xfYSf2waAZ5j2DfVugExVi3N+7CxDLRm/2l5SnWgDwK+tC4PhMKb3Mv0/ewDYvIAHLr2Ar8PS
C9hgrtU/JZHbr97pQLWBSf+UdWdH7eP5gdXb4eCLSNgVH6FhANDsjPsVM/JCd2sBhuMp4QaAFaZaI58z
0kvNAOCewMowGM8FTL8asJaleewFPOsuMAhDg4VKPQGAXgQA5amG6dn+p7/tlbwjOSJhR6wNAm8x9biC
QHKFJiTbggQAehEAAqYepje58VcJEaZa08BO0O5gU4Gd8RGJ2zkE/sV0y92uQJjE2BMACABK1y2mkY/j
V5yMZQSAhoHA6g2MdOcJcAio3xMgABAAlP7kH2kf/OTyhQCw2xl4y92aQPJ+DQin9AQAehEA5LmF/ZbH
xm972QHAtjC41NUWIS4MGo6mADMSNQIgz6vOo5cCAdBvIPkq2uorsF/w83r8anfGsamABQJsaoBbhB9Z
g4UcRwzutCwO8pBh9YDg/5gmWCIABbIUlb7Eqv6IwEjrPVdyhN9ea5SfZauvWuAejk8vfYXefosQQfCM
NWAIcwc6HGURYqwAggBTiINZSCRE2m7LAZAIAOEAALzXOxQ2Rn+2JvaUWA3/GfunvrlS738HJe5NiNBs
j+tfH2DewdPWLMKJTCut6wS91vJiv9hPDTB6UH80mYcR8wVDZXgH960d+h/k/ofdNADveal1DMhtXGLG
4k9MN617+rhmMZHpOUzsGZDlWOXZU///A2yjWVvAsVLjAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@ -0,0 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,234 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Transformers2_Launcher
{
public class Codecave
{
private Process _Process;
private IntPtr _ProcessHandle;
private IntPtr _ModuleBaseAddress = IntPtr.Zero;
private UInt32 _Cave_Address = 0;
private UInt32 _CaveOffset = 0;
public UInt32 CaveAddress
{
get { return _Cave_Address; }
}
public UInt32 CaveOffset
{
get { return _CaveOffset; }
}
public Codecave(Process p, IntPtr BaseAddress)
{
_Process = p;
_ModuleBaseAddress = BaseAddress;
}
/// <summary>
/// Trying to access the process
/// </summary>
/// <returns>True if success, otherwise False</returns>
public bool Open()
{
_ProcessHandle = _Process.Handle;
if (_ProcessHandle != IntPtr.Zero)
return true;
else
return false;
}
/// <summary>
/// Reserves a region of memory within the virtual address space of a specified process.
/// The function initializes the memory it allocates to zero.
/// </summary>
/// <param name="Size">The size of the region of memory to allocate, in bytes.</param>
/// <returns>True is success, otherwise False</returns>
public bool Alloc(UInt32 Size)
{
//Allocation mémoire
_Cave_Address = (UInt32)Win32API.VirtualAllocEx(_ProcessHandle, IntPtr.Zero, Size, MemoryAllocType.MEM_COMMIT, MemoryPageProtect.PAGE_EXECUTE_READWRITE);
if (_Cave_Address != 0)
return true;
else
return false;
}
//call Address
public bool Write_call(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 5;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0xE8);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//cmp eax,[Value]
public bool Write_cmp(int Value)
{
List<Byte> Buffer = new List<byte>();
Buffer.Add(0x81);
Buffer.Add(0xF9);
Buffer.AddRange(BitConverter.GetBytes(Value));
return Write_Bytes(Buffer.ToArray());
}
//je [Address]
public bool Write_je(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 6;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0x0F);
Buffer.Add(0x84);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//jb [Address]
public bool Write_jb(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 6;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0x0F);
Buffer.Add(0x82);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//jng [Address]
public bool Write_jng(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 6;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0x0F);
Buffer.Add(0x8E);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//jnl [Address]
public bool Write_jnl(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 6;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0x0F);
Buffer.Add(0x8D);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//jng [Address]
public bool Write_jg(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 6;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0x0F);
Buffer.Add(0x8F);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//jng [Address]
public bool Write_ja(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 6;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0x0F);
Buffer.Add(0x87);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//jnl [Address]
public bool Write_jl(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 6;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0x0F);
Buffer.Add(0x8C);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//jmp [Address]
public bool Write_jmp(UInt32 Address)
{
UInt32 JmpAddress = Address - (_Cave_Address + _CaveOffset) - 5;
List<Byte> Buffer = new List<byte>();
Buffer.Add(0xE9);
Buffer.AddRange(BitConverter.GetBytes(JmpAddress));
return Write_Bytes(Buffer.ToArray());
}
//nop
public bool Write_nop(int Amount = 1)
{
List<Byte> Buffer = new List<byte>();
for (int i = 0; i < Amount; i++)
{
Buffer.Add(0x90);
}
return Write_Bytes(Buffer.ToArray());
}
/// <summary>
/// Write bytes in memory, read from a string like "00 00 00 00"
/// </summary>
/// <param name="StrBuffer">String formated series of bytes to write</param>
/// <returns>True if success, otherwise False</returns>
public bool Write_StrBytes(String StrBuffer)
{
String[] sBytes = StrBuffer.Split(' ');
List<Byte> Buffer = new List<byte>();
foreach (String hex in sBytes)
{
Buffer.Add((byte)Convert.ToInt32(hex, 16));
}
return Write_Bytes(Buffer.ToArray());
}
/// <summary>
/// Write bytes in memory, read from an array of bytes
/// </summary>
/// <param name="Buffer">Array of bytes to write</param>
/// <returns>True if success, otherwise False</returns>
public bool Write_Byte(Byte Data)
{
UInt32 BytesWritten = 0;
if (Win32API.WriteProcessMemory(_ProcessHandle, _Cave_Address + _CaveOffset, new byte[]{Data}, 1, ref BytesWritten))
{
_CaveOffset += BytesWritten;
return true;
}
else
{
return false;
}
}
/// <summary>
/// Write bytes in memory, read from an array of bytes
/// </summary>
/// <param name="Buffer">Array of bytes to write</param>
/// <returns>True if success, otherwise False</returns>
public bool Write_Bytes(Byte[] Buffer)
{
UInt32 BytesWritten = 0;
if (Win32API.WriteProcessMemory(_ProcessHandle, _Cave_Address + _CaveOffset, Buffer, (UInt32)Buffer.Length, ref BytesWritten))
{
_CaveOffset += BytesWritten;
return true;
}
else
{
return false;
}
}
}
}

View File

@ -0,0 +1,343 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Debugger;
namespace Debugger
{
#region DEBUG_EVENT
[StructLayout(LayoutKind.Sequential)]
public struct DEBUG_EVENT
{
public DebugEventType dwDebugEventCode;
public int dwProcessId;
public int dwThreadId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 86, ArraySubType = UnmanagedType.U1)]
byte[] debugInfo;
public EXCEPTION_DEBUG_INFO Exception
{
get { return GetDebugInfo<EXCEPTION_DEBUG_INFO>(); }
}
public CREATE_THREAD_DEBUG_INFO CreateThread
{
get { return GetDebugInfo<CREATE_THREAD_DEBUG_INFO>(); }
}
public CREATE_PROCESS_DEBUG_INFO CreateProcessInfo
{
get { return GetDebugInfo<CREATE_PROCESS_DEBUG_INFO>(); }
}
public EXIT_THREAD_DEBUG_INFO ExitThread
{
get { return GetDebugInfo<EXIT_THREAD_DEBUG_INFO>(); }
}
public EXIT_PROCESS_DEBUG_INFO ExitProcess
{
get { return GetDebugInfo<EXIT_PROCESS_DEBUG_INFO>(); }
}
public LOAD_DLL_DEBUG_INFO LoadDll
{
get { return GetDebugInfo<LOAD_DLL_DEBUG_INFO>(); }
}
public UNLOAD_DLL_DEBUG_INFO UnloadDll
{
get { return GetDebugInfo<UNLOAD_DLL_DEBUG_INFO>(); }
}
public OUTPUT_DEBUG_STRING_INFO DebugString
{
get { return GetDebugInfo<OUTPUT_DEBUG_STRING_INFO>(); }
}
public RIP_INFO RipInfo
{
get { return GetDebugInfo<RIP_INFO>(); }
}
private T GetDebugInfo<T>() where T : struct
{
var structSize = Marshal.SizeOf(typeof(T));
var pointer = Marshal.AllocHGlobal(structSize);
Marshal.Copy(debugInfo, 0, pointer, structSize);
var result = Marshal.PtrToStructure(pointer, typeof(T));
Marshal.FreeHGlobal(pointer);
return (T)result;
}
[StructLayout(LayoutKind.Sequential)]
public struct EXCEPTION_DEBUG_INFO
{
public EXCEPTION_RECORD ExceptionRecord;
public uint dwFirstChance;
}
[StructLayout(LayoutKind.Sequential)]
public struct EXCEPTION_RECORD
{
public uint ExceptionCode;
public uint ExceptionFlags;
public IntPtr ExceptionRecord;
public IntPtr ExceptionAddress;
public uint NumberParameters;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15, ArraySubType = UnmanagedType.U4)]
public uint[] ExceptionInformation;
}
public delegate uint PTHREAD_START_ROUTINE(IntPtr lpThreadParameter);
[StructLayout(LayoutKind.Sequential)]
public struct CREATE_THREAD_DEBUG_INFO
{
public IntPtr hThread;
public IntPtr lpThreadLocalBase;
public PTHREAD_START_ROUTINE lpStartAddress;
}
[StructLayout(LayoutKind.Sequential)]
public struct CREATE_PROCESS_DEBUG_INFO
{
public IntPtr hFile;
public IntPtr hProcess;
public IntPtr hThread;
public IntPtr lpBaseOfImage;
public uint dwDebugInfoFileOffset;
public uint nDebugInfoSize;
public IntPtr lpThreadLocalBase;
public PTHREAD_START_ROUTINE lpStartAddress;
public IntPtr lpImageName;
public ushort fUnicode;
}
[StructLayout(LayoutKind.Sequential)]
public struct EXIT_THREAD_DEBUG_INFO
{
public uint dwExitCode;
}
[StructLayout(LayoutKind.Sequential)]
public struct EXIT_PROCESS_DEBUG_INFO
{
public uint dwExitCode;
}
[StructLayout(LayoutKind.Sequential)]
public struct LOAD_DLL_DEBUG_INFO
{
public IntPtr hFile;
public IntPtr lpBaseOfDll;
public uint dwDebugInfoFileOffset;
public uint nDebugInfoSize;
public IntPtr lpImageName;
public ushort fUnicode;
}
[StructLayout(LayoutKind.Sequential)]
public struct UNLOAD_DLL_DEBUG_INFO
{
public IntPtr lpBaseOfDll;
}
[StructLayout(LayoutKind.Sequential)]
public struct OUTPUT_DEBUG_STRING_INFO
{
[MarshalAs(UnmanagedType.LPStr)]
public string lpDebugStringData;
public ushort fUnicode;
public ushort nDebugStringLength;
}
[StructLayout(LayoutKind.Sequential)]
public struct RIP_INFO
{
public uint dwError;
public uint dwType;
}
}
#endregion
public enum DebugEventType : uint
{
RIP_EVENT = 9,
OUTPUT_DEBUG_STRING_EVENT = 8,
UNLOAD_DLL_DEBUG_EVENT = 7,
LOAD_DLL_DEBUG_EVENT = 6,
EXIT_PROCESS_DEBUG_EVENT = 5,
EXIT_THREAD_DEBUG_EVENT = 4,
CREATE_PROCESS_DEBUG_EVENT = 3,
CREATE_THREAD_DEBUG_EVENT = 2,
EXCEPTION_DEBUG_EVENT = 1,
}
public enum ContinueStatus : uint
{
DBG_CONTINUE = 0x00010002,
DBG_EXCEPTION_NOT_HANDLED = 0x80010001,
DBG_REPLY_LATER = 0x40010001
}
public class QuickDebugger
{
#region Debugger WIN32 functions
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CreateProcess(
string lpApplicationName,
string lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll", EntryPoint = "WaitForDebugEvent")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WaitForDebugEvent(ref DEBUG_EVENT lpDebugEvent, uint dwMilliseconds);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ContinueDebugEvent(int dwProcessId, int dwThreadId, ContinueStatus dwContinueStatus);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool DebugActiveProcessStop(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, UInt32 lpBaseAddress, byte[] lpBuffer, UInt32 dwSize, ref UInt32 lpNumberOfBytesWritten);
#endregion
#region Win32 Struct
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
}
// This also works with CharSet.Ansi as long as the calling function uses the same character set.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFOEX
{
public STARTUPINFO StartupInfo;
public IntPtr lpAttributeList;
}
// This also works with CharSet.Ansi as long as the calling function uses the same character set.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
#endregion
public const uint STATUS_BREAKPOINT = 0x80000003;
const uint DEBUG_ONLY_THIS_PROCESS = 0x00000002;
const UInt32 INFINITE = 0xffffffff;
private String _TargetExePath;
private DEBUG_EVENT _DebugEvent;
private bool _ContinueDebugging = true;
public delegate void DebugEventHandler(object sender, DebugEventArgs e);
public event DebugEventHandler OnDebugEvent;
public QuickDebugger(String PathToExe)
{
_TargetExePath = PathToExe;
}
public void StartProcess()
{
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
STARTUPINFO sInfo = new STARTUPINFO();
SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES();
pSec.nLength = Marshal.SizeOf(pSec);
tSec.nLength = Marshal.SizeOf(tSec);
CreateProcess(_TargetExePath, "", ref pSec, ref tSec, false, DEBUG_ONLY_THIS_PROCESS, IntPtr.Zero, null, ref sInfo, out pInfo);
_DebugEvent = new DEBUG_EVENT();
while (_ContinueDebugging)
{
if (!WaitForDebugEvent(ref _DebugEvent, INFINITE))
return;
if (OnDebugEvent != null)
OnDebugEvent(this, new DebugEventArgs(_DebugEvent));
else
ContinueDebugEvent();
}
}
public void ContinueDebugEvent()
{
ContinueDebugEvent(_DebugEvent.dwProcessId, _DebugEvent.dwThreadId, ContinueStatus.DBG_CONTINUE);
}
public void StopDebuging()
{
_ContinueDebugging = false;
}
public void DetachDebugger()
{
DebugActiveProcessStop((uint)_DebugEvent.dwProcessId);
_ContinueDebugging = false;
}
}
public class DebugEventArgs : EventArgs
{
public DEBUG_EVENT Dbe { get; private set; }
public DebugEventArgs(DEBUG_EVENT DebugEvent)
{
Dbe = DebugEvent;
}
}
}

View File

@ -0,0 +1,38 @@
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace Transformers2_Launcher
{
#region INI class
public class INIFile
{
private string _RelativePath = string.Empty;
public FileInfo FInfo { get; private set; }
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
public INIFile(string INIPath)
{
_RelativePath = INIPath;
FInfo = new FileInfo(_RelativePath);
}
public long IniWriteValue(string Section, string Key, string Value)
{
return WritePrivateProfileString(Section, Key, Value, this._RelativePath);
}
public string IniReadValue(string Section, string Key)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, Key, "", temp, 255, this._RelativePath);
return temp.ToString();
}
}
#endregion
}

View File

@ -0,0 +1,36 @@
using System;
using System.IO;
namespace Transformers2_Launcher
{
public static class Logger
{
private static string LogFilename = "debug.txt";
public static bool IsEnabled { get; set; }
public static void InitLogFileName()
{
LogFilename = "Debug_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".txt";
}
/// <summary>
/// Writing to Log only if verbose arg given in cmdline
/// </summary>
public static void WriteLog(String Data)
{
if (IsEnabled)
{
try
{
using (StreamWriter sr = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + @"\" + LogFilename, true))
{
sr.WriteLine(DateTime.Now.ToString("[HH:mm:ss.ffffff] ") + Data);
sr.Close();
}
}
catch { }
}
}
}
}

View File

@ -0,0 +1,105 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Transformers2_Launcher
{
public static class ProcessTools
{
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("kernel32.dll")]
static extern uint SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern int ResumeThread(IntPtr hThread);
[Flags]
public enum ThreadAccess : int
{
TERMINATE = (0x0001),
SUSPEND_RESUME = (0x0002),
GET_CONTEXT = (0x0008),
SET_CONTEXT = (0x0010),
SET_INFORMATION = (0x0020),
QUERY_INFORMATION = (0x0040),
SET_THREAD_TOKEN = (0x0080),
IMPERSONATE = (0x0100),
DIRECT_IMPERSONATION = (0x0200)
}
[DllImport("ntdll.dll", PreserveSig = false)]
public static extern void NtSuspendProcess(IntPtr processHandle);
[DllImport("ntdll.dll", PreserveSig = false, SetLastError = true)]
public static extern void NtResumeProcess(IntPtr processHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess,bool bInheritHandle,int processId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VirtualMemoryOperation = 0x00000008,
VirtualMemoryRead = 0x00000010,
VirtualMemoryWrite = 0x00000020,
DuplicateHandle = 0x00000040,
CreateProcess = 0x000000080,
SetQuota = 0x00000100,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x00001000,
Synchronize = 0x00100000
}
public static void Suspend(this Process process)
{
foreach (ProcessThread thread in process.Threads)
{
var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);
if (pOpenThread == IntPtr.Zero)
{
break;
}
SuspendThread(pOpenThread);
}
}
public static void Resume(this Process process)
{
foreach (ProcessThread thread in process.Threads)
{
var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);
if (pOpenThread == IntPtr.Zero)
{
break;
}
ResumeThread(pOpenThread);
}
}
public static void SuspendProcess(Process p)
{
IntPtr hProcess = OpenProcess(ProcessAccessFlags.All, false, p.Id);
NtSuspendProcess(hProcess);
CloseHandle(hProcess);
}
public static void ResumeProcess(Process p)
{
IntPtr hProcess = OpenProcess(ProcessAccessFlags.All, false, p.Id);
NtResumeProcess(hProcess);
CloseHandle(hProcess);
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Windows.Forms;
namespace Transformers2_Launcher
{
public static class Program
{
/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
bool bEnableLogs = false;
if (args.Length > 0)
{
for (int i = 0; i < args.Length; i++)
{
if (args[i].ToLower().Equals("-v") || args[i].ToLower().Equals("--verbose"))
{
bEnableLogs = true;
break;
}
}
}
Transformers2_Launcher Launcher = new Transformers2_Launcher(bEnableLogs);
Launcher.RunGame();
//Launcher.Run_Game_Debug();
Application.Exit();
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Les informations générales relatives à un assembly dépendent de
// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations
// associées à un assembly.
[assembly: AssemblyTitle("Transformers2_Launcher")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Transformers2_Launcher")]
[assembly: AssemblyCopyright("Argonlefou © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly
// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de
// COM, affectez la valeur true à l'attribut ComVisible sur ce type.
[assembly: ComVisible(false)]
// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM
[assembly: Guid("0731316c-555f-4a84-a206-1e3539358b53")]
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
//
// Version principale
// Version secondaire
// Numéro de build
// Révision
//
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
// en utilisant '*', comme indiqué ci-dessous :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0")]
[assembly: AssemblyFileVersion("1.0.0")]

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Ce code a été généré par un outil.
// Version du runtime :4.0.30319.42000
//
// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
// le code est régénéré.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Transformers2_Launcher.Properties {
using System;
/// <summary>
/// Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées.
/// </summary>
// Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder
// à l'aide d'un outil, tel que ResGen ou Visual Studio.
// Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen
// avec l'option /str ou régénérez votre projet VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Retourne l'instance ResourceManager mise en cache utilisée par cette classe.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Transformers2_Launcher.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Remplace la propriété CurrentUICulture du thread actuel pour toutes
/// les recherches de ressources à l'aide de cette classe de ressource fortement typée.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Ce code a été généré par un outil.
// Version du runtime :4.0.30319.42000
//
// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
// le code est régénéré.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Transformers2_Launcher.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,522 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using Debugger;
namespace Transformers2_Launcher
{
public class Transformers2_Launcher
{
private const string MEMORY_DATA_FOLDER = "MemoryData";
private const string TARGET_EXE_NAME = @"Transformers2.exe";
private int _ProcessId = 0;
private Process _Process;
private IntPtr _Process_MemoryBaseAddress = IntPtr.Zero;
private IntPtr _ProcessHandle = IntPtr.Zero;
//Memory Hacks
private UInt32 _DisableCShell_Offset = 0x001E70E4;
private UInt32 _RestoreHiddenConfig_Offset = 0x00240C80;
private UInt32 _SetWindowedMode_Offset = 0x002409F5;
private UInt32 _RemoveOriginalWindowedMode_Offset = 0x00240A1C;
private UInt32 _ForceResolutionIndex_Offset = 0x00260AD5;
private UInt32 _ResolutionTableHd_Offset = 0x008A5008;
private UInt32 _DisableLEDBoardCreation_Offset = 0x002EB93C;
private UInt32 _DisableSAEBoardCreation_Offset = 0x0017A4A2;
private UInt32 _CGunMgrForceInputMouse_Offset1 = 0x000F54F9;
private UInt32 _CGunMgrForceInputMouse_Offset2 = 0x000F551C;
private UInt32 _CGunMgrForceInputMouse_Offset3 = 0x000F5534;
//MD5 check of target binaries, may help to know if it's the wrong version or not compatible
protected Dictionary<string, string> _KnownMd5Prints;
protected String _TargetProcess_Md5Hash = string.Empty;
//Config values
private const string LAUNCHER_INI_PATH = @".\Transformers2_Launcher.ini";
private INIFile _Launcher_IniFile;
private UInt32 _Cfg_ScreenWidth = 0;
private UInt32 _Cfg_ScreenHeight = 0;
private byte _Cfg_Windowed = 0;
Debugger.QuickDebugger _Qdb;
public Transformers2_Launcher(bool EnableLogs)
{
Logger.InitLogFileName();
Logger.IsEnabled = EnableLogs;
_Launcher_IniFile = new INIFile(AppDomain.CurrentDomain.BaseDirectory + LAUNCHER_INI_PATH);
if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + TARGET_EXE_NAME))
{
Logger.IsEnabled = true;
Logger.WriteLog("Transformers2_Launcher() => Transformers2.exe not found. Abording...");
Environment.Exit(0);
}
if (!File.Exists(_Launcher_IniFile.FInfo.FullName))
{
Logger.IsEnabled = true;
Logger.WriteLog("Transformers2_Launcher() => No config file found. Abording...");
Environment.Exit(0);
}
try
{
_Cfg_ScreenWidth = UInt32.Parse(_Launcher_IniFile.IniReadValue("Video", "WIDTH"));
_Cfg_ScreenHeight = UInt32.Parse(_Launcher_IniFile.IniReadValue("Video", "HEIGHT"));
if (_Launcher_IniFile.IniReadValue("Video", "FULLSCREEN").Equals("0"))
_Cfg_Windowed = 1;
else
_Cfg_Windowed = 0;
}
catch (Exception Ex)
{
Logger.IsEnabled = true;
Logger.WriteLog("Transformers2_Launcher() => Error reading config file : " + _Launcher_IniFile.FInfo.FullName);
Logger.WriteLog(Ex.Message.ToString());
Logger.WriteLog("Abording...");
Environment.Exit(0);
}
_KnownMd5Prints = new Dictionary<String, String>();
_KnownMd5Prints.Add("Transformers Shadow Rising v180605 - Original Dump", "b3b1f4ad6408d6ee946761a00f761455");
}
/// <summary>
/// Create the process with DEBUG attributes, so that we can stop it to inject the code, and then resume it
/// Inspired from a hand-made debugger https://www.codeproject.com/Articles/43682/Writing-a-basic-Windows-debugger
/// </summary>
public void RunGame()
{
_Qdb = new QuickDebugger(AppDomain.CurrentDomain.BaseDirectory + TARGET_EXE_NAME);
_Qdb.OnDebugEvent += new Debugger.QuickDebugger.DebugEventHandler(Qdb_OnDebugEvent);
_Qdb.StartProcess();
}
private void Qdb_OnDebugEvent(object sender, Debugger.DebugEventArgs e)
{
switch (e.Dbe.dwDebugEventCode)
{
case DebugEventType.CREATE_PROCESS_DEBUG_EVENT:
{
Logger.WriteLog("RunGame() => Process created");
_Qdb.ContinueDebugEvent();
} break;
case DebugEventType.CREATE_THREAD_DEBUG_EVENT:
{
DEBUG_EVENT.CREATE_THREAD_DEBUG_INFO ti = new DEBUG_EVENT.CREATE_THREAD_DEBUG_INFO();
ti = e.Dbe.CreateThread;
Logger.WriteLog("Thread 0x" + ti.hThread.ToString("X8") + " (Id: " + e.Dbe.dwThreadId.ToString() + ") created");
_Qdb.ContinueDebugEvent();
} break;
//The game has a breakpoint installed at start (!), we can use it to search for information, block the process to insert our code
case DebugEventType.EXCEPTION_DEBUG_EVENT:
{
DEBUG_EVENT.EXCEPTION_DEBUG_INFO Ex = new DEBUG_EVENT.EXCEPTION_DEBUG_INFO();
Ex = e.Dbe.Exception;
if (Ex.ExceptionRecord.ExceptionCode == QuickDebugger.STATUS_BREAKPOINT)
{
Logger.WriteLog("RunGame() => Breakpoint reached !");
Process p = Process.GetProcessById(e.Dbe.dwProcessId);
_Process = p;
_ProcessId = _Process.Id;
_ProcessHandle = _Process.Handle;
_Process_MemoryBaseAddress = _Process.MainModule.BaseAddress;
Logger.WriteLog("RunGame() => Process ID: " + _ProcessId.ToString());
Logger.WriteLog("RunGame() => Process Memory Base Address: 0x" + _Process_MemoryBaseAddress.ToString("X8"));
Logger.WriteLog("RunGame() => Process Handle: 0x" + _ProcessHandle.ToString("X8"));
CheckExeMd5();
ReadGameDataFromMd5Hash();
Apply_Hacks();
Logger.WriteLog("RunGame() => Hack complete, leaving the game to run on its own now....");
_Qdb.DetachDebugger();
_Qdb.ContinueDebugEvent();
}
} break;
default:
{
_Qdb.ContinueDebugEvent();
} break;
}
}
/// <summary>
/// Creating the Process without DEBUG attributes can allow another debugger to go in and analyse what's going on
/// </summary>
public void Run_Game_Debug()
{
FileInfo fi = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + TARGET_EXE_NAME);
_Process = new Process();
_Process.StartInfo.FileName = fi.FullName;
_Process.Start();
try
{
ProcessTools.SuspendProcess(_Process);
_ProcessId = _Process.Id;
_ProcessHandle = _Process.Handle;
_Process_MemoryBaseAddress = _Process.MainModule.BaseAddress;
Apply_Hacks();
ProcessTools.ResumeProcess(_Process);
}
catch (InvalidOperationException)
{
}
catch (Exception)
{
}
}
#region Hacks
public void Apply_Hacks()
{
//Disabling the CShell necessity, if not the game is shutting down if no correct Keep-alive reply from the Shell.exe program
WriteByte((UInt32)_Process_MemoryBaseAddress + _DisableCShell_Offset, 0x00);
//GetConfigIniDir() function is stripped. Putting back a fixed name (./App.ini) to restore the possibility to change some settings
WriteBytes((UInt32)_Process_MemoryBaseAddress + _RestoreHiddenConfig_Offset, new byte[] { 0xB8, 0x86, 0x0C, 0x64, 0x00, 0xC3, 0x2E, 0x2F, 0x41, 0x70, 0x70, 0x2E, 0x69, 0x6E, 0x69, 0x00 });
//LED Board is connected through COM port
//Setting COM access result to (-1) instead of trying to open COM port for real
WriteBytes((UInt32)_Process_MemoryBaseAddress + _DisableLEDBoardCreation_Offset, new byte[] { 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x1D, 0x90, 0x90, 0x90, 0x90 });
//Force not to create SAEBoard
WriteByte((UInt32)_Process_MemoryBaseAddress + _DisableSAEBoardCreation_Offset, 0xEB);
//CGunMgr() init input mode by checking first if JVS is enabled, forcing it to false
WriteByte((UInt32)_Process_MemoryBaseAddress + _CGunMgrForceInputMouse_Offset1, 0xEB);
//Then checking if SAEBoard is active, forcing it to false also
WriteByte((UInt32)_Process_MemoryBaseAddress + _CGunMgrForceInputMouse_Offset2, 0xEB);
//Finally forcing input mode to '1' (mouse) for P2 (already 1 for P1 normally)
WriteByte((UInt32)_Process_MemoryBaseAddress + _CGunMgrForceInputMouse_Offset3, 0x1);
//Replacing the original default value for Windowed mode by our own
WriteByte((UInt32)_Process_MemoryBaseAddress + _SetWindowedMode_Offset, _Cfg_Windowed);
//Disabling the default Windowed mode set after reading the "hidden" config file
WriteBytes((UInt32)_Process_MemoryBaseAddress + _RemoveOriginalWindowedMode_Offset, new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 });
//Screen Size Hack :
//First step is to force the game to choose index 0xF in the resolution table, whatever SWITCH or option is used
WriteBytes((UInt32)_Process_MemoryBaseAddress + _ForceResolutionIndex_Offset, new byte[] { 0x90, 0x90, 0xB8, 0x0F });
//Second step is to replace Width and Height values for the desires Resolution by our own
for (uint i = 0; i < 3; i++)
{
WriteBytes((UInt32)_Process_MemoryBaseAddress + _ResolutionTableHd_Offset + (i * 8), BitConverter.GetBytes(_Cfg_ScreenWidth));
WriteBytes((UInt32)_Process_MemoryBaseAddress + _ResolutionTableHd_Offset + (i * 8) + 4, BitConverter.GetBytes(_Cfg_ScreenHeight));
}
// Not needed
//Credits force value to 0 instead of -1 (-1 won't update value) ?????? to confirm when set_credit hack is done
//WriteByte((UInt32)_Process_MemoryBaseAddress + 0x66953, 0x00);
}
#endregion
#region MD5 Verification
/// <summary>
/// Compute the MD5 hash of the target executable and compare it to the known list of MD5 Hashes
/// This can be usefull if people are using some unknown dump with different memory,
/// or a wrong version of emulator
/// This is absolutely not blocking, just for debuging with output log
/// </summary>
protected void CheckExeMd5()
{
CheckMd5(_Process.MainModule.FileName);
}
protected void CheckMd5(String TargetFileName)
{
GetMd5HashAsString(TargetFileName);
Logger.WriteLog("CheckMd5() => MD5 hash of " + TargetFileName + " = " + _TargetProcess_Md5Hash);
String FoundMd5 = String.Empty;
foreach (KeyValuePair<String, String> pair in _KnownMd5Prints)
{
if (pair.Value == _TargetProcess_Md5Hash)
{
FoundMd5 = pair.Key;
break;
}
}
if (FoundMd5 == String.Empty)
{
Logger.WriteLog(@"CheckMd5() => /!\ MD5 Hash unknown, the mod may not work correctly with this target /!\");
}
else
{
Logger.WriteLog("CheckMd5() => MD5 Hash is corresponding to a known target = " + FoundMd5);
}
}
/// <summary>
/// Compute the MD5 hash from the target file.
/// </summary>
/// <param name="FileName">Full filepath of the targeted executable.</param>
private void GetMd5HashAsString(String FileName)
{
if (File.Exists(FileName))
{
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(FileName))
{
var hash = md5.ComputeHash(stream);
_TargetProcess_Md5Hash = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
}
}
}
#endregion
#region MemoryData Loading
/// <summary>
/// Read memory values in .cfg file, whose name depends on the MD5 hash of the targeted exe.
/// Mostly used for PC games
/// </summary>
/// <param name="GameData_Folder"></param>
protected virtual void ReadGameDataFromMd5Hash()
{
String ConfigFile = AppDomain.CurrentDomain.BaseDirectory + MEMORY_DATA_FOLDER + @"\" + _TargetProcess_Md5Hash + ".cfg";
if (File.Exists(ConfigFile))
{
Logger.WriteLog("ReadGameDataFromMd5Hash() => Reading game memory setting from " + ConfigFile);
using (StreamReader sr = new StreamReader(ConfigFile))
{
String line;
String FieldName = String.Empty;
line = sr.ReadLine();
while (line != null)
{
String[] buffer = line.Split('=');
if (buffer.Length > 1)
{
try
{
FieldName = "_" + buffer[0].Trim();
if (buffer[0].Contains("Nop"))
{
NopStruct n = new NopStruct(buffer[1].Trim());
this.GetType().GetField(FieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase).SetValue(this, n);
Logger.WriteLog(FieldName + " successfully set to following NopStruct : 0x" + n.MemoryOffset.ToString("X8") + "|" + n.Length.ToString());
}
else if (buffer[0].Contains("Injection"))
{
InjectionStruct i = new InjectionStruct(buffer[1].Trim());
this.GetType().GetField(FieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase).SetValue(this, i);
Logger.WriteLog(FieldName + " successfully set to following InjectionStruct : 0x" + i.Injection_Offset.ToString("X8") + "|" + i.Length.ToString());
}
else
{
UInt32 v = UInt32.Parse(buffer[1].Substring(3).Trim(), NumberStyles.HexNumber);
this.GetType().GetField(FieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase).SetValue(this, v);
Logger.WriteLog(FieldName + " successfully set to following value : 0x" + v.ToString("X8"));
}
}
catch (Exception ex)
{
Logger.WriteLog("ReadGameDataFromMd5Hash() => Error reading game data for " + FieldName + " : " + ex.Message.ToString());
}
}
line = sr.ReadLine();
}
sr.Close();
}
}
else
{
Logger.WriteLog("ReadGameDataFromMd5Hash() => Memory File not found : " + ConfigFile);
}
}
#endregion
#region Memory Hack x86
/// <summary>
/// Defines how many NOP to write at a given Memory offset
/// </summary>
public struct NopStruct
{
public UInt32 MemoryOffset;
public UInt32 Length;
public NopStruct(UInt32 Offset, UInt32 NopLength)
{
MemoryOffset = Offset;
Length = NopLength;
}
public NopStruct(String OffsetAndNumber)
{
MemoryOffset = 0;
Length = 0;
if (OffsetAndNumber != null)
{
try
{
Length = UInt32.Parse((OffsetAndNumber.Split('|'))[1]);
MemoryOffset = UInt32.Parse((OffsetAndNumber.Split('|'))[0].Substring(2).Trim(), System.Globalization.NumberStyles.HexNumber);
}
catch
{
Logger.WriteLog("Impossible to load NopStruct from following String : " + OffsetAndNumber);
}
}
}
}
/// <summary>
/// Defines an injection Memory zone and it's length
/// </summary>
public struct InjectionStruct
{
public UInt32 Injection_Offset;
public UInt32 Injection_ReturnOffset;
public UInt32 Length;
public InjectionStruct(UInt32 Offset, UInt32 InjectionLength)
{
Injection_Offset = Offset;
Length = InjectionLength;
Injection_ReturnOffset = Offset + Length;
}
public InjectionStruct(String OffsetAndNumber)
{
Injection_Offset = 0;
Length = 0;
Injection_ReturnOffset = 0;
if (OffsetAndNumber != null)
{
try
{
Length = UInt32.Parse((OffsetAndNumber.Split('|'))[1]);
Injection_Offset = UInt32.Parse((OffsetAndNumber.Split('|'))[0].Substring(2).Trim(), System.Globalization.NumberStyles.HexNumber);
Injection_ReturnOffset = Injection_Offset + Length;
}
catch
{
Logger.WriteLog("Impossible to load InjectionStruct from following String : " + OffsetAndNumber);
}
}
}
}
protected Byte ReadByte(UInt32 Address)
{
byte[] Buffer = { 0 };
UInt32 bytesRead = 0;
if (!Win32API.ReadProcessMemory(_ProcessHandle, Address, Buffer, 1, ref bytesRead))
{
Logger.WriteLog("Cannot read memory at address 0x" + Address.ToString("X8"));
}
return Buffer[0];
}
protected Byte[] ReadBytes(UInt32 Address, UInt32 BytesCount)
{
byte[] Buffer = new byte[BytesCount];
UInt32 bytesRead = 0;
if (!Win32API.ReadProcessMemory(_ProcessHandle, Address, Buffer, (UInt32)Buffer.Length, ref bytesRead))
{
Logger.WriteLog("Cannot read memory at address 0x" + Address.ToString("X8"));
}
return Buffer;
}
protected UInt32 ReadPtr(UInt32 PtrAddress)
{
byte[] Buffer = ReadBytes(PtrAddress, 4);
return BitConverter.ToUInt32(Buffer, 0);
}
protected UInt32 ReadPtrChain(UInt32 BaseAddress, UInt32[] Offsets)
{
byte[] Buffer = ReadBytes(BaseAddress, 4);
UInt32 Ptr = BitConverter.ToUInt32(Buffer, 0);
if (Ptr == 0)
{
return 0;
}
else
{
for (int i = 0; i < Offsets.Length; i++)
{
Buffer = ReadBytes(Ptr + Offsets[i], 8);
Ptr = BitConverter.ToUInt32(Buffer, 0);
if (Ptr == 0)
return 0;
}
}
return Ptr;
}
protected bool WriteByte(UInt32 Address, byte Value)
{
UInt32 bytesWritten = 0;
Byte[] Buffer = { Value };
if (Win32API.WriteProcessMemory(_ProcessHandle, Address, Buffer, 1, ref bytesWritten))
{
if (bytesWritten == 1)
return true;
else
return false;
}
else
return false;
}
protected bool WriteBytes(UInt32 Address, byte[] Buffer)
{
UInt32 bytesWritten = 0;
if (Win32API.WriteProcessMemory(_ProcessHandle, Address, Buffer, (UInt32)Buffer.Length, ref bytesWritten))
{
if (bytesWritten == Buffer.Length)
return true;
else
return false;
}
else
return false;
}
protected void SetNops(UInt32 BaseAddress, NopStruct Nop)
{
for (UInt32 i = 0; i < Nop.Length; i++)
{
UInt32 Address = (UInt32)BaseAddress + Nop.MemoryOffset + i;
if (!WriteByte(Address, 0x90))
{
Logger.WriteLog("Impossible to NOP address 0x" + Address.ToString("X8"));
break;
}
}
}
#endregion
}
}

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{5D726FF6-B1A8-43C7-BEE8-EFC9E1E88DE0}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Transformers2_Launcher</RootNamespace>
<AssemblyName>Transformers2_Launcher</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Ypf-Transformers-Transformer.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Codecave.cs" />
<Compile Include="INIFile.cs" />
<Compile Include="Logger.cs" />
<Compile Include="ProcessTools.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Debugger.cs" />
<Compile Include="Transformers2_Launcher.cs" />
<Compile Include="Win32API.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<None Include="Resources\DefaultRanking.dat" />
<None Include="Resources\spr_logo.zip" />
<None Include="Resources\spr_menuextras_en.zip" />
<None Include="Resources\spr_menuextras_es.zip" />
<None Include="Resources\spr_menuextras_fr.zip" />
<None Include="Resources\spr_menuextras_it.zip" />
</ItemGroup>
<ItemGroup>
<Content Include="Ypf-Transformers-Transformer.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,241 @@
using System;
using System.Runtime.InteropServices;
namespace Transformers2_Launcher
{
public static class Win32API
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(IntPtr hProcess, UInt32 lpBaseAddress, byte[] lpBuffer, UInt32 dwSize, ref UInt32 lpNumberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, UInt32 lpBaseAddress, byte[] lpBuffer, UInt32 dwSize, ref UInt32 lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, UInt32 dwSize, MemoryAllocType flAllocationType, MemoryPageProtect flProtect);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl);
}
public static class Win32Define
{
//Mouse and Keyboard Hook
public const int WH_MOUSE_LL = 14;
public const int WH_KEYBOARD_LL = 13;
//Windows messages
public const UInt32 WM_COPYDATA = 0x004A;
public const UInt32 WM_KEYDOWN = 0x0100;
public const UInt32 WM_KEYUP = 0x0101;
public const UInt32 WM_MOUSEMOVE = 0x0200;
public const UInt32 WM_LBUTTONDOWN = 0x0201;
public const UInt32 WM_LBUTTONUP = 0x0202;
public const UInt32 WM_INPUT = 0x00FF;
public const UInt32 WM_RBUTTONDOWN = 0x0204;
public const UInt32 WM_RBUTTONUP = 0x0205;
public const UInt32 WM_MBUTTONDOWN = 0x0207;
public const UInt32 WM_MBUTTONUP = 0x0208;
public const UInt32 WM_MOUSEWHEEL = 0x020A;
public const UInt32 WM_SYSKEYDOWN = 0x0104;
public const uint MAPVK_VK_TO_VSC = 0x00;
public const uint MAPVK_VSC_TO_VK = 0x01;
public const uint MAPVK_VK_TO_CHAR = 0x02;
public const uint MAPVK_VSC_TO_VK_EX = 0x03;
public const uint MAPVK_VK_TO_VSC_EX = 0x04;
}
[Flags]
public enum MemoryAllocType
{
MEM_COMMIT = 0x1000,
MEM_RESERVE = 0x2000,
MEM_RESET = 0x8000,
MEM_RESET_UNDO = 0x1000000,
}
[Flags]
public enum MemoryPageProtect
{
PAGE_EXECUTE = 0x10,
PAGE_EXECUTE_READ = 0x20,
PAGE_EXECUTE_READWRITE = 0x40,
PAGE_EXECUTE_WRITECOPY = 0x80,
PAGE_NOACCESS = 0x01,
PAGE_READONLY = 0x02,
PAGE_READWRITE = 0x04,
PAGE_WRITECOPY = 0x08,
PAGE_TARGETS_INVALID = 0x40000000,
PAGE_TARGETS_NO_UPDATE = 0x40000000
}
public enum HardwareScanCode : byte
{
DIK_ESCAPE = 0x01,
DIK_1 = 0x02,
DIK_2 = 0x03,
DIK_3 = 0x04,
DIK_4 = 0x05,
DIK_5 = 0x06,
DIK_6 = 0x07,
DIK_7 = 0x08,
DIK_8 = 0x09,
DIK_9 = 0x0A,
DIK_0 = 0x0B,
DIK_MINUS = 0x0C,
DIK_EQUALS = 0x0D,
DIK_BACK = 0x0E,
DIK_TAB = 0x0F,
DIK_Q = 0x10,
DIK_W = 0x11,
DIK_E = 0x12,
DIK_R = 0x13,
DIK_T = 0x14,
DIK_Y = 0x15,
DIK_U = 0x16,
DIK_I = 0x17,
DIK_O = 0x18,
DIK_P = 0x19,
DIK_LBRACKET = 0x1A,
DIK_RBRACKET = 0x1B,
DIK_RETURN = 0x1C,
DIK_LCONTROL = 0x1D,
DIK_A = 0x1E,
DIK_S = 0x1F,
DIK_D = 0x20,
DIK_F = 0x21,
DIK_G = 0x22,
DIK_H = 0x23,
DIK_J = 0x24,
DIK_K = 0x25,
DIK_L = 0x26,
DIK_SEMICOLON = 0x27,
DIK_APOSTROPHE = 0x28,
DIK_GRAVE = 0x29,
DIK_LSHIFT = 0x2A,
DIK_BACKSLASH = 0x2B,
DIK_Z = 0x2C,
DIK_X = 0x2D,
DIK_C = 0x2E,
DIK_V = 0x2F,
DIK_B = 0x30,
DIK_N = 0x31,
DIK_M = 0x32,
DIK_COMMA = 0x33,
DIK_PERIOD = 0x34,
DIK_SLASH = 0x35,
DIK_RSHIFT = 0x36,
DIK_MULTIPLY = 0x37,
DIK_LMENU = 0x38,
DIK_SPACE = 0x39,
DIK_CAPITAL = 0x3A,
DIK_F1 = 0x3B,
DIK_F2 = 0x3C,
DIK_F3 = 0x3D,
DIK_F4 = 0x3E,
DIK_F5 = 0x3F,
DIK_F6 = 0x40,
DIK_F7 = 0x41,
DIK_F8 = 0x42,
DIK_F9 = 0x43,
DIK_F10 = 0x44,
DIK_NUMLOCK = 0x45,
DIK_SCROLL = 0x46,
DIK_NUMPAD7 = 0x47,
DIK_NUMPAD8 = 0x48,
DIK_NUMPAD9 = 0x49,
DIK_SUBTRACT = 0x4A,
DIK_NUMPAD4 = 0x4B,
DIK_NUMPAD5 = 0x4C,
DIK_NUMPAD6 = 0x4D,
DIK_ADD = 0x4E,
DIK_NUMPAD1 = 0x4F,
DIK_NUMPAD2 = 0x50,
DIK_NUMPAD3 = 0x51,
DIK_NUMPAD0 = 0x52,
DIK_DECIMAL = 0x53,
DIK_F11 = 0x57,
DIK_F12 = 0x58,
DIK_F13 = 0x64,
DIK_F14 = 0x65,
DIK_F15 = 0x66,
DIK_KANA = 0x70,
DIK_CONVERT = 0x79,
DIK_NOCONVERT = 0x7B,
DIK_YEN = 0x7D,
DIK_NUMPADEQUALS = 0x8D,
DIK_CIRCUMFLEX = 0x90,
DIK_AT = 0x91,
DIK_COLON = 0x92,
DIK_UNDERLINE = 0x93,
DIK_KANJI = 0x94,
DIK_STOP = 0x95,
DIK_AX = 0x96,
DIK_UNLABELED = 0x97,
DIK_NUMPADENTER = 0x9C,
DIK_RCONTROL = 0x9D,
DIK_NUMPADCOMMA = 0xB3,
DIK_DIVIDE = 0xB5,
DIK_SYSRQ = 0xB7,
DIK_RMENU = 0xB8,
DIK_HOME = 0xC7,
DIK_UP = 0xC8,
DIK_PRIOR = 0xC9,
DIK_LEFT = 0xCB,
DIK_RIGHT = 0xCD,
DIK_END = 0xCF,
DIK_DOWN = 0xD0,
DIK_NEXT = 0xD1,
DIK_INSERT = 0xD2,
DIK_DELETE = 0xD3,
DIK_LWIN = 0xDB,
DIK_RWIN = 0xDC,
DIK_APPS = 0xDD,
}
/// <summary>
/// Contains information about a low-level keyboard input event.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct KBDLLHOOKSTRUCT
{
/// <summary>
/// A virtual-key code. The code must be a value in the range 1 to 254.
/// </summary>
public int vkCode;
/// <summary>
/// A hardware scan code for the key.
/// </summary>
public HardwareScanCode scanCode;
/// <summary>
/// The extended-key flag, event-injected flags, context code, and transition-state flag.
/// </summary>
public int flags;
/// <summary>
/// The time stamp for this message, equivalent to what GetMessageTime would return for this message.
/// </summary>
public int time;
/// <summary>
/// Additional information associated with the message.
/// </summary>
public UIntPtr dwExtraInfo;
public override string ToString()
{
return string.Format("vkCode=0x{0:X}, scanCode=0x{1:X}, flags={2}, time={3}, dwextrainfo={4:X}",
vkCode, scanCode, flags, time, dwExtraInfo);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB