1/*
2 * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#include <framework/core/application.h>
24#include <framework/core/resourcemanager.h>
25#include <framework/core/eventdispatcher.h>
26#include <framework/luaengine/luainterface.h>
27#include <framework/http/http.h>
28#include <framework/platform/crashhandler.h>
29#include <framework/platform/platformwindow.h>
30#include <client/client.h>
31
32int main(int argc, const char* argv[]) {
33 std::vector<std::string> args(argv, argv + argc);
34
35#ifdef CRASH_HANDLER
36 installCrashHandler();
37#endif
38
39 // initialize resources
40 g_resources.init(argv[0]);
41 std::string compactName = g_resources.getCompactName();
42 g_logger.setLogFile(compactName + ".log");
43
44 // setup application name and version
45 g_app.setName("RD Core Client");
46 g_app.setCompactName(compactName);
47 g_app.setVersion("1.0");
48
49#ifdef WITH_ENCRYPTION
50 if (std::find(args.begin(), args.end(), "--encrypt") != args.end()) {
51 g_lua.init();
52 g_resources.encrypt(args.size() >= 3 ? args[2] : "");
53 std::cout << "Encryption complete" << std::endl;
54#ifdef WIN32
55 MessageBoxA(NULL, "Encryption complete", "Success", 0);
56#endif
57 return 0;
58 }
59#endif
60
61 if (g_resources.launchCorrect(g_app.getName(), g_app.getCompactName())) {
62 return 0; // started other executable
63 }
64
65 // initialize application framework and otclient
66 g_app.init(args);
67 g_client.init(args);
68 g_http.init();
69
70 bool testMode = std::find(args.begin(), args.end(), "--test") != args.end();
71 if (testMode) {
72 g_logger.setTestingMode();
73 }
74
75 // find script init.lua and run it
76 g_resources.setupWriteDir(g_app.getName(), g_app.getCompactName());
77 g_resources.setup();
78
79 if (!g_lua.safeRunScript("init.lua")) {
80 if (g_resources.isLoadedFromArchive() && !g_resources.isLoadedFromMemory() &&
81 g_resources.loadDataFromSelf(true)) {
82 g_logger.error("Unable to run script init.lua! Trying to run version from memory.");
83 if (!g_lua.safeRunScript("init.lua")) {
84 g_resources.deleteFile("data.zip"); // remove incorrect data.zip
85 g_logger.fatal("Unable to run script init.lua from binary file!\nTry to run client again.");
86 }
87 } else {
88 g_logger.fatal("Unable to run script init.lua!");
89 }
90 }
91
92 if (testMode) {
93 if (!g_lua.safeRunScript("test.lua")) {
94 g_logger.fatal("Can't run test.lua");
95 }
96 }
97
98#ifdef WIN32
99 // support for progdn proxy system, if you don't have this dll nothing will happen
100 // however, it is highly recommended to use otcv8 proxy system
101 LoadLibraryA("progdn32.dll");
102#endif
103
104 // the run application main loop
105 g_app.run();
106
107#ifdef CRASH_HANDLER
108 uninstallCrashHandler();
109#endif
110
111 // unload modules
112 g_app.deinit();
113
114 // terminate everything and free memory
115 g_http.terminate();
116 g_client.terminate();
117 g_app.terminate();
118 return 0;
119}
120
121#ifdef ANDROID
122#include <framework/platform/androidwindow.h>
123
124android_app* g_androidState = nullptr;
125void android_main(struct android_app* state)
126{
127 g_mainThreadId = g_dispatcherThreadId = g_graphicsThreadId = std::this_thread::get_id();
128 g_androidState = state;
129
130 state->userData = nullptr;
131 state->onAppCmd = +[](android_app* app, int32_t cmd) -> void {
132 return g_androidWindow.handleCmd(cmd);
133 };
134 state->onInputEvent = +[](android_app* app, AInputEvent* event) -> int32_t {
135 return g_androidWindow.handleInput(event);
136 };
137 state->activity->callbacks->onNativeWindowResized = +[](ANativeActivity* activity, ANativeWindow* window) -> void {
138 g_graphicsDispatcher.scheduleEventEx("updateWindowSize", [] {
139 g_androidWindow.updateSize();
140 }, 500);
141 };
142 state->activity->callbacks->onContentRectChanged = +[](ANativeActivity* activity, const ARect* rect) -> void {
143 g_graphicsDispatcher.scheduleEventEx("updateWindowSize", [] {
144 g_androidWindow.updateSize();
145 }, 500);
146 };
147
148 bool terminated = false;
149 g_window.setOnClose([&] {
150 terminated = true;
151 });
152 while(!g_window.isVisible() && !terminated)
153 g_window.poll(); // init window
154 // run app
155 const char* args[] = { "otclientv8.apk" };
156 main(1, args);
157 std::exit(0); // required!
158}
159#endif
160