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