mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-20 07:01:27 +02:00
Installation with Ctrl+I, fixes #77
This commit is contained in:
@@ -8,7 +8,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
#ifdef MACOSX
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WIN
|
#ifdef WIN
|
||||||
|
#include <shlobj.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#include <windows.h>
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -124,6 +132,185 @@ void Client::Initialise(std::string proxyString)
|
|||||||
versionCheckRequest = http_async_req_start(NULL, SERVER "/Download/Version.json", NULL, 0, 1);
|
versionCheckRequest = http_async_req_start(NULL, SERVER "/Download/Version.json", NULL, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::DoInstallation()
|
||||||
|
{
|
||||||
|
#if defined(WIN)
|
||||||
|
int returnval;
|
||||||
|
LONG rresult;
|
||||||
|
HKEY newkey;
|
||||||
|
char *currentfilename = exe_name();
|
||||||
|
char *iconname = NULL;
|
||||||
|
char *opencommand = NULL;
|
||||||
|
//char AppDataPath[MAX_PATH];
|
||||||
|
char *AppDataPath = NULL;
|
||||||
|
iconname = (char*)malloc(strlen(currentfilename)+6);
|
||||||
|
sprintf(iconname, "%s,-102", currentfilename);
|
||||||
|
|
||||||
|
//Create Roaming application data folder
|
||||||
|
/*if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, AppDataPath)))
|
||||||
|
{
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//AppDataPath = _getcwd(NULL, 0);
|
||||||
|
|
||||||
|
//Move Game executable into application data folder
|
||||||
|
//TODO: Implement
|
||||||
|
|
||||||
|
opencommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath));
|
||||||
|
/*if((strlen(AppDataPath)+strlen(APPDATA_SUBDIR "\\Powder Toy"))<MAX_PATH)
|
||||||
|
{
|
||||||
|
strappend(AppDataPath, APPDATA_SUBDIR);
|
||||||
|
_mkdir(AppDataPath);
|
||||||
|
strappend(AppDataPath, "\\Powder Toy");
|
||||||
|
_mkdir(AppDataPath);
|
||||||
|
} else {
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}*/
|
||||||
|
sprintf(opencommand, "\"%s\" open \"%%1\" ddir \"%s\"", currentfilename, AppDataPath);
|
||||||
|
|
||||||
|
//Create extension entry
|
||||||
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.cps", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
|
||||||
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.stm", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
|
||||||
|
//Create program entry
|
||||||
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"Powder Toy Save", strlen("Powder Toy Save")+1);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
|
||||||
|
//Set DefaultIcon
|
||||||
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\DefaultIcon", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)iconname, strlen(iconname)+1);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
|
||||||
|
//Set Launch command
|
||||||
|
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\shell\\open\\command", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)opencommand, strlen(opencommand)+1);
|
||||||
|
if (rresult != ERROR_SUCCESS) {
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
returnval = 0;
|
||||||
|
goto finalise;
|
||||||
|
}
|
||||||
|
RegCloseKey(newkey);
|
||||||
|
|
||||||
|
returnval = 1;
|
||||||
|
finalise:
|
||||||
|
|
||||||
|
if(iconname) free(iconname);
|
||||||
|
if(opencommand) free(opencommand);
|
||||||
|
if(currentfilename) free(currentfilename);
|
||||||
|
|
||||||
|
return returnval;
|
||||||
|
#elif defined(LIN)
|
||||||
|
#include "icondoc.h"
|
||||||
|
|
||||||
|
char *currentfilename = exe_name();
|
||||||
|
FILE *f;
|
||||||
|
char *mimedata =
|
||||||
|
"<?xml version=\"1.0\"?>\n"
|
||||||
|
" <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>\n"
|
||||||
|
" <mime-type type=\"application/vnd.powdertoy.save\">\n"
|
||||||
|
" <comment>Powder Toy save</comment>\n"
|
||||||
|
" <glob pattern=\"*.cps\"/>\n"
|
||||||
|
" <glob pattern=\"*.stm\"/>\n"
|
||||||
|
" </mime-type>\n"
|
||||||
|
"</mime-info>\n";
|
||||||
|
f = fopen("powdertoy-save.xml", "wb");
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
|
fwrite(mimedata, 1, strlen(mimedata), f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
char *desktopfiledata_tmp =
|
||||||
|
"[Desktop Entry]\n"
|
||||||
|
"Type=Application\n"
|
||||||
|
"Name=Powder Toy\n"
|
||||||
|
"Comment=Physics sandbox game\n"
|
||||||
|
"MimeType=application/vnd.powdertoy.save;\n"
|
||||||
|
"NoDisplay=true\n";
|
||||||
|
char *desktopfiledata = (char *)malloc(strlen(desktopfiledata_tmp)+strlen(currentfilename)+100);
|
||||||
|
strcpy(desktopfiledata, desktopfiledata_tmp);
|
||||||
|
strappend(desktopfiledata, "Exec=");
|
||||||
|
strappend(desktopfiledata, currentfilename);
|
||||||
|
strappend(desktopfiledata, " open %f\n");
|
||||||
|
f = fopen("powdertoy-tpt.desktop", "wb");
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
|
fwrite(desktopfiledata, 1, strlen(desktopfiledata), f);
|
||||||
|
fclose(f);
|
||||||
|
system("xdg-mime install powdertoy-save.xml");
|
||||||
|
system("xdg-desktop-menu install powdertoy-tpt.desktop");
|
||||||
|
f = fopen("powdertoy-save-32.png", "wb");
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
|
fwrite(icon_doc_32_png, 1, sizeof(icon_doc_32_png), f);
|
||||||
|
fclose(f);
|
||||||
|
f = fopen("powdertoy-save-16.png", "wb");
|
||||||
|
if (!f)
|
||||||
|
return 0;
|
||||||
|
fwrite(icon_doc_16_png, 1, sizeof(icon_doc_16_png), f);
|
||||||
|
fclose(f);
|
||||||
|
system("xdg-icon-resource install --noupdate --context mimetypes --size 32 powdertoy-save-32.png application-vnd.powdertoy.save");
|
||||||
|
system("xdg-icon-resource install --noupdate --context mimetypes --size 16 powdertoy-save-16.png application-vnd.powdertoy.save");
|
||||||
|
system("xdg-icon-resource forceupdate");
|
||||||
|
system("xdg-mime default powdertoy-tpt.desktop application/vnd.powdertoy.save");
|
||||||
|
unlink("powdertoy-save-32.png");
|
||||||
|
unlink("powdertoy-save-16.png");
|
||||||
|
unlink("powdertoy-save.xml");
|
||||||
|
unlink("powdertoy-tpt.desktop");
|
||||||
|
return true;
|
||||||
|
#elif defined MACOSX
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void Client::SetProxy(std::string proxy)
|
void Client::SetProxy(std::string proxy)
|
||||||
{
|
{
|
||||||
http_done();
|
http_done();
|
||||||
|
@@ -86,6 +86,8 @@ public:
|
|||||||
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::vector<std::string> extensions);
|
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::vector<std::string> extensions);
|
||||||
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::string extension);
|
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::string extension);
|
||||||
|
|
||||||
|
bool DoInstallation();
|
||||||
|
|
||||||
std::vector<unsigned char> ReadFile(std::string filename);
|
std::vector<unsigned char> ReadFile(std::string filename);
|
||||||
|
|
||||||
void Initialise(std::string proxyString);
|
void Initialise(std::string proxyString);
|
||||||
|
@@ -46,7 +46,7 @@ ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, ConfirmDial
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ui::Button * cancelButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X-50, 16), "Cancel");
|
ui::Button * cancelButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X-75, 16), "Cancel");
|
||||||
cancelButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
cancelButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
cancelButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
cancelButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||||
cancelButton->Appearance.BorderInactive = ui::Colour(200, 200, 200);
|
cancelButton->Appearance.BorderInactive = ui::Colour(200, 200, 200);
|
||||||
|
61
src/dialogues/InformationMessage.cpp
Normal file
61
src/dialogues/InformationMessage.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* InformationMessage.cpp
|
||||||
|
*
|
||||||
|
* Created on: Jan 29, 2012
|
||||||
|
* Author: Simon
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Style.h"
|
||||||
|
#include "InformationMessage.h"
|
||||||
|
#include "interface/Button.h"
|
||||||
|
#include "interface/Label.h"
|
||||||
|
|
||||||
|
InformationMessage::InformationMessage(std::string title, std::string message):
|
||||||
|
ui::Window(ui::Point(-1, -1), ui::Point(200, 75))
|
||||||
|
{
|
||||||
|
ui::Label * titleLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 16), title);
|
||||||
|
titleLabel->SetTextColour(style::Colour::InformationTitle);
|
||||||
|
titleLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
|
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||||
|
AddComponent(titleLabel);
|
||||||
|
|
||||||
|
ui::Label * messageLabel = new ui::Label(ui::Point(4, 24), ui::Point(Size.X-8, 60), message);
|
||||||
|
messageLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
|
messageLabel->Appearance.VerticalAlign = ui::Appearance::AlignTop;
|
||||||
|
AddComponent(messageLabel);
|
||||||
|
|
||||||
|
class DismissAction: public ui::ButtonAction
|
||||||
|
{
|
||||||
|
InformationMessage * message;
|
||||||
|
public:
|
||||||
|
DismissAction(InformationMessage * message_) { message = message_; }
|
||||||
|
void ActionCallback(ui::Button * sender)
|
||||||
|
{
|
||||||
|
ui::Engine::Ref().CloseWindow();
|
||||||
|
message->SelfDestruct(); //TODO: Fix component disposal
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ui::Button * okayButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), "Dismiss");
|
||||||
|
okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
|
okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||||
|
okayButton->Appearance.BorderInactive = ui::Colour(200, 200, 200);
|
||||||
|
okayButton->SetActionCallback(new DismissAction(this));
|
||||||
|
AddComponent(okayButton);
|
||||||
|
SetOkayButton(okayButton);
|
||||||
|
SetCancelButton(okayButton);
|
||||||
|
|
||||||
|
ui::Engine::Ref().ShowWindow(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InformationMessage::OnDraw()
|
||||||
|
{
|
||||||
|
Graphics * g = ui::Engine::Ref().g;
|
||||||
|
|
||||||
|
g->clearrect(Position.X-2, Position.Y-2, Size.X+4, Size.Y+4);
|
||||||
|
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
InformationMessage::~InformationMessage() {
|
||||||
|
}
|
||||||
|
|
20
src/dialogues/InformationMessage.h
Normal file
20
src/dialogues/InformationMessage.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* InformationMessage.h
|
||||||
|
*
|
||||||
|
* Created on: Jan 29, 2012
|
||||||
|
* Author: Simon
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INFORMATIONMESSAGE_H_
|
||||||
|
#define INFORMATIONMESSAGE_H_
|
||||||
|
|
||||||
|
#include "interface/Window.h"
|
||||||
|
|
||||||
|
class InformationMessage: public ui::Window {
|
||||||
|
public:
|
||||||
|
InformationMessage(std::string title, std::string message);
|
||||||
|
virtual void OnDraw();
|
||||||
|
virtual ~InformationMessage();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* INFORMATIONMESSAGE_H_ */
|
@@ -10,6 +10,7 @@
|
|||||||
#include "login/LoginController.h"
|
#include "login/LoginController.h"
|
||||||
#include "interface/Point.h"
|
#include "interface/Point.h"
|
||||||
#include "dialogues/ErrorMessage.h"
|
#include "dialogues/ErrorMessage.h"
|
||||||
|
#include "dialogues/InformationMessage.h"
|
||||||
#include "dialogues/ConfirmPrompt.h"
|
#include "dialogues/ConfirmPrompt.h"
|
||||||
#include "GameModelException.h"
|
#include "GameModelException.h"
|
||||||
#include "simulation/Air.h"
|
#include "simulation/Air.h"
|
||||||
@@ -172,6 +173,36 @@ void GameController::PlaceSave(ui::Point position)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameController::Install()
|
||||||
|
{
|
||||||
|
#if defined(MACOSX)
|
||||||
|
new InformationMessage("No Installation necessary", "You don't need to install The Powder Toy on Mac OS X");
|
||||||
|
#elif defined(WIN) || defined(LIN)
|
||||||
|
class InstallConfirmation: public ConfirmDialogueCallback {
|
||||||
|
public:
|
||||||
|
GameController * c;
|
||||||
|
InstallConfirmation(GameController * c_) { c = c_; }
|
||||||
|
virtual void ConfirmCallback(ConfirmPrompt::DialogueResult result) {
|
||||||
|
if (result == ConfirmPrompt::ResultOkay)
|
||||||
|
{
|
||||||
|
if(Client::Ref().DoInstallation())
|
||||||
|
{
|
||||||
|
new InformationMessage("Install Success", "The installation completed without error");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new ErrorMessage("Could not install", "The installation did not complete due to an error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual ~InstallConfirmation() { }
|
||||||
|
};
|
||||||
|
new ConfirmPrompt("Install The Powder Toy", "You are about to install The Powder Toy onto this computer", new InstallConfirmation(this));
|
||||||
|
#else
|
||||||
|
new ErrorMessage("Cannot install", "You cannot install The Powder Toy on this platform");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void GameController::AdjustBrushSize(int direction, bool logarithmic, bool xAxis, bool yAxis)
|
void GameController::AdjustBrushSize(int direction, bool logarithmic, bool xAxis, bool yAxis)
|
||||||
{
|
{
|
||||||
if(xAxis && yAxis)
|
if(xAxis && yAxis)
|
||||||
|
@@ -63,6 +63,8 @@ public:
|
|||||||
void Tick();
|
void Tick();
|
||||||
void Exit();
|
void Exit();
|
||||||
|
|
||||||
|
void Install();
|
||||||
|
|
||||||
void LoadRenderPreset(RenderPreset preset);
|
void LoadRenderPreset(RenderPreset preset);
|
||||||
void SetZoomEnabled(bool zoomEnable);
|
void SetZoomEnabled(bool zoomEnable);
|
||||||
void SetZoomPosition(ui::Point position);
|
void SetZoomPosition(ui::Point position);
|
||||||
|
@@ -1267,6 +1267,10 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool
|
|||||||
case '[':
|
case '[':
|
||||||
c->AdjustBrushSize(-1, !alt, shiftBehaviour, ctrlBehaviour);
|
c->AdjustBrushSize(-1, !alt, shiftBehaviour, ctrlBehaviour);
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
if(ctrl)
|
||||||
|
c->Install();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key >= '0' && key <= '9')
|
if(key >= '0' && key <= '9')
|
||||||
|
Reference in New Issue
Block a user