|
DevelopersGuide2
Welcome to GameAnywhere. GameAnywhere is a file synchronization software that enables gamers to bypass the hassle on reconfiguring game settings and easily have their saved game data with them anywhere, anytime.
Getting StartedIn this section, we would introduce the basic features of GameAnywhere and what you will need to develop GameAnywhere. Software Requirements
Features of GameAnywhere
Screenshots
Software ArchitectureIn this section, we will give you a high level overview of the components in GameAnywhere.
This diagram depicts what happens in the program. The Controller is declared and the Controller starts up the GUI. The GUI interacts with the user. In a typical synchronization scenario, the user indicates the direction of the synchronization first. The GUI will request information regarding the games from Controller, which in turn calls GameLibrary for the information to return to GUI. After the user selects the games to synchronize, GUI will then create a list of SyncAction with the games' information and send it to Controller for synchronization. Controller will then provide the information to the relevant sync class to process. Software Data StructureThis section describes the various classes that were used to store information. GameGame is a class that stores the necessary information regarding a Game, i.e. game file path, install path, game name. SyncErrorSyncError stores the information for an synchronization error. It would contain the unsuccessful sync file/folder path, the process that encountered this error and lastly, the error message. SyncActionSyncAction contains the necessary information to sync a game. A Game object and a list of SyncError are wrapped in a SyncAction object. The unsuccessfully synced files will be related to the Game object. Initially, it contains an empty list of SyncError when it is created by the GUI. SyncAction also contain the sync action, which indicates what type of game files to be synced. There are basically two types of games files, saved games files and game configuration files. User can choose to sync either one or both. Class SummaryGameLibrary ClassThe GameLibrary class, contains all the methods and information to initialize installed games into a list of games, that will contain all the appropriate paths to the config files and saved game files of each individual game. It will also resolve and return the common set of games that are found in both the source and target paths according to the synchronization direction chosen by the user, through the method GetGameList(direction). The direction of synchronization must be properly defined with this method. Sync ClassThis parent class contains the general methods to backup and restore the computer to original game state. OfflineSync ClassOfflineSync Class inherits from Sync Class. This class contains the algorithm to handle the synchronization between computer and thumb drive. The sync direction determine how the game files are transferred. OnlineSync ClassSimilar to OfflineSync Class, OnlineSync Class inherit from Sync Class. OnlineSync Class contains the algorithm to handle the synchronization between computer and a GameAnywhere Online Account. WebAndThumb ClassThis class handles contains the algorithm to handle the synchronization between thumb drive and a GameAnywhere Online Account. WebCommsThis class contains the methods and information needed to connect and communicate with the a GameAnywhere Online Account. Game Files Storage StructureIn GameAnywhere, we are concerned with the two types of game files. They are Configuration files and Saved Game files. Games files on the computer are detected automatically (see Games Detection). This is how game files are stored on the external device: A general structure looks like this:
Example:
Use camel case for sub-folder names i.e. "savedGame". SyncFolderGameAnywhere would create a folder to store all the games files that you would want to save. This folder is called SyncFolder. It would be located at the same directory as GameAnywhere.exe. The subfolders in SyncFolder are the game folder(s). Each of the game folder is named after a game. Configuration and Saved game files are stored in their respective folder under a game folder. Adding GamesTo edit the supported games in GameAnywhere, simply edit the userGames.txt file located in the same directory as GameAnywhere.exe. Variables Needed to Add GameCritical game information
Paths for files
Reserved Words/Variables that can be used in the paths for files
Syntax Rules
#This is a line of comments. SearchSaveParent = A.*, B.* Possible Result: "A.boa", "B.ho", "B.man" * is a wildcard that will match any character(s). It will search in the SaveParentPath for all possible files. Then these will be added into the saved game list. An alternative way albeit slower is to add the full paths of these files into SavePathList separated by comma. userGames.txt ExampleGame=FIFA 10 RegValue=Install Dir RegKey=RegistrySoftwarePath\EA Sports\FIFA 10 RegType=HKLM ConfigPathList=DocumentsPath\FIFA 10\user ConfigParentPath=DocumentsPath\FIFA 10 SaveParentPath=DocumentsPath\FIFA 10 SearchSaveParent=A. *,B. *,C. *,D. *,I. *,J. * [ENDGAME] Game=Dragon Age Origins RegValue=Path RegKey=RegistrySoftwarePath\BioWare\Dragon Age RegType=HKLM ConfigPathList=DocumentsPath\BioWare\Dragon Age\Settings ConfigParentPath=DocumentsPath\BioWare\Dragon Age SavePathList=DocumentsPath\BioWare\Dragon Age\Characters SaveParentPath=DocumentsPath\BioWare\Dragon Age [ENDGAME] Game=Batman Arkham Asylum RegValue=Install Directory RegKey=RegistrySoftwarePath\RocksteadyLtd\Batman Arkham Asylum RegType=HKLM ConfigPathList=DocumentsPath\Eidos\Batman Arkham Asylum\BmGame\Config\UserInput.ini,DocumentsPath\Eidos\Batman Arkham Asylum\BmGame\Config\UserGame.ini ConfigParentPath=DocumentsPath\Eidos\Batman Arkham Asylum\BmGame\Config SavePathList=DocumentsPath\Eidos\Batman Arkham Asylum\SaveData SaveParentPath=DocumentsPath\Eidos\Batman Arkham Asylum [ENDGAME] Offline SynchronizationOffline synchronization includes synchronizing between the computer and the SyncFolder. SyncFolder is located on an thumb drive.
Synchronizing Thumb Drive to Computer
Steps for synchronizing from Thumb Drive to Computer:
Synchronizing Computer to Thumb Drive
Steps for synchronizing from Computer to Thumb Drive:
Restore Computer to Original Game State
Steps for restore:
Online SynchronizationSynchronizing Computer to GameAnywhere Online Account
This is a one way synchronization from PC to GameAnywhere Online account. Here is how it works:
Synchronizing GameAnywhere Online Account to Computer
Steps for synchronizing from GameAnywhere Online Account to Computer:
Thumb Drive and Web Synchronization
Web and Thumb Drive Synchronization is a two-way file-level synchronization operation. The aim of this operation is to ensure that the game files stored on the web are the same as the game files stored on the thumb drive. The files on both sides will be checked and compared against a metadata file that is stored on the thumb drive and the user would then be asked to resolve any outstanding conflicts that cannot be automatically be resolved. Metadata fileThe MetaData object stores the the path of the files as well as the checksum of each file in the SyncFolder. We have used a Dictionary of strings to store them. This MetaData object is then output as a serialized metadata file. There will only be one metadata file being stored in the thumb drive (metadata.ga). This file would only be created if a user selects Thumb drive and Web sync. Here is the format of how the contents of the metadata is stored:
Synchronization Algorithm / Conflict ResolutionSince the metadata file stores the state of the previous successful synchronization, it can be used to compare if the files have been change, deleted or newly created. Metadata and SyncingWhen The WebAndThumbSync object is instantiated, it will:
Checking ConflictsThe CheckConflicts() method is called to check for conflicts, which either can automatically be resolved, or requires the user resolution. Conflicts are checked by comparing the three MetaData objects created, iterating through each entry of the FileTable data member. Scenario: No ConflictAutomatic Conflict Resolution
Scenario: Conflict(s)Manual Conflict Resolution by User
Conflicts and GUI
GameAnywhere Online AccountOverviewTo provide users with their own GameAnywhere web account, we need a database to store user account information and Amazon Web Services(AWS) SimpleDB was chosen. Furthermore, by allowing users to synchronize their game data to the web, we need to provide them with a web storage. Thus we would be using AWS Simple Storage Service (S3). For more information about the benefits using AWS, please visit http://aws.amazon.com/. Here we will share with you how authentication is done for a user to login. AuthenticationHow the Components Interact
User The User component consists of user related functions such as Login, Register, ChangePassword, Logout, etc. It is an abstraction of what a user can do. Behind each function, it actually interacts with the database on the cloud(AWS SimpleDB) to retrieve, create and update information. As such, we have a specialized component called SimpleDB, which we will discuss further. SimpleDB In AWS SimpleDB, a table is called a domain while rows are identified as items, and columns are attributes. The primary key to distinguish a unique row is known as the item name. So here is an overview of the SimpleDB component, it is meant for communicating with AWS SimpleDB and it provides database functions like:
This component is dependent on the AmazonSimpleDBClient, which is part of the .NET AWS SDK provided by Amazon. AmazonSimpleDBClient The AmazonSimpleDBClient component is a wrapper class. It mainly deals with amazon SimpleDB web service directly by sending requests and receiving responses from it. By using the AWS SDK for .NET, it hides all the low level amazon webservices programming like authentication and error handling which are actually SOAP/REST calls. You may download the latest Amazon Web Services SDK for .NET from http://aws.amazon.com/sdkfornet/. Database StructureThe domain we have created and will be using is called “UserAccounts”. Each item/row in the database has the following attributes: ItemName, Password, ActivationStatus, ActivationKey. The ItemName acts like a primary key, there should be no duplicates in the domain. And every attribute value is of string datatype as it is a limitation of AWS SimpleDB. Below shows the structure of the “UserAccounts” domain:
Password SecurityIn order to ensure optimum security of users password, all passwords are encrypted in our database. This is secure because even us admins do not know your password as it is not even readable from the database. MD5 is a one way encryption that we have used. It will always return the same hash value for the same given input. The way we store your passwords is to MD5 hash your username together with your password. This is a method known as Salted MD5, it ensures that no two users will have the same MD5 hashed passwords even if they have similar passwords. For more information about MD5, please visit http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx. You can find the CreateMD5Hash method being used very frequently in the User component for processes such as the Login and Registration. RegistrationTo register for an account we need the following details:
Before adding a user into the database, it first ensures that the user account does not exist in our database. Here are the steps for inserting a user to the database: if (!UserExists(email))
{
//Registration complete
string activationKey = CreateMD5Hash(email.Substring(email.Length / 2) + password);
string md5Password = CreateMD5Hash(email + password);
//Insert user info into DB
db.InsertItem(email, md5Password, activationKey);
SendActivationEmail(email, password, activationKey))
}
In order to reduce the number of spam users, all accounts registered with us would require to be activatd by clicking on the link provided in our email after registration. Lets take a look at how it is done:
LoginLogin requires a username and password from the user. Here are the steps to login a user: if (UserExists(email) && IsAccountActivated(email))
{
string userPassword = db.GetAttribute(email, "Password");
string md5Password = CreateMD5Hash(email + password);
if (userPassword.Equals(md5Password))
{
this.email = email;
this.password = password;
this.state = UserState.UserLoggedIn;
return true;
}
}
Password RetrievalThe password retrieval system does not actually send a user back his original password but rather it sends the user an email to reset his password. The reason is because the passwords in the database are encrypted, thus we are unable to recover a user’s password using the username. Here is how the resetting of password works: if (UserExists(email))
{
if (IsAccountActivated(email))
{
//Retrieve complete
string password = db.GetAttribute(email, "Password");
string resetKey = CreateMD5Hash(email + password);
//Insert new attribute to item DB
db.AddAttributeValue(email, "ResetKey", resetKey);
SendPasswordEmail(email, resetKey))
}
}
When the user receives the Reset password email, he may choose to ignore it. However, in order for the user to reset his password, here is how it is done:
Change PasswordTo change a user’s password, it requires the user to provide the username, current password and new password. Here is how the password can be changed: if (UserExists(email) && IsAccountActivated(email))
{
string userPassword = db.GetAttribute(email, "Password");
string md5OldPassword = CreateMD5Hash(email + oldPassword);
//Check if current password matches in DB
if (userPassword.Equals(md5OldPassword))
{
//Change to new password and update item in DB
string md5NewPassword = CreateMD5Hash(email + newPassword);
db.UpdateAttributeValue(email, "Password", md5NewPassword);
}
}
Resend Activation EmailAt times, users might have our activation email in their spam folders or GameAnywhere fails to deliver the email. Thus, a ResendActivation method which takes in the username and password is needed. In order to reduce spams, we disallow malicious users to enter usernames of unactivated accounts by enforcing a password to be entered as well. Below is how ResendActivation method works: if (UserExists(email))
{
if (!IsAccountActivated(email))
{
string password = db.GetAttribute(email, "Password");
string md5InputPassword = CreateMD5Hash(email + inputPassword);
string activationKey = CreateMD5Hash(email.Substring(email.Length / 2) + inputPassword);
if (md5InputPassword.Equals(password))
SendActivationEmail(email, inputPassword, activationKey))
}
}
API ReferenceClick here for GameAnywhere API. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||