1 // Common includes
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "Kbhit.h"
5 #include "RakNetworkFactory.h"
6 #include "GetTime.h"
7 #include "RakPeerInterface.h"
8 #include "MessageIdentifiers.h"
9 #include "BitStream.h"
10 #include "StringCompressor.h"
11 #include "PacketizedTCP.h"
12 
13 // Client only includes
14 #include "FileListTransferCBInterface.h"
15 #include "FileListTransfer.h"
16 #include "AutopatcherClient.h"
17 #include "AutopatcherPatchContext.h"
18 #include "RakSleep.h"
19 
20 #include "AutopatcherClientGFx3Impl.h"
21 
22 
23 static const char *AUTOPATCHER_LAST_UPDATE_FILE="autopatcherLastUpdate.txt";
24 static const char *AUTOPATCHER_RESTART_FILE="autopatcherRestart.txt";
25 
26 class TestCB : public FileListTransferCBInterface
27 {
28 public:
OnFile(OnFileStruct * onFileStruct)29 	virtual bool OnFile(OnFileStruct *onFileStruct)
30 	{
31 		char buff[1024];
32 
33 		if (onFileStruct->context.op==PC_HASH_WITH_PATCH)
34 			strcpy(buff,"Patched: ");
35 		else if (onFileStruct->context.op==PC_WRITE_FILE)
36 			strcpy(buff,"Written: ");
37 		else if (onFileStruct->context.op==PC_ERROR_FILE_WRITE_FAILURE)
38 			strcpy(buff,"Write Failure: ");
39 		else if (onFileStruct->context.op==PC_ERROR_PATCH_TARGET_MISSING)
40 			strcpy(buff,"Patch target missing: ");
41 		else if (onFileStruct->context.op==PC_ERROR_PATCH_APPLICATION_FAILURE)
42 			strcpy(buff,"Patch process failure: ");
43 		else if (onFileStruct->context.op==PC_ERROR_PATCH_RESULT_CHECKSUM_FAILURE)
44 			strcpy(buff,"Patch checksum failure: ");
45 		else if (onFileStruct->context.op==PC_NOTICE_WILL_COPY_ON_RESTART)
46 			strcpy(buff,"Copy pending restart: ");
47 		else if (onFileStruct->context.op==PC_NOTICE_FILE_DOWNLOADED)
48 			strcpy(buff,"Downloaded: ");
49 		else if (onFileStruct->context.op==PC_NOTICE_FILE_DOWNLOADED_PATCH)
50 			strcpy(buff,"Downloaded Patch: ");
51 		else
52 			RakAssert(0);
53 
54 
55 		sprintf(buff+strlen(buff), "%i. (100%%) %i/%i %s %ib / %ib\n", onFileStruct->setID, onFileStruct->fileIndex+1, onFileStruct->numberOfFilesInThisSet,
56 			onFileStruct->fileName, onFileStruct->byteLengthOfThisFile,
57 			 onFileStruct->byteLengthOfThisSet);
58 
59 		FxResponseArgs<1> args;
60 		args.Add(GFxValue(buff));
61 		FxDelegate::Invoke(autopatcherClient->movie, "addToPatchNotesText", args);
62 
63 		FxResponseArgs<5> args2;
64 		args2.Add(GFxValue(buff));
65 		args2.Add(GFxValue(1.0));
66 		args2.Add(GFxValue(1.0));
67 		args2.Add(GFxValue((double)onFileStruct->bytesDownloadedForThisSet));
68 		args2.Add(GFxValue((double)onFileStruct->byteLengthOfThisSet));
69 		FxDelegate::Invoke(autopatcherClient->movie, "updateProgressBars", args2);
70 
71 		// Return false for the file data to be deallocated automatically
72 		return false;
73 	}
74 
OnFileProgress(FileProgressStruct * fps)75 	virtual void OnFileProgress(FileProgressStruct *fps)
76 	{
77 		char buff[1024];
78 		sprintf(buff, "%s %ib / %ib\n", fps->onFileStruct->fileName,
79 			fps->onFileStruct->bytesDownloadedForThisFile, fps->onFileStruct->byteLengthOfThisFile);
80 
81 		FxResponseArgs<5> args2;
82 		float thisFileProgress,totalProgress;
83 		thisFileProgress=(float)fps->partCount/(float)fps->partTotal;
84 		totalProgress=(float)(fps->onFileStruct->fileIndex+1)/(float)fps->onFileStruct->numberOfFilesInThisSet;
85 		args2.Add(GFxValue(buff));
86 		args2.Add(GFxValue((double)fps->onFileStruct->bytesDownloadedForThisFile));
87 		args2.Add(GFxValue((double)fps->onFileStruct->byteLengthOfThisFile));
88 		args2.Add(GFxValue((double)fps->onFileStruct->bytesDownloadedForThisSet));
89 		args2.Add(GFxValue((double)fps->onFileStruct->byteLengthOfThisSet));
90 		FxDelegate::Invoke(autopatcherClient->movie, "updateProgressBars", args2);
91 	}
92 
93 	AutopatcherClientGFx3Impl *autopatcherClient;
94 
95 } transferCallback;
96 
AutopatcherClientGFx3Impl()97 AutopatcherClientGFx3Impl::AutopatcherClientGFx3Impl()
98 {
99 	autopatcherClient=0;
100 	fileListTransfer=0;
101 	packetizedTCP=0;
102 }
~AutopatcherClientGFx3Impl()103 AutopatcherClientGFx3Impl::~AutopatcherClientGFx3Impl()
104 {
105 	Shutdown();
106 }
Init(const char * _pathToThisExe,GPtr<FxDelegate> pDelegate,GPtr<GFxMovieView> pMovie)107 void AutopatcherClientGFx3Impl::Init(const char *_pathToThisExe, GPtr<FxDelegate> pDelegate, GPtr<GFxMovieView> pMovie)
108 {
109 	pDelegate->RegisterHandler(this);
110 	delegate=pDelegate;
111 	movie=pMovie;
112 	strcpy(pathToThisExe,_pathToThisExe);
113 
114 	autopatcherClient=RakNet::OP_NEW<AutopatcherClient>(__FILE__,__LINE__);
115 	fileListTransfer=RakNet::OP_NEW<FileListTransfer>(__FILE__,__LINE__);
116 	packetizedTCP=RakNet::OP_NEW<PacketizedTCP>(__FILE__,__LINE__);
117 	autopatcherClient->SetFileListTransferPlugin(fileListTransfer);
118 
119 	packetizedTCP->AttachPlugin(autopatcherClient);
120 	packetizedTCP->AttachPlugin(fileListTransfer);
121 
122 }
Update(void)123 void AutopatcherClientGFx3Impl::Update(void)
124 {
125 	Packet *p;
126 
127 	SystemAddress notificationAddress;
128 	notificationAddress=packetizedTCP->HasCompletedConnectionAttempt();
129 	if (notificationAddress!=UNASSIGNED_SYSTEM_ADDRESS)
130 	{
131 		UpdateConnectResult(true);
132 		serverAddress=notificationAddress;
133 	}
134 	notificationAddress=packetizedTCP->HasFailedConnectionAttempt();
135 	if (notificationAddress!=UNASSIGNED_SYSTEM_ADDRESS)
136 	{
137 		UpdateConnectResult(false);
138 	}
139 	notificationAddress=packetizedTCP->HasNewIncomingConnection();
140 	notificationAddress=packetizedTCP->HasLostConnection();
141 	if (notificationAddress!=UNASSIGNED_SYSTEM_ADDRESS)
142 	{
143 		UpdateConnectResult(false);
144 	}
145 
146 	p=packetizedTCP->Receive();
147 	while (p)
148 	{
149 		if (p->data[0]==ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR)
150 		{
151 			char buff[256];
152 			RakNet::BitStream temp(p->data, p->length, false);
153 			temp.IgnoreBits(8);
154 			stringCompressor->DecodeString(buff, 256, &temp);
155 
156 			// Error.
157 			FxDelegate::Invoke(movie, "gotoCompletionMenu", FxResponseArgs<0>());
158 
159 			FxResponseArgs<1> args2;
160 			args2.Add(GFxValue(buff));
161 			FxDelegate::Invoke(movie, "setCompletionMessage", args2);
162 		}
163 		else if (p->data[0]==ID_AUTOPATCHER_FINISHED)
164 		{
165 			FxDelegate::Invoke(movie, "gotoCompletionMenu", FxResponseArgs<0>());
166 
167 			SaveLastUpdateDate();
168 		}
169 		else if (p->data[0]==ID_AUTOPATCHER_RESTART_APPLICATION)
170 		{
171 			FxDelegate::Invoke(movie, "gotoCompletionMenu", FxResponseArgs<0>());
172 
173 			FxResponseArgs<1> args2;
174 			RakNet::RakString completionMsg("Launch \"AutopatcherClientRestarter.exe %s\"\nQuit this application immediately after to unlock files.\n", AUTOPATCHER_RESTART_FILE);
175 			args2.Add(GFxValue(completionMsg.C_String()));
176 			FxDelegate::Invoke(movie, "setCompletionMessage", args2);
177 
178 			SaveLastUpdateDate();
179 		}
180 
181 		packetizedTCP->DeallocatePacket(p);
182 		p=packetizedTCP->Receive();
183 	}
184 }
Shutdown(void)185 void AutopatcherClientGFx3Impl::Shutdown(void)
186 {
187 	if (delegate.GetPtr()!=0)
188 	{
189 		delegate->UnregisterHandler(this);
190 		delegate.Clear();
191 	}
192 	movie.Clear();
193 	if (packetizedTCP)
194 		packetizedTCP->Stop();
195 	RakNet::OP_DELETE(autopatcherClient,__FILE__,__LINE__);
196 	RakNet::OP_DELETE(fileListTransfer,__FILE__,__LINE__);
197 	RakNet::OP_DELETE(packetizedTCP,__FILE__,__LINE__);
198 	autopatcherClient=0;
199 	fileListTransfer=0;
200 	packetizedTCP=0;
201 }
Connect(const char * ip,unsigned short port)202 const char* AutopatcherClientGFx3Impl::Connect(const char *ip, unsigned short port)
203 {
204 	if (packetizedTCP->Start(0,1)==true)
205 	{
206 		packetizedTCP->Connect(ip,port,false);
207 		return "Connecting";
208 	}
209 	else
210 		return "Start call failed.";
211 }
PressedPatch(const FxDelegateArgs & pparams)212 void AutopatcherClientGFx3Impl::PressedPatch(const FxDelegateArgs& pparams)
213 {
214 	AutopatcherClientGFx3Impl* prt = (AutopatcherClientGFx3Impl*)pparams.GetHandler();
215 	//appNameText.text, appDirectoryText.text, fullRescanBtn.selected
216 	const char *appName = pparams[0].GetString();
217 	const char *appDir = pparams[1].GetString();
218 	bool fullRescan = pparams[2].GetBool();
219 	strcpy(prt->appDirectory, appDir);
220 
221 	char restartFile[512];
222 	strcpy(restartFile, appDir);
223 	strcat(restartFile, "/");
224 	strcat(restartFile, AUTOPATCHER_RESTART_FILE);
225 	char lastUpdateDate[512];
226 	if (fullRescan==false)
227 		prt->LoadLastUpdateDate(lastUpdateDate,appDir);
228 	else
229 		lastUpdateDate[0]=0;
230 
231 	transferCallback.autopatcherClient=prt;
232 	if (prt->autopatcherClient->PatchApplication(appName, appDir, lastUpdateDate, prt->serverAddress, &transferCallback, restartFile, prt->pathToThisExe))
233 	{
234 		FxDelegate::Invoke(prt->movie, "gotoPatchMenu", FxResponseArgs<0>());
235 	}
236 	else
237 	{
238 		prt->packetizedTCP->Stop();
239 		//prt->UpdateConnectResult("Failed to start patching");
240 		FxDelegate::Invoke(prt->movie, "gotoPatchStartMenu", FxResponseArgs<0>());
241 	}
242 }
OpenSite(const FxDelegateArgs & pparams)243 void AutopatcherClientGFx3Impl::OpenSite(const FxDelegateArgs& pparams)
244 {
245 	AutopatcherClientGFx3Impl* prt = (AutopatcherClientGFx3Impl*)pparams.GetHandler();
246 	const char *siteType = pparams[0].GetString();
247 	if (stricmp(siteType, "help")==0)
248 	{
249 		ShellExecute(NULL, "open", "http://www.jenkinssoftware.com/raknet/manual/autopatcher.html",	NULL, NULL, SW_SHOWNORMAL);
250 	}
251 	else if (stricmp(siteType, "raknet")==0)
252 	{
253 		ShellExecute(NULL, "open", "http://www.jenkinssoftware.com/",	NULL, NULL, SW_SHOWNORMAL);
254 	}
255 	else if (stricmp(siteType, "scaleform")==0)
256 	{
257 		ShellExecute(NULL, "open", "https://www.scaleform.com/",	NULL, NULL, SW_SHOWNORMAL);
258 	}
259 }
PressedConnect(const FxDelegateArgs & pparams)260 void AutopatcherClientGFx3Impl::PressedConnect(const FxDelegateArgs& pparams)
261 {
262 	AutopatcherClientGFx3Impl* prt = (AutopatcherClientGFx3Impl*)pparams.GetHandler();
263 	const char *result = prt->Connect(pparams[0].GetString(), atoi(pparams[1].GetString()));
264 }
PressedOKBtn(const FxDelegateArgs & pparams)265 void AutopatcherClientGFx3Impl::PressedOKBtn(const FxDelegateArgs& pparams)
266 {
267 	AutopatcherClientGFx3Impl* prt = (AutopatcherClientGFx3Impl*)pparams.GetHandler();
268 	prt->autopatcherClient->Clear();
269 	prt->packetizedTCP->Stop();
270 
271 	prt->GotoMainMenu();
272 }
UpdateConnectResult(bool isConnected)273 void AutopatcherClientGFx3Impl::UpdateConnectResult( bool isConnected )
274 {
275 	FxResponseArgs<1> args;
276 	args.Add(GFxValue(isConnected));
277 	FxDelegate::Invoke(movie, "ConnectResult", args);
278 }
279 
Accept(CallbackProcessor * cbreg)280 void AutopatcherClientGFx3Impl::Accept(CallbackProcessor* cbreg)
281 {
282 	cbreg->Process( "PressedOKBtn", &AutopatcherClientGFx3Impl::PressedOKBtn );
283 	cbreg->Process( "PressedConnect", &AutopatcherClientGFx3Impl::PressedConnect );
284 	cbreg->Process( "PressedPatch", &AutopatcherClientGFx3Impl::PressedPatch );
285 	cbreg->Process( "openSite", &AutopatcherClientGFx3Impl::OpenSite );
286 }
287 
SaveLastUpdateDate(void)288 void AutopatcherClientGFx3Impl::SaveLastUpdateDate(void)
289 {
290 	char inPath[512];
291 	char *serverDate=autopatcherClient->GetServerDate();
292 	if (serverDate==0 || serverDate[0]==0)
293 		return;
294 	strcpy(inPath, appDirectory);
295 	strcat(inPath, "/");
296 	strcat(inPath, AUTOPATCHER_LAST_UPDATE_FILE);
297 	FILE *fp = fopen(inPath,"wb");
298 	if (fp!=0)
299 	{
300 		fwrite(serverDate,1,512,fp);
301 		fclose(fp);
302 	}
303 }
304 
LoadLastUpdateDate(char * out,const char * appDir)305 void AutopatcherClientGFx3Impl::LoadLastUpdateDate(char *out, const char *appDir)
306 {
307 	strcpy(appDirectory,appDir);
308 	strcpy(out, appDirectory);
309 	strcat(out, "/");
310 	strcat(out, AUTOPATCHER_LAST_UPDATE_FILE);
311 	FILE *fp = fopen(out,"rb");
312 	if (fp!=0)
313 	{
314 		fread(out,1,512,fp);
315 		fclose(fp);
316 	}
317 	else
318 		out[0]=0;
319 }
GotoMainMenu(void)320 void AutopatcherClientGFx3Impl::GotoMainMenu(void)
321 {
322 	FxDelegate::Invoke(movie, "gotoMainMenu", FxResponseArgs<0>());
323 	autopatcherClient->Clear();
324 	packetizedTCP->Stop();
325 }
326