diff --git a/api/stats.php b/api/stats.php deleted file mode 100644 index 48859a1..0000000 --- a/api/stats.php +++ /dev/null @@ -1,13 +0,0 @@ -uid) { - die(); -} - -if($json->uid) { - file_put_contents("stats/".($json->uid).".log", "\n".$data."\n", FILE_APPEND); -} - -echo "OK"; -?> \ No newline at end of file diff --git a/api/status.php b/api/status.php deleted file mode 100644 index 2b1a20e..0000000 --- a/api/status.php +++ /dev/null @@ -1,26 +0,0 @@ -([0-9]*)<\/strong>/', $site, $matches); - $online_otservlist = $matches[1]; -} catch(Exception $e) {} -$online_discord = 0; -try { - $online_discord = json_decode(file_get_contents("https://discordapp.com/api/guilds/628769144925585428/widget.json"))->presence_count; -} catch(Exception $e) {} - -$response = array( - "online" => "$online_otservlist Players online", - "discord_online" => $online_discord, - "discord_link" => "https://discord.gg/t4ntS5p" -); -echo json_encode($response); -?> \ No newline at end of file diff --git a/api/updater.php b/api/updater.php deleted file mode 100644 index f59e4f3..0000000 --- a/api/updater.php +++ /dev/null @@ -1,69 +0,0 @@ - "otclient_gl.exe", - "WIN32-EGL" => "otclient_dx.exe", - "WIN32-WGL-GCC" => "otclient_gcc_gl.exe", - "WIN32-EGL-GCC" => "otclient_gcc_dx.exe", - "X11-GLX" => "otclient_linux", - "X11-EGL" => "otclient_linux", - "ANDROID-EGL" => "", // we can't update android binary - "ANDROID64-EGL" => "" // we can't update android binary -); -// CONFIG END - -function sendError($error) { - echo(json_encode(array("error" => $error))); - die(); -} - -$data = json_decode(file_get_contents("php://input")); -//if(!$data) { -// sendError("Invalid input data"); -//} - -$version = $data->version ?: 0; // APP_VERSION from init.lua -$build = $data->build ?: ""; // 2.4, 2.4.1, 2.5, etc -$os = $data->os ?: "unknown"; // android, windows, mac, linux, unknown -$platform = $data->platform ?: ""; // WIN32-WGL, X11-GLX, ANDROID-EGL, etc -$args = $data->args; // custom args when calling Updater.check() -$binary = $binaries[$platform] ?: ""; - -$cache = null; -$cache_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $checksum_file; -if (file_exists($cache_file) && (filemtime($cache_file) + $checksum_update_interval > time())) { - $cache = json_decode(file_get_contents($cache_file), true); -} -if(!$cache) { // update cache - $dir = realpath($files_dir); - $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); - $cache = array(); - foreach ($rii as $file) { - if (!$file->isFile()) - continue; - $path = str_replace($dir, '', $file->getPathname()); - $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); - $cache[$path] = hash_file("crc32b", $file->getPathname()); - } - file_put_contents($cache_file . ".tmp", json_encode($cache)); - rename($cache_file . ".tmp", $cache_file); -} -$ret = array("url" => $files_url, "files" => array(), "keepFiles" => false); -foreach($cache as $file => $checksum) { - $base = trim(explode("/", ltrim($file, "/"))[0]); - if(in_array($base, $files_and_dirs)) { - $ret["files"][$file] = $checksum; - } - if($base == $binary && !empty($binary)) { - $ret["binary"] = array("file" => $file, "checksum" => $checksum); - } -} - -echo(json_encode($ret, JSON_PRETTY_PRINT)); - -?> \ No newline at end of file diff --git a/api/updater_advanced.php b/api/updater_advanced.php deleted file mode 100644 index 62a3710..0000000 --- a/api/updater_advanced.php +++ /dev/null @@ -1,77 +0,0 @@ - "otclient_gl.exe", - "WIN32-EGL" => "otclient_dx.exe", - "WIN32-WGL-GCC" => "otclient_gcc_gl.exe", - "WIN32-EGL-GCC" => "otclient_gcc_dx.exe", - "X11-GLX" => "otclient_linux", - "X11-EGL" => "otclient_linux", - "ANDROID-EGL" => "", // we can't update android binary - "ANDROID64-EGL" => "" // we can't update android binary -); -// CONFIG END - -function sendError($error) { - echo(json_encode(array("error" => $error))); - die(); -} - -$data = json_decode(file_get_contents("php://input")); -//if(!$data) { -// sendError("Invalid input data"); -//} - -$version = $data->version ?: 0; // APP_VERSION from init.lua -$build = $data->build ?: ""; // 2.4, 2.4.1, 2.5, etc -$os = $data->os ?: "unknown"; // android, windows, mac, linux, unknown -$platform = $data->platform ?: ""; // WIN32-WGL, X11-GLX, ANDROID-EGL, etc -$args = $data->args; // custom args when calling Updater.check() -$binary = $binaries[$platform] ?: ""; - -$forVersion = ""; -if($args && $args->version) { - $forVersion = strval($args->version); -} - -$cache = null; -$cache_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $checksum_file; -if (file_exists($cache_file) && (filemtime($cache_file) + $checksum_update_interval > time())) { - $cache = json_decode(file_get_contents($cache_file), true); -} -if(!$cache) { // update cache - $dir = realpath($files_dir); - $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)); - $cache = array(); - foreach ($rii as $file) { - if (!$file->isFile()) - continue; - $path = str_replace($dir, '', $file->getPathname()); - $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); - $cache[$path] = hash_file("crc32b", $file->getPathname()); - } - file_put_contents($cache_file . ".tmp", json_encode($cache)); - rename($cache_file . ".tmp", $cache_file); -} -$ret = array("url" => $files_url, "files" => array(), "keepFiles" => empty($forVersion) ? false : true); -foreach($cache as $file => $checksum) { - $base = trim(explode("/", ltrim($file, "/"))[0]); - if(strpos($file, "data/things") !== false && (empty($forVersion) || strpos($file, $forVersion) === false)) { - continue; - } - if(in_array($base, $files_and_dirs)) { - $ret["files"][$file] = $checksum; - } - if($base == $binary && !empty($binary)) { - $ret["binary"] = array("file" => $file, "checksum" => $checksum); - } -} - -echo(json_encode($ret, JSON_PRETTY_PRINT)); - -?> \ No newline at end of file diff --git a/otclient_linux b/otclient_linux deleted file mode 100644 index 9842843..0000000 Binary files a/otclient_linux and /dev/null differ diff --git a/run_android.bat b/run_android.bat deleted file mode 100644 index b407fa1..0000000 --- a/run_android.bat +++ /dev/null @@ -1 +0,0 @@ -adb uninstall com.otclientv8 && adb install otclientv8.apk && adb logcat -c && adb shell am start -n com.otclientv8/com.otclientv8.OTClientV8 && adb logcat | findstr /i otclient \ No newline at end of file diff --git a/server/README.md b/server/README.md deleted file mode 100644 index 378f01c..0000000 --- a/server/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Here are tools for server - -all lua scripts are made for and tested on latest tfs (1.2/1.3) - -add json.lua to data/lib/core and then in core.lua add: dofile('data/lib/core/json.lua') diff --git a/server/json.lua b/server/json.lua deleted file mode 100644 index 22cbb47..0000000 --- a/server/json.lua +++ /dev/null @@ -1,399 +0,0 @@ --- add to lib/core, later add dofile in lib/core/core.lua - --- --- json.lua --- --- Copyright (c) 2018 rxi --- --- Permission is hereby granted, free of charge, to any person obtaining a copy of --- this software and associated documentation files (the "Software"), to deal in --- the Software without restriction, including without limitation the rights to --- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies --- of the Software, and to permit persons to whom the Software is furnished to do --- so, subject to the following conditions: --- --- The above copyright notice and this permission notice shall be included in all --- copies or substantial portions of the Software. --- --- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --- SOFTWARE. --- - -json = { _version = "0.1.1" } - -------------------------------------------------------------------------------- --- Encode -------------------------------------------------------------------------------- - -local encode - -local escape_char_map = { - [ "\\" ] = "\\\\", - [ "\"" ] = "\\\"", - [ "\b" ] = "\\b", - [ "\f" ] = "\\f", - [ "\n" ] = "\\n", - [ "\r" ] = "\\r", - [ "\t" ] = "\\t", -} - -local escape_char_map_inv = { [ "\\/" ] = "/" } -for k, v in pairs(escape_char_map) do - escape_char_map_inv[v] = k -end - - -local function escape_char(c) - return escape_char_map[c] or string.format("\\u%04x", c:byte()) -end - - -local function encode_nil(val) - return "null" -end - - -local function encode_table(val, stack) - local res = {} - stack = stack or {} - - -- Circular reference? - if stack[val] then error("circular reference") end - - stack[val] = true - - if val[1] ~= nil or next(val) == nil then - -- Treat as array -- check keys are valid and it is not sparse - local n = 0 - for k in pairs(val) do - if type(k) ~= "number" then - error("invalid table: mixed or invalid key types") - end - n = n + 1 - end - if n ~= #val then - error("invalid table: sparse array") - end - -- Encode - for i, v in ipairs(val) do - table.insert(res, encode(v, stack)) - end - stack[val] = nil - return "[" .. table.concat(res, ",") .. "]" - - else - -- Treat as an object - for k, v in pairs(val) do - if type(k) ~= "string" then - error("invalid table: mixed or invalid key types") - end - table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) - end - stack[val] = nil - return "{" .. table.concat(res, ",") .. "}" - end -end - - -local function encode_string(val) - return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' -end - - -local function encode_number(val) - -- Check for NaN, -inf and inf - if val ~= val or val <= -math.huge or val >= math.huge then - error("unexpected number value '" .. tostring(val) .. "'") - end - return string.format("%.14g", val) -end - - -local type_func_map = { - [ "nil" ] = encode_nil, - [ "table" ] = encode_table, - [ "string" ] = encode_string, - [ "number" ] = encode_number, - [ "boolean" ] = tostring, -} - - -encode = function(val, stack) - local t = type(val) - local f = type_func_map[t] - if f then - return f(val, stack) - end - error("unexpected type '" .. t .. "'") -end - - -function json.encode(val) - return ( encode(val) ) -end - - -------------------------------------------------------------------------------- --- Decode -------------------------------------------------------------------------------- - -local parse - -local function create_set(...) - local res = {} - for i = 1, select("#", ...) do - res[ select(i, ...) ] = true - end - return res -end - -local space_chars = create_set(" ", "\t", "\r", "\n") -local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") -local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") -local literals = create_set("true", "false", "null") - -local literal_map = { - [ "true" ] = true, - [ "false" ] = false, - [ "null" ] = nil, -} - - -local function next_char(str, idx, set, negate) - for i = idx, #str do - if set[str:sub(i, i)] ~= negate then - return i - end - end - return #str + 1 -end - - -local function decode_error(str, idx, msg) - local line_count = 1 - local col_count = 1 - for i = 1, idx - 1 do - col_count = col_count + 1 - if str:sub(i, i) == "\n" then - line_count = line_count + 1 - col_count = 1 - end - end - error( string.format("%s at line %d col %d", msg, line_count, col_count) ) -end - - -local function codepoint_to_utf8(n) - -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa - local f = math.floor - if n <= 0x7f then - return string.char(n) - elseif n <= 0x7ff then - return string.char(f(n / 64) + 192, n % 64 + 128) - elseif n <= 0xffff then - return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) - elseif n <= 0x10ffff then - return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, - f(n % 4096 / 64) + 128, n % 64 + 128) - end - error( string.format("invalid unicode codepoint '%x'", n) ) -end - - -local function parse_unicode_escape(s) - local n1 = tonumber( s:sub(3, 6), 16 ) - local n2 = tonumber( s:sub(9, 12), 16 ) - -- Surrogate pair? - if n2 then - return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) - else - return codepoint_to_utf8(n1) - end -end - - -local function parse_string(str, i) - local has_unicode_escape = false - local has_surrogate_escape = false - local has_escape = false - local last - for j = i + 1, #str do - local x = str:byte(j) - - if x < 32 then - decode_error(str, j, "control character in string") - end - - if last == 92 then -- "\\" (escape char) - if x == 117 then -- "u" (unicode escape sequence) - local hex = str:sub(j + 1, j + 5) - if not hex:find("%x%x%x%x") then - decode_error(str, j, "invalid unicode escape in string") - end - if hex:find("^[dD][89aAbB]") then - has_surrogate_escape = true - else - has_unicode_escape = true - end - else - local c = string.char(x) - if not escape_chars[c] then - decode_error(str, j, "invalid escape char '" .. c .. "' in string") - end - has_escape = true - end - last = nil - - elseif x == 34 then -- '"' (end of string) - local s = str:sub(i + 1, j - 1) - if has_surrogate_escape then - s = s:gsub("\\u[dD][89aAbB]..\\u....", parse_unicode_escape) - end - if has_unicode_escape then - s = s:gsub("\\u....", parse_unicode_escape) - end - if has_escape then - s = s:gsub("\\.", escape_char_map_inv) - end - return s, j + 1 - - else - last = x - end - end - decode_error(str, i, "expected closing quote for string") -end - - -local function parse_number(str, i) - local x = next_char(str, i, delim_chars) - local s = str:sub(i, x - 1) - local n = tonumber(s) - if not n then - decode_error(str, i, "invalid number '" .. s .. "'") - end - return n, x -end - - -local function parse_literal(str, i) - local x = next_char(str, i, delim_chars) - local word = str:sub(i, x - 1) - if not literals[word] then - decode_error(str, i, "invalid literal '" .. word .. "'") - end - return literal_map[word], x -end - - -local function parse_array(str, i) - local res = {} - local n = 1 - i = i + 1 - while 1 do - local x - i = next_char(str, i, space_chars, true) - -- Empty / end of array? - if str:sub(i, i) == "]" then - i = i + 1 - break - end - -- Read token - x, i = parse(str, i) - res[n] = x - n = n + 1 - -- Next token - i = next_char(str, i, space_chars, true) - local chr = str:sub(i, i) - i = i + 1 - if chr == "]" then break end - if chr ~= "," then decode_error(str, i, "expected ']' or ','") end - end - return res, i -end - - -local function parse_object(str, i) - local res = {} - i = i + 1 - while 1 do - local key, val - i = next_char(str, i, space_chars, true) - -- Empty / end of object? - if str:sub(i, i) == "}" then - i = i + 1 - break - end - -- Read key - if str:sub(i, i) ~= '"' then - decode_error(str, i, "expected string for key") - end - key, i = parse(str, i) - -- Read ':' delimiter - i = next_char(str, i, space_chars, true) - if str:sub(i, i) ~= ":" then - decode_error(str, i, "expected ':' after key") - end - i = next_char(str, i + 1, space_chars, true) - -- Read value - val, i = parse(str, i) - -- Set - res[key] = val - -- Next token - i = next_char(str, i, space_chars, true) - local chr = str:sub(i, i) - i = i + 1 - if chr == "}" then break end - if chr ~= "," then decode_error(str, i, "expected '}' or ','") end - end - return res, i -end - - -local char_func_map = { - [ '"' ] = parse_string, - [ "0" ] = parse_number, - [ "1" ] = parse_number, - [ "2" ] = parse_number, - [ "3" ] = parse_number, - [ "4" ] = parse_number, - [ "5" ] = parse_number, - [ "6" ] = parse_number, - [ "7" ] = parse_number, - [ "8" ] = parse_number, - [ "9" ] = parse_number, - [ "-" ] = parse_number, - [ "t" ] = parse_literal, - [ "f" ] = parse_literal, - [ "n" ] = parse_literal, - [ "[" ] = parse_array, - [ "{" ] = parse_object, -} - - -parse = function(str, idx) - local chr = str:sub(idx, idx) - local f = char_func_map[chr] - if f then - return f(str, idx) - end - decode_error(str, idx, "unexpected character '" .. chr .. "'") -end - - -function json.decode(str) - if type(str) ~= "string" then - error("expected argument of type string, got " .. type(str)) - end - local res, idx = parse(str, next_char(str, 1, space_chars, true)) - idx = next_char(str, idx, space_chars, true) - if idx <= #str then - decode_error(str, idx, "trailing garbage") - end - return res -end diff --git a/server/shop/shop.lua b/server/shop/shop.lua deleted file mode 100644 index ebb9dfb..0000000 --- a/server/shop/shop.lua +++ /dev/null @@ -1,362 +0,0 @@ --- BETA VERSION, net tested yet --- Instruction: --- creaturescripts.xml --- and in login.lua player:registerEvent("Shop") --- create sql table shop_history --- set variables --- set up function init(), add there items and categories, follow examples --- set up callbacks at the bottom to add player item/outfit/whatever you want - -local SHOP_EXTENDED_OPCODE = 201 -local SHOP_OFFERS = {} -local SHOP_CALLBACKS = {} -local SHOP_CATEGORIES = nil -local SHOP_BUY_URL = "http://otland.net" -- can be empty -local SHOP_AD = { -- can be nil - image = "https://s3.envato.com/files/62273611/PNG%20Blue/Banner%20blue%20468x60.png", - url = "http://otclient.ovh", - text = "" -} -local MAX_PACKET_SIZE = 50000 - ---[[ SQL TABLE - -CREATE TABLE `shop_history` ( - `id` int(11) NOT NULL, - `account` int(11) NOT NULL, - `player` int(11) NOT NULL, - `date` datetime NOT NULL, - `title` varchar(100) NOT NULL, - `cost` int(11) NOT NULL, - `details` varchar(500) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - -ALTER TABLE `shop_history` - ADD PRIMARY KEY (`id`); -ALTER TABLE `shop_history` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; - -]]-- - -function init() - -- print(json.encode(g_game.getLocalPlayer():getOutfit())) -- in console in otclient, will print current outfit and mount - - SHOP_CATEGORIES = {} - - local category1 = addCategory({ - type="item", - item=ItemType(2160):getClientId(), - count=100, - name="Items" - }) - local category2 = addCategory({ - type="outfit", - name="Outfits", - outfit={ - mount=0, - feet=114, - legs=114, - body=116, - type=143, - auxType=0, - addons=3, - head=2, - rotating=true - } - }) - local category3 = addCategory({ - type="image", - image="http://otclient.ovh/images/137.png", - name="Category with http image" - }) - local category4 = addCategory({ - type="image", - image="/data/images/game/states/electrified.png", - name="Category with local image" - }) - - - category1.addItem(1, 2160, 1, "1 Crystal coin", "description of cristal coin") - category1.addItem(5, 2160, 5, "5 Crystal coin", "description of cristal coin") - category1.addItem(50, 2160, 50, "50 Crystal coin", "description of cristal coin") - category1.addItem(90, 2160, 100, "100 Crystal coin", "description of cristal coin") - category1.addItem(200, 2493, 1, "Demon helmet1", "woo\ndemon helmet\nnice, you should buy it") - category1.addItem(1, 2160, 1, "1 Crystal coin1", "description of cristal coin") - category1.addItem(5, 2160, 5, "5 Crystal coin1", "description of cristal coin") - category1.addItem(50, 2160, 50, "50 Crystal coin1", "description of cristal coin") - category1.addItem(90, 2160, 100, "100 Crystal coin1", "description of cristal coin") - category1.addItem(200, 2493, 1, "Demon helmet2", "woo\ndemon helmet\nnice, you should buy it") - category1.addItem(1, 2160, 1, "1 Crystal coin3", "description of cristal coin") - category1.addItem(5, 2160, 5, "5 Crystal coin3", "description of cristal coin") - category1.addItem(50, 2160, 50, "50 Crystal coin3", "description of cristal coin") - category1.addItem(90, 2160, 100, "100 Crystal coin3", "description of cristal coin") - category1.addItem(200, 2493, 1, "Demon helmet3", "wooxD\ndemon helmet\nnice, you should buy it") - - category2.addOutfit(500, { - mount=0, - feet=114, - legs=114, - body=116, - type=143, - auxType=0, - addons=3, - head=2, - rotating=true - }, "title of this cool outfit or whatever", "this is your new cool outfit. You can buy it here.\nsrlsy") - category2.addOutfit(100, { - mount=682, - feet=0, - legs=0, - body=0, - type=143, - auxType=0, - addons=0, - head=0, - rotating=true - }, "MOUNT!!!", "DOUBLE CLICK TO BUY THIS MOUNT. IDK NAME") - - category2.addOutfit(100, { - mount=0, - feet=0, - legs=0, - body=0, - type=35, - auxType=0, - addons=0, - head=0, - rotating=true - }, "Demon outfit", "Want be a demon?\nNo problem") - category2.addOutfit(100, { - mount=0, - feet=0, - legs=0, - body=0, - type=35, - auxType=0, - addons=0, - head=0, - rotating=false - }, "Demon outfit2", "This one is not rotating") - - category4.addImage(10000, "/data/images/game/states/haste.png", "Offer with local image", "another local image\n/data/images/game/states/haste.png") - category4.addImage(10000, "http://otclient.ovh/images/freezing.png", "Offer with remote image and custom buy action", "blalasdasd image\nhttp://otclient.ovh/images/freezing.png", customImageBuyAction) -end - -function addCategory(data) - data['offers'] = {} - table.insert(SHOP_CATEGORIES, data) - table.insert(SHOP_CALLBACKS, {}) - local index = #SHOP_CATEGORIES - return { - addItem = function(cost, itemId, count, title, description, callback) - if not callback then - callback = defaultItemBuyAction - end - table.insert(SHOP_CATEGORIES[index]['offers'], { - cost=cost, - type="item", - item=ItemType(itemId):getClientId(), -- displayed - itemId=itemId, - count=count, - title=title, - description=description - }) - table.insert(SHOP_CALLBACKS[index], callback) - end, - addOutfit = function(cost, outfit, title, description, callback) - if not callback then - callback = defaultOutfitBuyAction - end - table.insert(SHOP_CATEGORIES[index]['offers'], { - cost=cost, - type="outfit", - outfit=outfit, - title=title, - description=description - }) - table.insert(SHOP_CALLBACKS[index], callback) - end, - addImage = function(cost, image, title, description, callback) - if not callback then - callback = defaultImageBuyAction - end - table.insert(SHOP_CATEGORIES[index]['offers'], { - cost=cost, - type="image", - image=image, - title=title, - description=description - }) - table.insert(SHOP_CALLBACKS[index], callback) - end - } -end - -function getPoints(player) - local points = 0 - local resultId = db.storeQuery("SELECT `premium_points` FROM `accounts` WHERE `id` = " .. player:getAccountId()) - if resultId ~= false then - points = result.getDataInt(resultId, "premium_points") - result.free(resultId) - end - return points -end - -function getStatus(player) - local status = { - ad = SHOP_AD, - points = getPoints(player), - buyUrl = SHOP_BUY_URL - } - return status -end - -function sendJSON(player, action, data, forceStatus) - local status = nil - if not player:getStorageValue(1150001) or player:getStorageValue(1150001) + 10 < os.time() or forceStatus then - status = getStatus(player) - end - player:setStorageValue(1150001, os.time()) - - - local buffer = json.encode({action = action, data = data, status = status}) - local s = {} - for i=1, #buffer, MAX_PACKET_SIZE do - s[#s+1] = buffer:sub(i,i+MAX_PACKET_SIZE - 1) - end - local msg = NetworkMessage() - if #s == 1 then - msg:addByte(50) - msg:addByte(SHOP_EXTENDED_OPCODE) - msg:addString(s[1]) - msg:sendToPlayer(player) - return - end - -- split message if too big - msg:addByte(50) - msg:addByte(SHOP_EXTENDED_OPCODE) - msg:addString("S" .. s[1]) - msg:sendToPlayer(player) - for i=2,#s - 1 do - msg = NetworkMessage() - msg:addByte(50) - msg:addByte(SHOP_EXTENDED_OPCODE) - msg:addString("P" .. s[i]) - msg:sendToPlayer(player) - end - msg = NetworkMessage() - msg:addByte(50) - msg:addByte(SHOP_EXTENDED_OPCODE) - msg:addString("E" .. s[#s]) - msg:sendToPlayer(player) -end - -function sendMessage(player, title, msg, forceStatus) - sendJSON(player, "message", {title=title, msg=msg}, forceStatus) -end - -function onExtendedOpcode(player, opcode, buffer) - if opcode ~= SHOP_EXTENDED_OPCODE then - return false - end - local status, json_data = pcall(function() return json.decode(buffer) end) - if not status then - return false - end - - local action = json_data['action'] - local data = json_data['data'] - if not action or not data then - return false - end - - if SHOP_CATEGORIES == nil then - init() - end - - if action == 'init' then - sendJSON(player, "categories", SHOP_CATEGORIES) - elseif action == 'buy' then - processBuy(player, data) - elseif action == "history" then - sendHistory(player) - end - return true -end - -function processBuy(player, data) - local categoryId = tonumber(data["category"]) - local offerId = tonumber(data["offer"]) - local offer = SHOP_CATEGORIES[categoryId]['offers'][offerId] - local callback = SHOP_CALLBACKS[categoryId][offerId] - if not offer or not callback or data["title"] ~= offer["title"] or data["cost"] ~= offer["cost"] then - sendJSON(player, "categories", SHOP_CATEGORIES) -- refresh categories, maybe invalid - return sendMessage(player, "Error!", "Invalid offer") - end - local points = getPoints(player) - if not offer['cost'] or offer['cost'] > points or points < 1 then - return sendMessage(player, "Error!", "You don't have enough points to buy " .. offer['title'] .."!", true) - end - local status = callback(player, offer) - if status == true then - db.query("UPDATE `accounts` set `premium_points` = `premium_points` - " .. offer['cost'] .. " WHERE `id` = " .. player:getAccountId()) - db.asyncQuery("INSERT INTO `shop_history` (`account`, `player`, `date`, `title`, `cost`, `details`) VALUES ('" .. player:getAccountId() .. "', '" .. player:getGuid() .. "', NOW(), " .. db.escapeString(offer['title']) .. ", " .. db.escapeString(offer['cost']) .. ", " .. db.escapeString(json.encode(offer)) .. ")") - return sendMessage(player, "Success!", "You bought " .. offer['title'] .."!", true) - end - if status == nil or status == false then - status = "Unknown error while buying " .. offer['title'] - end - sendMessage(player, "Error!", status) -end - -function sendHistory(player) - if player:getStorageValue(1150002) and player:getStorageValue(1150002) + 10 > os.time() then - return -- min 10s delay - end - player:setStorageValue(1150002, os.time()) - - local history = {} - local resultId = db.storeQuery("SELECT * FROM `shop_history` WHERE `account` = " .. player:getAccountId() .. " order by `id` DESC") - - if resultId ~= false then - repeat - local details = result.getDataString(resultId, "details") - local status, json_data = pcall(function() return json.decode(details) end) - if not status then - json_data = { - type = "image", - title = result.getDataString(resultId, "title"), - cost = result.getDataInt(resultId, "cost") - } - end - table.insert(history, json_data) - history[#history]["description"] = "Bought on " .. result.getDataString(resultId, "date") .. " for " .. result.getDataInt(resultId, "cost") .. " points." - until not result.next(resultId) - result.free(resultId) - end - - sendJSON(player, "history", history) -end - --- BUY CALLBACKS --- May be useful: print(json.encode(offer)) - -function defaultItemBuyAction(player, offer) - -- todo: check if has capacity - if player:addItem(offer["itemId"], offer["count"], false) then - return true - end - return "Can't add item! Do you have enough space?" -end - -function defaultOutfitBuyAction(player, offer) - return "default outfit buy action is not implemented" -end - -function defaultImageBuyAction(player, offer) - return "default image buy action is not implemented" -end - -function customImageBuyAction(player, offer) - return "custom image buy action is not implemented. Offer: " .. offer['title'] -end \ No newline at end of file diff --git a/src/README.md b/src/README.md deleted file mode 100644 index 516d531..0000000 --- a/src/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# OTClientV8 partial sources (90% of code) - -To help you understand how OTClientV8 works, some parts of source code has been published. -All files from client/ dir has been shared, but there few places with hidden code due to various reasons -In the future more parts of OTCv8 will be available here - -If you want buy access to full sources, contact kondrah#7945 on discord -Or send mail to otclient@otclient.ovh (but discord is better) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt deleted file mode 100644 index dc51557..0000000 --- a/src/client/CMakeLists.txt +++ /dev/null @@ -1,113 +0,0 @@ -# CMAKE_CURRENT_LIST_DIR cmake 2.6 compatibility -if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6) - get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) -endif(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6) - -# client options -add_definitions(-DCLIENT) -option(BOT_PROTECTION "Enable bot protection" ON) -if(BOT_PROTECTION) - add_definitions(-DBOT_PROTECTION) - message(STATUS "Bot protection: ON") -else(BOT_PROTECTION) - message(STATUS "Bot protection: OFF") -endif(BOT_PROTECTION) - -set(client_SOURCES ${client_SOURCES} - # client - ${CMAKE_CURRENT_LIST_DIR}/const.h - ${CMAKE_CURRENT_LIST_DIR}/global.h - ${CMAKE_CURRENT_LIST_DIR}/luafunctions_client.cpp - ${CMAKE_CURRENT_LIST_DIR}/client.cpp - ${CMAKE_CURRENT_LIST_DIR}/client.h - - # core - ${CMAKE_CURRENT_LIST_DIR}/animatedtext.cpp - ${CMAKE_CURRENT_LIST_DIR}/animatedtext.h - ${CMAKE_CURRENT_LIST_DIR}/animator.h - ${CMAKE_CURRENT_LIST_DIR}/animator.cpp - ${CMAKE_CURRENT_LIST_DIR}/container.cpp - ${CMAKE_CURRENT_LIST_DIR}/container.h - ${CMAKE_CURRENT_LIST_DIR}/creature.cpp - ${CMAKE_CURRENT_LIST_DIR}/creature.h - ${CMAKE_CURRENT_LIST_DIR}/declarations.h - ${CMAKE_CURRENT_LIST_DIR}/effect.cpp - ${CMAKE_CURRENT_LIST_DIR}/effect.h - ${CMAKE_CURRENT_LIST_DIR}/game.cpp - ${CMAKE_CURRENT_LIST_DIR}/game.h - ${CMAKE_CURRENT_LIST_DIR}/shadermanager.cpp - ${CMAKE_CURRENT_LIST_DIR}/shadermanager.h - ${CMAKE_CURRENT_LIST_DIR}/item.cpp - ${CMAKE_CURRENT_LIST_DIR}/item.h - ${CMAKE_CURRENT_LIST_DIR}/localplayer.cpp - ${CMAKE_CURRENT_LIST_DIR}/localplayer.h - ${CMAKE_CURRENT_LIST_DIR}/map.cpp - ${CMAKE_CURRENT_LIST_DIR}/map.h - ${CMAKE_CURRENT_LIST_DIR}/mapio.cpp - ${CMAKE_CURRENT_LIST_DIR}/mapview.cpp - ${CMAKE_CURRENT_LIST_DIR}/mapview.h - ${CMAKE_CURRENT_LIST_DIR}/minimap.cpp - ${CMAKE_CURRENT_LIST_DIR}/minimap.h - ${CMAKE_CURRENT_LIST_DIR}/lightview.cpp - ${CMAKE_CURRENT_LIST_DIR}/lightview.h - ${CMAKE_CURRENT_LIST_DIR}/missile.cpp - ${CMAKE_CURRENT_LIST_DIR}/missile.h - ${CMAKE_CURRENT_LIST_DIR}/outfit.cpp - ${CMAKE_CURRENT_LIST_DIR}/outfit.h - ${CMAKE_CURRENT_LIST_DIR}/player.cpp - ${CMAKE_CURRENT_LIST_DIR}/player.h - ${CMAKE_CURRENT_LIST_DIR}/spritemanager.cpp - ${CMAKE_CURRENT_LIST_DIR}/spritemanager.h - ${CMAKE_CURRENT_LIST_DIR}/statictext.cpp - ${CMAKE_CURRENT_LIST_DIR}/statictext.h - ${CMAKE_CURRENT_LIST_DIR}/thing.cpp - ${CMAKE_CURRENT_LIST_DIR}/thing.h - ${CMAKE_CURRENT_LIST_DIR}/thingtypemanager.cpp - ${CMAKE_CURRENT_LIST_DIR}/thingtypemanager.h - ${CMAKE_CURRENT_LIST_DIR}/thingtype.cpp - ${CMAKE_CURRENT_LIST_DIR}/thingtype.h - ${CMAKE_CURRENT_LIST_DIR}/itemtype.cpp - ${CMAKE_CURRENT_LIST_DIR}/itemtype.h - ${CMAKE_CURRENT_LIST_DIR}/tile.cpp - ${CMAKE_CURRENT_LIST_DIR}/tile.h - ${CMAKE_CURRENT_LIST_DIR}/houses.cpp - ${CMAKE_CURRENT_LIST_DIR}/houses.h - ${CMAKE_CURRENT_LIST_DIR}/towns.cpp - ${CMAKE_CURRENT_LIST_DIR}/towns.h - ${CMAKE_CURRENT_LIST_DIR}/creatures.cpp - ${CMAKE_CURRENT_LIST_DIR}/creatures.h - - # lua - ${CMAKE_CURRENT_LIST_DIR}/luavaluecasts_client.cpp - ${CMAKE_CURRENT_LIST_DIR}/luavaluecasts_client.h - - # net - ${CMAKE_CURRENT_LIST_DIR}/protocolcodes.cpp - ${CMAKE_CURRENT_LIST_DIR}/protocolcodes.h - ${CMAKE_CURRENT_LIST_DIR}/protocolgame.cpp - ${CMAKE_CURRENT_LIST_DIR}/protocolgame.h - ${CMAKE_CURRENT_LIST_DIR}/protocolgameparse.cpp - ${CMAKE_CURRENT_LIST_DIR}/protocolgamesend.cpp - - # ui - ${CMAKE_CURRENT_LIST_DIR}/uicreature.cpp - ${CMAKE_CURRENT_LIST_DIR}/uicreature.h - ${CMAKE_CURRENT_LIST_DIR}/uiitem.cpp - ${CMAKE_CURRENT_LIST_DIR}/uiitem.h - ${CMAKE_CURRENT_LIST_DIR}/uimap.cpp - ${CMAKE_CURRENT_LIST_DIR}/uimap.h - ${CMAKE_CURRENT_LIST_DIR}/uiminimap.cpp - ${CMAKE_CURRENT_LIST_DIR}/uiminimap.h - ${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.cpp - ${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.h - ${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.cpp - ${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.h - ${CMAKE_CURRENT_LIST_DIR}/uisprite.cpp - ${CMAKE_CURRENT_LIST_DIR}/uisprite.h - - # util - ${CMAKE_CURRENT_LIST_DIR}/position.h -) - -set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp - PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os") diff --git a/src/client/animatedtext.cpp b/src/client/animatedtext.cpp deleted file mode 100644 index 3a33384..0000000 --- a/src/client/animatedtext.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "animatedtext.h" -#include "map.h" -#include "game.h" -#include -#include -#include - -AnimatedText::AnimatedText() -{ - m_cachedText.setFont(g_fonts.getFont("verdana-11px-rounded")); - m_cachedText.setAlign(Fw::AlignLeft); -} - -void AnimatedText::drawText(const Point& dest, const Rect& visibleRect) -{ - static float tf = Otc::ANIMATED_TEXT_DURATION; - static float tftf = Otc::ANIMATED_TEXT_DURATION * Otc::ANIMATED_TEXT_DURATION; - - Point p = dest; - Size textSize = m_cachedText.getTextSize(); - float t = m_animationTimer.ticksElapsed(); - p.x -= textSize.width() / 2; - - if(g_game.getFeature(Otc::GameDiagonalAnimatedText)) { - p.x -= (4 * t / tf) + (8 * t * t / tftf); - } - - p.y += (-48 * t) / tf; - p += m_offset; - Rect rect(p, textSize); - - if(visibleRect.contains(rect)) { - float t0 = tf / 1.2; - Color color = m_color; - if(t > t0) { - color.setAlpha((float)(1 - (t - t0) / (tf - t0))); - } - m_cachedText.draw(rect, color); - } -} - -void AnimatedText::onAppear() -{ - m_animationTimer.restart(); - - // schedule removal - auto self = asAnimatedText(); - g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, Otc::ANIMATED_TEXT_DURATION); -} - -void AnimatedText::setColor(int color) -{ - m_color = Color::from8bit(color); -} - -void AnimatedText::setText(const std::string& text) -{ - m_cachedText.setText(text); -} - -bool AnimatedText::merge(const AnimatedTextPtr& other) -{ - if(other->getColor() != m_color) - return false; - - if(other->getCachedText().getFont() != m_cachedText.getFont()) - return false; - - if(m_animationTimer.ticksElapsed() > Otc::ANIMATED_TEXT_DURATION / 2.5) - return false; - - try { - int number = stdext::safe_cast(m_cachedText.getText()); - int otherNumber = stdext::safe_cast(other->getCachedText().getText()); - m_cachedText.setText(std::to_string(number + otherNumber)); - return true; - } catch(...) {} - return false; -} diff --git a/src/client/animatedtext.h b/src/client/animatedtext.h deleted file mode 100644 index ead95dd..0000000 --- a/src/client/animatedtext.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef ANIMATEDTEXT_H -#define ANIMATEDTEXT_H - -#include "thing.h" -#include -#include -#include - -// @bindclass -class AnimatedText : public Thing -{ -public: - AnimatedText(); - - void drawText(const Point& dest, const Rect& visibleRect); - - void setColor(int color); - void setText(const std::string& text); - void setOffset(const Point& offset) { m_offset = offset; } - - Color getColor() { return m_color; } - const CachedText& getCachedText() const { return m_cachedText; } - Point getOffset() { return m_offset; } - Timer getTimer() { return m_animationTimer; } - - bool merge(const AnimatedTextPtr& other); - - AnimatedTextPtr asAnimatedText() { return static_self_cast(); } - bool isAnimatedText() { return true; } - std::string getText() { return m_cachedText.getText(); } - -protected: - virtual void onAppear(); - -private: - Color m_color; - Timer m_animationTimer; - CachedText m_cachedText; - Point m_offset; -}; - -#endif diff --git a/src/client/animator.cpp b/src/client/animator.cpp deleted file mode 100644 index 15bcadb..0000000 --- a/src/client/animator.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* -* Copyright (c) 2010-2017 OTClient -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -#include "declarations.h" -#include "animator.h" - -#include -#include -#include -#include - -Animator::Animator() -{ - m_animationPhases = 0; - m_startPhase = 0; - m_loopCount = 0; - m_async = false; - m_currentDuration = 0; - m_currentDirection = AnimDirForward; - m_currentLoop = 0; - m_lastPhaseTicks = 0; - m_isComplete = false; - m_phase = 0; -} - -void Animator::unserialize(int animationPhases, const FileStreamPtr& fin) -{ - m_animationPhases = animationPhases; - m_async = fin->getU8() == 0; - m_loopCount = fin->get32(); - m_startPhase = fin->get8(); - - for(int i = 0; i < m_animationPhases; ++i) { - int minimum = fin->getU32(); - int maximum = fin->getU32(); - m_phaseDurations.push_back(std::make_pair(minimum, std::max(0, maximum - minimum))); - } - - m_phase = getStartPhase(); - - VALIDATE(m_animationPhases == (int)m_phaseDurations.size()); - VALIDATE(m_startPhase >= -1 && m_startPhase < m_animationPhases); -} - -void Animator::serialize(const FileStreamPtr& fin) -{ - fin->addU8(m_async ? 0 : 1); - fin->add32(m_loopCount); - fin->add8(m_startPhase); - - for(auto& phase : m_phaseDurations) { - fin->addU32(phase.first); - fin->addU32(phase.first + phase.second); - } -} - -void Animator::setPhase(int phase) -{ - if(m_phase == phase) return; - - if(m_async) { - if(phase == AnimPhaseAsync) - m_phase = 0; - else if(phase == AnimPhaseRandom) - m_phase = (int)stdext::random_range(0, (long)m_animationPhases); - else if(phase >= 0 && phase < m_animationPhases) - m_phase = phase; - else - m_phase = getStartPhase(); - - m_isComplete = false; - m_lastPhaseTicks = g_clock.millis(); - m_currentDuration = getPhaseDuration(phase); - m_currentLoop = 0; - } else - calculateSynchronous(); -} - -int Animator::getPhase() -{ - ticks_t ticks = g_clock.millis(); - if(ticks != m_lastPhaseTicks && !m_isComplete) { - int elapsedTicks = (int)(ticks - m_lastPhaseTicks); - if(elapsedTicks >= m_currentDuration) { - int phase = 0; - if(m_loopCount < 0) - phase = getPingPongPhase(); - else - phase = getLoopPhase(); - - if(m_phase != phase) { - int duration = getPhaseDuration(phase) - (elapsedTicks - m_currentDuration); - if(duration < 0 && !m_async) { - calculateSynchronous(); - } else { - m_phase = phase; - m_currentDuration = std::max(0, duration); - } - } else - m_isComplete = true; - } else - m_currentDuration -= elapsedTicks; - - m_lastPhaseTicks = ticks; - } - return m_phase; -} - -int Animator::getPhaseAt(Timer& timer, int lastPhase) -{ - static int rand_val = 6; - ticks_t time = timer.ticksElapsed(); - for (int i = lastPhase; i < m_animationPhases; ++i) { - int phaseDuration = m_phaseDurations[i].second == 0 ? - m_phaseDurations[i].first : m_phaseDurations[i].first + rand_val % (m_phaseDurations[i].second); - rand_val = rand_val * 7 + 11; - if (time < phaseDuration) { - timer.restart(); - timer.adjust(-time); - return i; - } - time -= phaseDuration; - } - return -1; - /* - ticks_t total = 0; - - for (const auto &pair : m_phaseDurations) { - total += std::get<1>(pair); - - if (time < total) { - return index; - } - - ++index; - } - - return std::min(index, m_animationPhases - 1); - */ -} - -int Animator::getStartPhase() -{ - if(m_startPhase > -1) - return m_startPhase; - return (int)stdext::random_range(0, (long)m_animationPhases); -} - -void Animator::resetAnimation() -{ - m_isComplete = false; - m_currentDirection = AnimDirForward; - m_currentLoop = 0; - setPhase(AnimPhaseAutomatic); -} - -int Animator::getPingPongPhase() -{ - int count = m_currentDirection == AnimDirForward ? 1 : -1; - int nextPhase = m_phase + count; - if(nextPhase < 0 || nextPhase >= m_animationPhases) { - m_currentDirection = m_currentDirection == AnimDirForward ? AnimDirBackward : AnimDirForward; - count *= -1; - } - return m_phase + count; -} - -int Animator::getLoopPhase() -{ - int nextPhase = m_phase + 1; - if(nextPhase < m_animationPhases) - return nextPhase; - - if(m_loopCount == 0) - return 0; - - if(m_currentLoop < (m_loopCount - 1)) { - m_currentLoop++; - return 0; - } - - return m_phase; -} - -int Animator::getPhaseDuration(int phase) -{ - VALIDATE(phase < (int)m_phaseDurations.size()); - - auto& data = m_phaseDurations.at(phase); - if (data.second == 0) return data.first; - int min = data.first; - int max = min + data.second; - return (int)stdext::random_range((long)min, (long)max); -} - -void Animator::calculateSynchronous() -{ - int totalDuration = 0; - for(int i = 0; i < m_animationPhases; i++) - totalDuration += getPhaseDuration(i); - - ticks_t ticks = g_clock.millis(); - int elapsedTicks = (int)(ticks % totalDuration); - int totalTime = 0; - for(int i = 0; i < m_animationPhases; i++) { - int duration = getPhaseDuration(i); - if(elapsedTicks >= totalTime && elapsedTicks < totalTime + duration) { - m_phase = i; - m_currentDuration = duration - (elapsedTicks - totalTime); - break; - } - totalTime += duration; - } - m_lastPhaseTicks = ticks; -} - -ticks_t Animator::getTotalDuration() -{ - ticks_t time = 0; - for (const auto &pair: m_phaseDurations) { - time += pair.first + pair.second; - } - - return time; -} diff --git a/src/client/animator.h b/src/client/animator.h deleted file mode 100644 index 61676b4..0000000 --- a/src/client/animator.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -* Copyright (c) 2010-2017 OTClient -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -#ifndef ANIMATOR_H -#define ANIMATOR_H - -#include "declarations.h" - -#include -#include - -enum AnimationPhase : int16 -{ - AnimPhaseAutomatic = -1, - AnimPhaseRandom = 254, - AnimPhaseAsync = 255, -}; - -enum AnimationDirection : uint8 -{ - AnimDirForward = 0, - AnimDirBackward = 1 -}; - -class Animator : public stdext::shared_object -{ -public: - Animator(); - - void unserialize(int animationPhases, const FileStreamPtr& fin); - void serialize(const FileStreamPtr& fin); - - void setPhase(int phase); - int getPhase(); - int getPhaseAt(Timer& timer, int lastPhase = 0); - - int getStartPhase(); - int getAnimationPhases() { return m_animationPhases; } - bool isAsync() { return m_async; } - bool isComplete() { return m_isComplete; } - - ticks_t getTotalDuration(); - - void resetAnimation(); - -private: - int getPingPongPhase(); - int getLoopPhase(); - int getPhaseDuration(int phase); - void calculateSynchronous(); - - int m_animationPhases; - int m_startPhase; - int m_loopCount; - bool m_async; - std::vector< std::pair > m_phaseDurations; - - int m_currentDuration; - AnimationDirection m_currentDirection; - int m_currentLoop; - - ticks_t m_lastPhaseTicks; - bool m_isComplete; - - int m_phase; -}; - -#endif diff --git a/src/client/client.cpp b/src/client/client.cpp deleted file mode 100644 index 54d9103..0000000 --- a/src/client/client.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "client.h" -#include -#include -#include -#include "game.h" -#include "map.h" -#include "shadermanager.h" -#include "spritemanager.h" -#include "minimap.h" -#include - -Client g_client; - -void Client::init(std::vector& args) -{ - // register needed lua functions - registerLuaFunctions(); - - g_map.init(); - g_minimap.init(); - g_game.init(); - g_shaders.init(); - g_things.init(); -} - -void Client::terminate() -{ - g_creatures.terminate(); - g_game.terminate(); - g_map.terminate(); - g_minimap.terminate(); - g_things.terminate(); - g_sprites.terminate(); - g_shaders.terminate(); -} diff --git a/src/client/client.h b/src/client/client.h deleted file mode 100644 index bba39d4..0000000 --- a/src/client/client.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CLIENT_H -#define CLIENT_H - -#include "global.h" - -class Client -{ -public: - void init(std::vector& args); - void terminate(); - void registerLuaFunctions(); -}; - -extern Client g_client; - -#endif diff --git a/src/client/const.h b/src/client/const.h deleted file mode 100644 index 6a1eafc..0000000 --- a/src/client/const.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CLIENT_CONST_H -#define CLIENT_CONST_H - -namespace Otc -{ - enum : int { - TILE_PIXELS = 32, - MAX_ELEVATION = 24, - - SEA_FLOOR = 7, - MAX_Z = 15, - UNDERGROUND_FLOOR = SEA_FLOOR+1, - AWARE_UNDEGROUND_FLOOR_RANGE = 2, - - INVISIBLE_TICKS_PER_FRAME = 500, - INVISIBLE_TICKS_PER_FRAME_FAST = 100, - ITEM_TICKS_PER_FRAME = 500, - ITEM_TICKS_PER_FRAME_FAST = 100, - ANIMATED_TEXT_DURATION = 1000, - STATIC_DURATION_PER_CHARACTER = 60, - MIN_STATIC_TEXT_DURATION = 3000, - MAX_STATIC_TEXT_WIDTH = 200, - MAX_AUTOWALK_STEPS_RETRY = 10, - MAX_AUTOWALK_DIST = 127 - }; - - enum DepthConst { - MAX_DEPTH = 16384 - 2048 - }; - - enum DrawFlags { - DrawGround = 1, - DrawGroundBorders = 2, - DrawOnBottom = 4, - DrawOnTop = 8, - DrawItems = 16, - DrawCreatures = 32, - DrawEffects = 64, - DrawMissiles = 128, - DrawCreaturesInformation = 256, - DrawStaticTexts = 512, - DrawAnimatedTexts = 1024, - DrawAnimations = 2048, - DrawBars = 4096, - DrawNames = 8192, - DrawLights = 16384, - DrawManaBar = 32768, - DontDrawLocalPlayer = 65536, - DrawIcons = 131072, - DrawWalls = DrawOnBottom | DrawOnTop, - DrawEverything = DrawGround | DrawGroundBorders | DrawWalls | DrawItems | - DrawCreatures | DrawEffects | DrawMissiles | DrawCreaturesInformation | - DrawStaticTexts | DrawAnimatedTexts | DrawAnimations | DrawBars | DrawNames | - DrawLights | DrawManaBar | DrawIcons - }; - - enum DatOpts { - DatGround = 0, - DatGroundClip, - DatOnBottom, - DatOnTop, - DatContainer, - DatStackable, - DatForceUse, - DatMultiUse, - DatWritable, - DatWritableOnce, - DatFluidContainer, - DatSplash, - DatBlockWalk, - DatNotMoveable, - DatBlockProjectile, - DatBlockPathFind, - DatPickupable, - DatHangable, - DatHookSouth, - DatHookEast, - DatRotable, - DatLight, - DatDontHide, - DatTranslucent, - DatDisplacement, - DatElevation, - DatLyingCorpse, - DatAnimateAlways, - DatMinimapColor, - DatLensHelp, - DatFullGround, - DatIgnoreLook, - DatCloth, - DatAnimation, // lastest tibia - DatLastOpt = 255 - }; - - enum InventorySlot { - InventorySlotHead = 1, - InventorySlotNecklace, - InventorySlotBackpack, - InventorySlotArmor, - InventorySlotRight, - InventorySlotLeft, - InventorySlotLegs, - InventorySlotFeet, - InventorySlotRing, - InventorySlotAmmo, - InventorySlotPurse, - InventorySlotExt1, - InventorySlotExt2, - InventorySlotExt3, - InventorySlotExt4, - LastInventorySlot - }; - - enum Statistic { - Health = 0, - MaxHealth, - FreeCapacity, - Experience, - Level, - LevelPercent, - Mana, - MaxMana, - MagicLevel, - MagicLevelPercent, - Soul, - Stamina, - LastStatistic - }; - - enum Skill { - Fist = 0, - Club, - Sword, - Axe, - Distance, - Shielding, - Fishing, - CriticalChance, - CriticalDamage, - LifeLeechChance, - LifeLeechAmount, - ManaLeechChance, - ManaLeechAmount, - LastSkill - }; - - enum Direction { - North = 0, - East, - South, - West, - NorthEast, - SouthEast, - SouthWest, - NorthWest, - InvalidDirection - }; - - enum FluidsColor { - FluidTransparent = 0, - FluidBlue, - FluidRed, - FluidBrown, - FluidGreen, - FluidYellow, - FluidWhite, - FluidPurple - }; - - enum FluidsType { - FluidNone = 0, - FluidWater, - FluidMana, - FluidBeer, - FluidOil, - FluidBlood, - FluidSlime, - FluidMud, - FluidLemonade, - FluidMilk, - FluidWine, - FluidHealth, - FluidUrine, - FluidRum, - FluidFruidJuice, - FluidCoconutMilk, - FluidTea, - FluidMead - }; - - enum FightModes { - FightOffensive = 1, - FightBalanced = 2, - FightDefensive = 3 - }; - - enum ChaseModes { - DontChase = 0, - ChaseOpponent = 1 - }; - - enum PVPModes { - WhiteDove = 0, - WhiteHand = 1, - YellowHand = 2, - RedFist = 3 - }; - - enum PlayerSkulls { - SkullNone = 0, - SkullYellow, - SkullGreen, - SkullWhite, - SkullRed, - SkullBlack, - SkullOrange - }; - - enum PlayerShields { - ShieldNone = 0, - ShieldWhiteYellow, // 1 party leader - ShieldWhiteBlue, // 2 party member - ShieldBlue, // 3 party member sexp off - ShieldYellow, // 4 party leader sexp off - ShieldBlueSharedExp, // 5 party member sexp on - ShieldYellowSharedExp, // 6 // party leader sexp on - ShieldBlueNoSharedExpBlink, // 7 party member sexp inactive guilty - ShieldYellowNoSharedExpBlink, // 8 // party leader sexp inactive guilty - ShieldBlueNoSharedExp, // 9 party member sexp inactive innocent - ShieldYellowNoSharedExp, // 10 party leader sexp inactive innocent - ShieldGray // 11 member of another party - }; - - enum PlayerEmblems { - EmblemNone = 0, - EmblemGreen, - EmblemRed, - EmblemBlue, - EmblemMember, - EmblemOther - }; - - enum CreatureIcons { - NpcIconNone = 0, - NpcIconChat, - NpcIconTrade, - NpcIconQuest, - NpcIconTradeQuest - }; - - enum PlayerStates { - IconNone = 0, - IconPoison = 1, - IconBurn = 2, - IconEnergy = 4, - IconDrunk = 8, - IconManaShield = 16, - IconParalyze = 32, - IconHaste = 64, - IconSwords = 128, - IconDrowning = 256, - IconFreezing = 512, - IconDazzled = 1024, - IconCursed = 2048, - IconPartyBuff = 4096, - IconPzBlock = 8192, - IconPz = 16384, - IconBleeding = 32768, - IconHungry = 65536 - }; - - enum MessageMode { - MessageNone = 0, - MessageSay = 1, - MessageWhisper = 2, - MessageYell = 3, - MessagePrivateFrom = 4, - MessagePrivateTo = 5, - MessageChannelManagement = 6, - MessageChannel = 7, - MessageChannelHighlight = 8, - MessageSpell = 9, - MessageNpcFrom = 10, - MessageNpcTo = 11, - MessageGamemasterBroadcast = 12, - MessageGamemasterChannel = 13, - MessageGamemasterPrivateFrom = 14, - MessageGamemasterPrivateTo = 15, - MessageLogin = 16, - MessageWarning = 17, - MessageGame = 18, - MessageFailure = 19, - MessageLook = 20, - MessageDamageDealed = 21, - MessageDamageReceived = 22, - MessageHeal = 23, - MessageExp = 24, - MessageDamageOthers = 25, - MessageHealOthers = 26, - MessageExpOthers = 27, - MessageStatus = 28, - MessageLoot = 29, - MessageTradeNpc = 30, - MessageGuild = 31, - MessagePartyManagement = 32, - MessageParty = 33, - MessageBarkLow = 34, - MessageBarkLoud = 35, - MessageReport = 36, - MessageHotkeyUse = 37, - MessageTutorialHint = 38, - MessageThankyou = 39, - MessageMarket = 40, - MessageMana = 41, - MessageBeyondLast = 42, - - // deprecated - MessageMonsterYell = 43, - MessageMonsterSay = 44, - MessageRed = 45, - MessageBlue = 46, - MessageRVRChannel = 47, - MessageRVRAnswer = 48, - MessageRVRContinue = 49, - MessageGameHighlight = 50, - MessageNpcFromStartBlock = 51, - LastMessage = 52, - MessageInvalid = 255 - }; - - enum GameFeature { - GameProtocolChecksum = 1, - GameAccountNames = 2, - GameChallengeOnLogin = 3, - GamePenalityOnDeath = 4, - GameNameOnNpcTrade = 5, - GameDoubleFreeCapacity = 6, - GameDoubleExperience = 7, - GameTotalCapacity = 8, - GameSkillsBase = 9, - GamePlayerRegenerationTime = 10, - GameChannelPlayerList = 11, - GamePlayerMounts = 12, - GameEnvironmentEffect = 13, - GameCreatureEmblems = 14, - GameItemAnimationPhase = 15, - GameMagicEffectU16 = 16, - GamePlayerMarket = 17, - GameSpritesU32 = 18, - GameTileAddThingWithStackpos = 19, - GameOfflineTrainingTime = 20, - GamePurseSlot = 21, - GameFormatCreatureName = 22, - GameSpellList = 23, - GameClientPing = 24, - GameExtendedClientPing = 25, - GameDoubleHealth = 28, - GameDoubleSkills = 29, - GameChangeMapAwareRange = 30, - GameMapMovePosition = 31, - GameAttackSeq = 32, - GameBlueNpcNameColor = 33, - GameDiagonalAnimatedText = 34, - GameLoginPending = 35, - GameNewSpeedLaw = 36, - GameForceFirstAutoWalkStep = 37, - GameMinimapRemove = 38, - GameDoubleShopSellAmount = 39, - GameContainerPagination = 40, - GameThingMarks = 41, - GameLooktypeU16 = 42, - GamePlayerStamina = 43, - GamePlayerAddons = 44, - GameMessageStatements = 45, - GameMessageLevel = 46, - GameNewFluids = 47, - GamePlayerStateU16 = 48, - GameNewOutfitProtocol = 49, - GamePVPMode = 50, - GameWritableDate = 51, - GameAdditionalVipInfo = 52, - GameBaseSkillU16 = 53, - GameCreatureIcons = 54, - GameHideNpcNames = 55, - GameSpritesAlphaChannel = 56, - GamePremiumExpiration = 57, - GameBrowseField = 58, - GameEnhancedAnimations = 59, - GameOGLInformation = 60, - GameMessageSizeCheck = 61, - GamePreviewState = 62, - GameLoginPacketEncryption = 63, - GameClientVersion = 64, - GameContentRevision = 65, - GameExperienceBonus = 66, - GameAuthenticator = 67, - GameUnjustifiedPoints = 68, - GameSessionKey = 69, - GameDeathType = 70, - GameIdleAnimations = 71, - GameKeepUnawareTiles = 72, - GameIngameStore = 73, - GameIngameStoreHighlights = 74, - GameIngameStoreServiceType = 75, - GameAdditionalSkills = 76, - GameDistanceEffectU16 = 77, - GamePrey = 78, - GameDoubleMagicLevel = 79, - - GameExtendedOpcode = 80, - GameMinimapLimitedToSingleFloor = 81, - - GameDoubleLevel = 83, - GameDoubleSoul = 84, - GameDoublePlayerGoodsMoney = 85, - GameCreatureWalkthrough = 86, - GameDoubleTradeMoney = 87, - - // 90-99 otclientv8 features - GameNewWalking = 90, - GameSlowerManualWalking = 91, - - GameItemTooltip = 93, - - GameBot = 95, - GameBiggerMapCache = 96, - GameForceLight = 97, - GameNoDebug = 98, - GameBotProtection = 99, - - // Custom features for customer - GameFasterAnimations = 101, - GameCenteredOutfits = 102, - GameSendIdentifiers = 103, - GameWingsAndAura = 104, - - // advanced features - GamePacketSizeU32 = 110, - GamePacketCompression = 111, - - LastGameFeature = 120 - }; - - enum PathFindResult { - PathFindResultOk = 0, - PathFindResultSamePosition, - PathFindResultImpossible, - PathFindResultTooFar, - PathFindResultNoWay - }; - - enum PathFindFlags { - PathFindAllowNotSeenTiles = 1, - PathFindAllowCreatures = 2, - PathFindAllowNonPathable = 4, - PathFindAllowNonWalkable = 8, - PathFindIgnoreCreatures = 16 - }; - - enum AutomapFlags { - MapMarkTick = 0, - MapMarkQuestion, - MapMarkExclamation, - MapMarkStar, - MapMarkCross, - MapMarkTemple, - MapMarkKiss, - MapMarkShovel, - MapMarkSword, - MapMarkFlag, - MapMarkLock, - MapMarkBag, - MapMarkSkull, - MapMarkDollar, - MapMarkRedNorth, - MapMarkRedSouth, - MapMarkRedEast, - MapMarkRedWest, - MapMarkGreenNorth, - MapMarkGreenSouth - }; - - enum VipState { - VipStateOffline = 0, - VipStateOnline = 1, - VipStatePending = 2 - }; - - enum SpeedFormula { - SpeedFormulaA = 0, - SpeedFormulaB, - SpeedFormulaC, - LastSpeedFormula - }; - - enum Blessings { - BlessingNone = 0, - BlessingAdventurer = 1, - BlessingSpiritualShielding = 1 << 1, - BlessingEmbraceOfTibia = 1 << 2, - BlessingFireOfSuns = 1 << 3, - BlessingWisdomOfSolitude = 1 << 4, - BlessingSparkOfPhoenix = 1 << 5 - }; - - enum DeathType { - DeathRegular = 0, - DeathBlessed = 1 - }; - - enum StoreProductTypes { - ProductTypeOther = 0, - ProductTypeNameChange = 1 - }; - - enum StoreErrorTypes { - StoreNoError = -1, - StorePurchaseError = 0, - StoreNetworkError = 1, - StoreHistoryError = 2, - StoreTransferError = 3, - StoreInformation = 4 - }; - - enum StoreStates { - StateNone = 0, - StateNew = 1, - StateSale = 2, - StateTimed = 3 - }; - - enum PreySlotNum_t : uint8_t { - PREY_SLOTNUM_FIRST, - PREY_SLOTNUM_SECOND, - PREY_SLOTNUM_THIRD, - PREY_SLOTNUM_LAST = PREY_SLOTNUM_THIRD - }; - enum PreyState_t : uint8_t { - PREY_STATE_LOCKED = 0, - PREY_STATE_INACTIVE = 1, - PREY_STATE_ACTIVE = 2, - PREY_STATE_SELECTION = 3, - PREY_STATE_SELECTION_CHANGE_MONSTER = 4, // unused; hmm - PREY_STATE_SELECTION_FROMALL = 5, - PREY_STATE_CHANGE_FROMALL = 6, // unused :( - }; - enum PreyMessageDialog_t : uint8_t { - //PREY_MESSAGEDIALOG_IMBUEMENT_SUCCESS = 0, - //PREY_MESSAGEDIALOG_IMBUEMENT_ERROR = 1, - //PREY_MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED = 2, - //PREY_MESSAGEDIALOG_IMBUEMENT_STATION_NOT_FOUND = 3, - //PREY_MESSAGEDIALOG_IMBUEMENT_CHARM_SUCCESS = 10, - //PREY_MESSAGEDIALOG_IMBUEMENT_CHARM_ERROR = 11, - PREY_MESSAGEDIALOG_PREY_MESSAGE = 20, - PREY_MESSAGEDIALOG_PREY_ERROR = 21, - }; - enum PreyResourceType_t : uint8_t { - PREY_RESOURCETYPE_BANK_GOLD = 0, - PREY_RESOURCETYPE_INVENTORY_GOLD = 1, - PREY_RESOURCETYPE_PREY_BONUS_REROLLS = 10 - }; - enum PreyBonusType_t : uint8_t { - PREY_BONUS_DAMAGE_BOOST = 0, - PREY_BONUS_DAMAGE_REDUCTION = 1, - PREY_BONUS_XP_BONUS = 2, - PREY_BONUS_IMPROVED_LOOT = 3, - PREY_BONUS_NONE = 4, // internal usage but still added to client; - PREY_BONUS_FIRST = PREY_BONUS_DAMAGE_BOOST, - PREY_BONUS_LAST = PREY_BONUS_IMPROVED_LOOT, - }; - enum PreyAction_t : uint8_t { - PREY_ACTION_LISTREROLL = 0, - PREY_ACTION_BONUSREROLL = 1, - PREY_ACTION_MONSTERSELECTION = 2, - PREY_ACTION_REQUEST_ALL_MONSTERS = 3, - PREY_ACTION_CHANGE_FROM_ALL = 4, - PREY_ACTION_LOCK_PREY = 5, - - }; - enum PreyConfigState { - PREY_CONFIG_STATE_FREE, - PREY_CONFIG_STATE_PREMIUM, - PREY_CONFIG_STATE_TIBIACOINS - }; - enum PreyUnlockState_t : uint8_t { - PREY_UNLOCK_STORE_AND_PREMIUM = 0, - PREY_UNLOCK_STORE = 1, - PREY_UNLOCK_NONE = 2, - }; -} - -#endif diff --git a/src/client/container.cpp b/src/client/container.cpp deleted file mode 100644 index f6df471..0000000 --- a/src/client/container.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "container.h" -#include "item.h" - -Container::Container(int id, int capacity, const std::string& name, const ItemPtr& containerItem, bool hasParent, bool isUnlocked, bool hasPages, int containerSize, int firstIndex) -{ - m_id = id; - m_capacity = capacity; - m_name = name; - m_containerItem = containerItem; - m_hasParent = hasParent; - m_closed = false; - m_unlocked = isUnlocked; - m_hasPages = hasPages; - m_size = containerSize; - m_firstIndex = firstIndex; -} - -ItemPtr Container::getItem(int slot) -{ - if(slot < 0 || slot >= (int)m_items.size()) - return nullptr; - return m_items[slot]; -} - -void Container::onOpen(const ContainerPtr& previousContainer) -{ - callLuaField("onOpen", previousContainer); -} - -void Container::onClose() -{ - m_closed = true; - callLuaField("onClose"); -} - -void Container::onAddItem(const ItemPtr& item, int slot) -{ - slot -= m_firstIndex; - - m_size++; - // indicates that there is a new item on next page - if(m_hasPages && slot > m_capacity) { - callLuaField("onSizeChange", m_size); - return; - } - - if(slot == 0) - m_items.push_front(item); - else - m_items.push_back(item); - updateItemsPositions(); - - callLuaField("onSizeChange", m_size); - callLuaField("onAddItem", slot, item); -} - -ItemPtr Container::findItemById(uint itemId, int subType) -{ - for(const ItemPtr item : m_items) - if(item->getId() == itemId && (subType == -1 || item->getSubType() == subType)) - return item; - return nullptr; -} - -void Container::onAddItems(const std::vector& items) -{ - for(const ItemPtr& item : items) - m_items.push_back(item); - updateItemsPositions(); -} - -void Container::onUpdateItem(int slot, const ItemPtr& item) -{ - slot -= m_firstIndex; - if(slot < 0 || slot >= (int)m_items.size()) { - g_logger.traceError("slot not found"); - return; - } - - ItemPtr oldItem = m_items[slot]; - m_items[slot] = item; - item->setPosition(getSlotPosition(slot)); - - callLuaField("onUpdateItem", slot, item, oldItem); -} - -void Container::onRemoveItem(int slot, const ItemPtr& lastItem) -{ - slot -= m_firstIndex; - if(m_hasPages && slot >= (int)m_items.size()) { - m_size--; - callLuaField("onSizeChange", m_size); - return; - } - - if(slot < 0 || slot >= (int)m_items.size()) { - g_logger.traceError("slot not found"); - return; - } - - ItemPtr item = m_items[slot]; - m_items.erase(m_items.begin() + slot); - - - if(lastItem) { - onAddItem(lastItem, m_firstIndex + m_capacity - 1); - m_size--; - } - m_size--; - - updateItemsPositions(); - - callLuaField("onSizeChange", m_size); - callLuaField("onRemoveItem", slot, item); -} - -void Container::updateItemsPositions() -{ - for(int slot = 0; slot < (int)m_items.size(); ++slot) - m_items[slot]->setPosition(getSlotPosition(slot)); -} diff --git a/src/client/container.h b/src/client/container.h deleted file mode 100644 index 49d12ee..0000000 --- a/src/client/container.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CONTAINER_H -#define CONTAINER_H - -#include "declarations.h" -#include "item.h" - -#include - -// @bindclass -class Container : public LuaObject -{ -protected: - Container(int id, int capacity, const std::string& name, const ItemPtr& containerItem, bool hasParent, bool isUnlocked, bool hasPages, int containerSize, int firstIndex); - -public: - ItemPtr getItem(int slot); - std::deque getItems() { return m_items; } - int getItemsCount() { return m_items.size(); } - Position getSlotPosition(int slot) { return Position(0xffff, m_id | 0x40, slot); } - int getId() { return m_id; } - int getCapacity() { return m_capacity; } - ItemPtr getContainerItem() { return m_containerItem; } - std::string getName() { return m_name; } - bool hasParent() { return m_hasParent; } - bool isClosed() { return m_closed; } - bool isUnlocked() { return m_unlocked; } - bool hasPages() { return m_hasPages; } - int getSize() { return m_size; } - int getFirstIndex() { return m_firstIndex; } - ItemPtr findItemById(uint itemId, int subType); - -protected: - void onOpen(const ContainerPtr& previousContainer); - void onClose(); - void onAddItem(const ItemPtr& item, int slot); - void onAddItems(const std::vector& items); - void onUpdateItem(int slot, const ItemPtr& item); - void onRemoveItem(int slot, const ItemPtr& lastItem); - - friend class Game; - -private: - void updateItemsPositions(); - - int m_id; - int m_capacity; - ItemPtr m_containerItem; - std::string m_name; - bool m_hasParent; - bool m_closed; - bool m_unlocked; - bool m_hasPages; - int m_size; - int m_firstIndex; - std::deque m_items; -}; - -#endif diff --git a/src/client/creature.cpp b/src/client/creature.cpp deleted file mode 100644 index d47f221..0000000 --- a/src/client/creature.cpp +++ /dev/null @@ -1,1150 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "creature.h" -#include "thingtypemanager.h" -#include "localplayer.h" -#include "map.h" -#include "tile.h" -#include "item.h" -#include "game.h" -#include "effect.h" -#include "luavaluecasts_client.h" -#include "lightview.h" - -#include -#include -#include -#include - -#include -#include -#include -#include "spritemanager.h" - -#include -#include - -std::array Creature::m_speedFormula = { -1,-1,-1 }; - -Creature::Creature() : Thing() -{ - m_id = 0; - m_healthPercent = 100; - m_manaPercent = -1; - m_speed = 200; - m_direction = Otc::South; - m_walkDirection = Otc::South; - m_walkAnimationPhase = 0; - m_walkedPixels = 0; - m_skull = Otc::SkullNone; - m_shield = Otc::ShieldNone; - m_emblem = Otc::EmblemNone; - m_type = Proto::CreatureTypeUnknown; - m_icon = Otc::NpcIconNone; - m_lastStepDirection = Otc::InvalidDirection; - m_footLastStep = 0; - m_nameCache.setFont(g_fonts.getFont("verdana-11px-rounded")); - m_nameCache.setAlign(Fw::AlignTopCenter); - m_footStep = 0; - //m_speedFormula.fill(-1); - m_outfitColor = Color::white; - m_progressBarPercent = 0; - m_progressBarUpdateEvent = nullptr; - g_stats.addCreature(); -} - -Creature::~Creature() -{ - g_stats.removeCreature(); -} - -void Creature::draw(const Point& dest, bool animate, LightView* lightView) -{ - if (!canBeSeen()) - return; - - Point creatureCenter = dest + m_walkOffset - getDisplacement() + Point(Otc::TILE_PIXELS / 2, Otc::TILE_PIXELS / 2); - drawBottomWidgets(creatureCenter, m_walking ? m_walkDirection : m_direction); - - Point animationOffset = animate ? m_walkOffset : Point(0, 0); - if (m_outfit.getCategory() != ThingCategoryCreature) - animationOffset -= getDisplacement(); - - if (m_showTimedSquare && animate) { - g_drawQueue->addBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 2), Size(28, 28)), 2, m_timedSquareColor); - } - - if (m_showStaticSquare && animate) { - g_drawQueue->addBoundingRect(Rect(dest + (animationOffset - getDisplacement()), Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS)), 2, m_staticSquareColor); - } - - size_t drawQueueSize = g_drawQueue->size(); - m_outfit.draw(dest + animationOffset, m_walking ? m_walkDirection : m_direction, m_walkAnimationPhase, true, lightView); - if (m_marked) { - g_drawQueue->setMark(drawQueueSize, updatedMarkedColor()); - } - - drawTopWidgets(creatureCenter, m_walking ? m_walkDirection : m_direction); - - Light light = rawGetThingType()->getLight(); - if (m_light.intensity != light.intensity || m_light.color != light.color) - light = m_light; - - // local player always have a minimum light in complete darkness - if (isLocalPlayer()) { - light.intensity = std::max(light.intensity, 2); - if (light.color == 0 || light.color > 215) - light.color = 215; - } - - if(lightView) - lightView->addLight(creatureCenter, light); -} - -void Creature::drawOutfit(const Rect& destRect, Otc::Direction direction, const Color& color) -{ - if (direction == Otc::InvalidDirection) - direction = m_direction; - - m_outfit.draw(destRect, direction, 0, false); -} - -void Creature::drawInformation(const Point& point, bool useGray, const Rect& parentRect, int drawFlags) -{ - if (m_healthPercent < 1) // creature is dead - return; - - Color fillColor = Color(96, 96, 96); - - if (!useGray) - fillColor = m_informationColor; - - // calculate main rects - Rect backgroundRect = Rect(point.x + m_informationOffset.x - (13.5), point.y + m_informationOffset.y, 27, 4); - backgroundRect.bind(parentRect); - - //debug - if (g_extras.debugWalking) { - int footDelay = (getStepDuration(true)) / 3; - int footAnimPhases = getWalkAnimationPhases() - 1; - m_nameCache.setText(stdext::format("%i %i %i %i %i\n %i %i\n%i %i %i\n%i %i %i %i %i", - (int)m_stepDuration, (int)getStepDuration(true), getStepDuration(false), (int)m_walkedPixels, (int)m_walkTimer.ticksElapsed(), - (int)m_walkOffset.x, (int)m_walkOffset.y, - (int)m_speed, (int)getTile()->getGroundSpeed(), (int)g_game.getWalkId(), - (int)(g_clock.millis() - m_footLastStep), (int)footDelay, (int)footAnimPhases, (int)m_walkAnimationPhase, (int)stdext::millis())); - } - - Size nameSize = m_nameCache.getTextSize(); - Rect textRect = Rect(point.x + m_informationOffset.x - nameSize.width() / 2.0, point.y + m_informationOffset.y - 12, nameSize); - textRect.bind(parentRect); - - // distance them - uint32 offset = 12; - if (isLocalPlayer()) { - offset *= 2; - } - - if (textRect.top() == parentRect.top()) - backgroundRect.moveTop(textRect.top() + offset); - if (backgroundRect.bottom() == parentRect.bottom()) - textRect.moveTop(backgroundRect.top() - offset); - - // health rect is based on background rect, so no worries - Rect healthRect = backgroundRect.expanded(-1); - healthRect.setWidth((m_healthPercent / 100.0) * 25); - - // draw - if (g_game.getFeature(Otc::GameBlueNpcNameColor) && isNpc() && m_healthPercent == 100 && !useGray) - fillColor = Color(0x66, 0xcc, 0xff); - - if (drawFlags & Otc::DrawBars && (!isNpc() || !g_game.getFeature(Otc::GameHideNpcNames))) { - g_drawQueue->addFilledRect(backgroundRect, Color::black); - g_drawQueue->addFilledRect(healthRect, fillColor); - - if (drawFlags & Otc::DrawManaBar) { - int manaPercent = m_manaPercent; - if (isLocalPlayer()) { - LocalPlayerPtr player = g_game.getLocalPlayer(); - if (player) { - double maxMana = player->getMaxMana(); - if (maxMana == 0) { - manaPercent = 100; - } else { - manaPercent = (player->getMana() * 100) / maxMana; - } - } - } - if (manaPercent >= 0) { - backgroundRect.moveTop(backgroundRect.bottom()); - g_drawQueue->addFilledRect(backgroundRect, Color::black); - - Rect manaRect = backgroundRect.expanded(-1); - manaRect.setWidth(((float)manaPercent / 100.f) * 25); - g_drawQueue->addFilledRect(manaRect, Color::blue); - } - } - - if (getProgressBarPercent()) { - backgroundRect.moveTop(backgroundRect.bottom()); - - g_drawQueue->addFilledRect(backgroundRect, Color::black); - - Rect progressBarRect = backgroundRect.expanded(-1); - double maxBar = 100; - progressBarRect.setWidth(getProgressBarPercent() / (maxBar * 1.0) * 25); - - g_drawQueue->addFilledRect(progressBarRect, Color::white); - } - } - - if (drawFlags & Otc::DrawNames) { - m_nameCache.draw(textRect, fillColor); - - if (m_text) { - auto extraTextSize = m_text->getCachedText().getTextSize(); - Rect extraTextRect = Rect(point.x + m_informationOffset.x - extraTextSize.width() / 2.0, point.y + m_informationOffset.y + 15, extraTextSize); - m_text->drawText(extraTextRect.center(), extraTextRect); - } - } - - if (!(drawFlags & Otc::DrawIcons)) - return; - - if (m_skull != Otc::SkullNone && m_skullTexture) { - Rect skullRect = Rect(backgroundRect.x() + 13.5 + 12, backgroundRect.y() + 5, m_skullTexture->getSize()); - g_drawQueue->addTexturedRect(skullRect, m_skullTexture, Rect(0, 0, m_skullTexture->getSize())); - } - if (m_shield != Otc::ShieldNone && m_shieldTexture && m_showShieldTexture) { - Rect shieldRect = Rect(backgroundRect.x() + 13.5, backgroundRect.y() + 5, m_shieldTexture->getSize()); - g_drawQueue->addTexturedRect(shieldRect, m_shieldTexture, Rect(0, 0, m_shieldTexture->getSize())); - } - if (m_emblem != Otc::EmblemNone && m_emblemTexture) { - Rect emblemRect = Rect(backgroundRect.x() + 13.5 + 12, backgroundRect.y() + 16, m_emblemTexture->getSize()); - g_drawQueue->addTexturedRect(emblemRect, m_emblemTexture, Rect(0, 0, m_emblemTexture->getSize())); - } - if (m_type != Proto::CreatureTypeUnknown && m_typeTexture) { - Rect typeRect = Rect(backgroundRect.x() + 13.5 + 12 + 12, backgroundRect.y() + 16, m_typeTexture->getSize()); - g_drawQueue->addTexturedRect(typeRect, m_typeTexture, Rect(0, 0, m_typeTexture->getSize())); - } - if (m_icon != Otc::NpcIconNone && m_iconTexture) { - Rect iconRect = Rect(backgroundRect.x() + 13.5 + 12, backgroundRect.y() + 5, m_iconTexture->getSize()); - g_drawQueue->addTexturedRect(iconRect, m_iconTexture, Rect(0, 0, m_iconTexture->getSize())); - } -} - -bool Creature::isInsideOffset(Point offset) -{ - // for worse precision: - // Rect rect(getDrawOffset() - (m_walking ? m_walkOffset : Point(0,0)), Size(Otc::TILE_PIXELS - getDisplacementY(), Otc::TILE_PIXELS - getDisplacementX())); - Rect rect(getDrawOffset() - m_walkOffset - getDisplacement(), Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS)); - return rect.contains(offset); -} - -bool Creature::canShoot(int distance) -{ - return getTile() ? getTile()->canShoot(distance) : false; -} - -void Creature::turn(Otc::Direction direction) -{ - setDirection(direction); - callLuaField("onTurn", direction); -} - -void Creature::walk(const Position& oldPos, const Position& newPos) -{ - if (oldPos == newPos) - return; - - // get walk direction - m_lastStepDirection = oldPos.getDirectionFromPosition(newPos); - m_lastStepFromPosition = oldPos; - m_lastStepToPosition = newPos; - - // set current walking direction - setDirection(m_lastStepDirection); - m_walkDirection = m_direction; - - // starts counting walk - m_walking = true; - m_walkTimer.restart(); - m_walkedPixels = 0; - - if (m_walkFinishAnimEvent) { - m_walkFinishAnimEvent->cancel(); - m_walkFinishAnimEvent = nullptr; - } - - // starts updating walk - nextWalkUpdate(); -} - -void Creature::stopWalk() -{ - if (!m_walking) - return; - - // stops the walk right away - terminateWalk(); -} - -void Creature::jump(int height, int duration) -{ - if (!m_jumpOffset.isNull()) - return; - - m_jumpTimer.restart(); - m_jumpHeight = height; - m_jumpDuration = duration; - - updateJump(); -} - -void Creature::updateJump() -{ - int t = m_jumpTimer.ticksElapsed(); - double a = -4 * m_jumpHeight / (m_jumpDuration * m_jumpDuration); - double b = +4 * m_jumpHeight / (m_jumpDuration); - - double height = a * t * t + b * t; - int roundHeight = stdext::round(height); - int halfJumpDuration = m_jumpDuration / 2; - - // schedules next update - if (m_jumpTimer.ticksElapsed() < m_jumpDuration) { - m_jumpOffset = PointF(height, height); - - int diff = 0; - if (m_jumpTimer.ticksElapsed() < halfJumpDuration) - diff = 1; - else if (m_jumpTimer.ticksElapsed() > halfJumpDuration) - diff = -1; - - int nextT, i = 1; - do { - nextT = stdext::round((-b + std::sqrt(std::max(b * b + 4 * a * (roundHeight + diff * i), 0.0)) * diff) / (2 * a)); - ++i; - - if (nextT < halfJumpDuration) - diff = 1; - else if (nextT > halfJumpDuration) - diff = -1; - } while (nextT - m_jumpTimer.ticksElapsed() == 0 && i < 3); - - auto self = static_self_cast(); - g_dispatcher.scheduleEvent([self] { - self->updateJump(); - }, nextT - m_jumpTimer.ticksElapsed()); - } else - m_jumpOffset = PointF(0, 0); -} - -void Creature::onPositionChange(const Position& newPos, const Position& oldPos) -{ - callLuaField("onPositionChange", newPos, oldPos); -} - -void Creature::onAppear() -{ - // cancel any disappear event - if (m_disappearEvent) { - m_disappearEvent->cancel(); - m_disappearEvent = nullptr; - } - - // creature appeared the first time or wasn't seen for a long time - if (m_removed) { - stopWalk(); - m_removed = false; - callLuaField("onAppear"); - // walk - } else if (m_oldPosition != m_position && m_oldPosition.isInRange(m_position, 1, 1) && m_allowAppearWalk) { - m_allowAppearWalk = false; - walk(m_oldPosition, m_position); - callLuaField("onWalk", m_oldPosition, m_position); - // teleport - } else if (m_oldPosition != m_position) { - stopWalk(); - callLuaField("onDisappear"); - callLuaField("onAppear"); - } // else turn -} - -void Creature::onDisappear() -{ - if (m_disappearEvent) - m_disappearEvent->cancel(); - - m_oldPosition = m_position; - - // a pair onDisappear and onAppear events are fired even when creatures walks or turns, - // so we must filter - auto self = static_self_cast(); - m_disappearEvent = g_dispatcher.addEvent([self] { - self->m_removed = true; - self->stopWalk(); - - self->callLuaField("onDisappear"); - - // invalidate this creature position - if (!self->isLocalPlayer()) - self->setPosition(Position()); - self->m_oldPosition = Position(); - self->m_disappearEvent = nullptr; - self->clearWidgets(); - }); -} - -void Creature::onDeath() -{ - callLuaField("onDeath"); -} - -int Creature::getWalkAnimationPhases() -{ - if (!getAnimator()) - return getAnimationPhases(); - return getAnimator()->getAnimationPhases() + (g_game.getFeature(Otc::GameIdleAnimations) ? 1 : 0); -} - -void Creature::updateWalkAnimation(int totalPixelsWalked) -{ - // update outfit animation - if (m_outfit.getCategory() != ThingCategoryCreature) - return; - - int footAnimPhases = getWalkAnimationPhases() - 1; - // TODO, should be /2 for <= 810 - int footDelay = getStepDuration(true); - if (footAnimPhases > 0) { - footDelay = ((getStepDuration(true) + 20) / (g_game.getFeature(Otc::GameFasterAnimations) ? footAnimPhases * 2 : footAnimPhases)); - } - if (!g_game.getFeature(Otc::GameFasterAnimations)) - footDelay += 10; - if (footDelay < 20) - footDelay = 20; - - // Since mount is a different outfit we need to get the mount animation phases - if (m_outfit.getMount() != 0) { - ThingType* type = g_things.rawGetThingType(m_outfit.getMount(), m_outfit.getCategory()); - footAnimPhases = std::min(footAnimPhases, type->getAnimationPhases() - 1); - } - - if (footAnimPhases == 0) { - m_walkAnimationPhase = 0; - } else if (g_clock.millis() >= m_footLastStep + footDelay && totalPixelsWalked < 32) { - m_footStep++; - m_walkAnimationPhase = 1 + (m_footStep % footAnimPhases); - m_footLastStep = (g_clock.millis() - m_footLastStep) > footDelay * 1.5 ? g_clock.millis() : m_footLastStep + footDelay; - } else if (m_walkAnimationPhase == 0 && totalPixelsWalked < 32) { - m_walkAnimationPhase = 1 + (m_footStep % footAnimPhases); - } - - if (totalPixelsWalked == 32 && !m_walkFinishAnimEvent) { - auto self = static_self_cast(); - m_walkFinishAnimEvent = g_dispatcher.scheduleEvent([self] { - self->m_footStep = 0; - self->m_walkAnimationPhase = 0; - self->m_walkFinishAnimEvent = nullptr; - }, 50); - } - -} - -void Creature::updateWalkOffset(int totalPixelsWalked, bool inNextFrame) -{ - Point& walkOffset = inNextFrame ? m_walkOffsetInNextFrame : m_walkOffset; - walkOffset = Point(0, 0); - if (m_walkDirection == Otc::North || m_walkDirection == Otc::NorthEast || m_walkDirection == Otc::NorthWest) - walkOffset.y = 32 - totalPixelsWalked; - else if (m_walkDirection == Otc::South || m_walkDirection == Otc::SouthEast || m_walkDirection == Otc::SouthWest) - walkOffset.y = totalPixelsWalked - 32; - - if (m_walkDirection == Otc::East || m_walkDirection == Otc::NorthEast || m_walkDirection == Otc::SouthEast) - walkOffset.x = totalPixelsWalked - 32; - else if (m_walkDirection == Otc::West || m_walkDirection == Otc::NorthWest || m_walkDirection == Otc::SouthWest) - walkOffset.x = 32 - totalPixelsWalked; -} - -void Creature::updateWalkingTile() -{ - // determine new walking tile - TilePtr newWalkingTile; - Rect virtualCreatureRect(Otc::TILE_PIXELS + (m_walkOffset.x - getDisplacementX()), - Otc::TILE_PIXELS + (m_walkOffset.y - getDisplacementY()), - Otc::TILE_PIXELS, Otc::TILE_PIXELS); - for (int xi = -1; xi <= 1 && !newWalkingTile; ++xi) { - for (int yi = -1; yi <= 1 && !newWalkingTile; ++yi) { - Rect virtualTileRect((xi + 1) * Otc::TILE_PIXELS, (yi + 1) * Otc::TILE_PIXELS, Otc::TILE_PIXELS, Otc::TILE_PIXELS); - - // only render creatures where bottom right is inside tile rect - if (virtualTileRect.contains(virtualCreatureRect.bottomRight())) { - newWalkingTile = g_map.getOrCreateTile(getPrewalkingPosition().translated(xi, yi, 0)); - } - } - } - - if (newWalkingTile != m_walkingTile) { - if (m_walkingTile) - m_walkingTile->removeWalkingCreature(static_self_cast()); - if (newWalkingTile) { - newWalkingTile->addWalkingCreature(static_self_cast()); - - // recache visible tiles in map views - if (newWalkingTile->isEmpty()) - g_map.notificateTileUpdate(newWalkingTile->getPosition()); - } - m_walkingTile = newWalkingTile; - } -} - -void Creature::nextWalkUpdate() -{ - // remove any previous scheduled walk updates - if (m_walkUpdateEvent) - m_walkUpdateEvent->cancel(); - - // do the update - updateWalk(); - - // schedules next update - if (m_walking) { - auto self = static_self_cast(); - m_walkUpdateEvent = g_dispatcher.scheduleEvent([self] { - self->m_walkUpdateEvent = nullptr; - self->nextWalkUpdate(); - }, getStepDuration(true) / 32); - } -} - -void Creature::updateWalk() -{ - float walkTicksPerPixel = ((float)(getStepDuration(true) + 10)) / 32.0f; - int totalPixelsWalked = std::min(m_walkTimer.ticksElapsed() / walkTicksPerPixel, 32.0f); - int totalPixelsWalkedInNextFrame = std::min((m_walkTimer.ticksElapsed() + 15) / walkTicksPerPixel, 32.0f); - - // needed for paralyze effect - m_walkedPixels = std::max(m_walkedPixels, totalPixelsWalked); - int walkedPixelsInNextFrame = std::max(m_walkedPixels, totalPixelsWalkedInNextFrame); - - // update walk animation and offsets - updateWalkAnimation(totalPixelsWalked); - updateWalkOffset(m_walkedPixels); - updateWalkOffset(walkedPixelsInNextFrame, true); - updateWalkingTile(); - - // terminate walk - if (m_walking && m_walkTimer.ticksElapsed() >= getStepDuration()) - terminateWalk(); -} - -void Creature::terminateWalk() -{ - // remove any scheduled walk update - if (m_walkUpdateEvent) { - m_walkUpdateEvent->cancel(); - m_walkUpdateEvent = nullptr; - } - - if (m_walkingTile) { - m_walkingTile->removeWalkingCreature(static_self_cast()); - m_walkingTile = nullptr; - } - - m_walking = false; - m_walkedPixels = 0; - m_walkOffset = Point(0, 0); - m_walkOffsetInNextFrame = Point(0, 0); - - // reset walk animation states - if (!m_walkFinishAnimEvent) { - auto self = static_self_cast(); - m_walkFinishAnimEvent = g_dispatcher.scheduleEvent([self] { - self->m_footStep = 0; - self->m_walkAnimationPhase = 0; - self->m_walkFinishAnimEvent = nullptr; - }, 50); - } -} - -void Creature::setName(const std::string& name) -{ - m_nameCache.setText(name); - m_name = name; -} - -void Creature::setHealthPercent(uint8 healthPercent) -{ - if (healthPercent > 100) - healthPercent = 100; - - if (!m_useCustomInformationColor) { - if (healthPercent > 92) - m_informationColor = Color(0x00, 0xBC, 0x00); - else if (healthPercent > 60) - m_informationColor = Color(0x50, 0xA1, 0x50); - else if (healthPercent > 30) - m_informationColor = Color(0xA1, 0xA1, 0x00); - else if (healthPercent > 8) - m_informationColor = Color(0xBF, 0x0A, 0x0A); - else if (healthPercent > 3) - m_informationColor = Color(0x91, 0x0F, 0x0F); - else - m_informationColor = Color(0x85, 0x0C, 0x0C); - } - - bool changed = m_healthPercent != healthPercent; - m_healthPercent = healthPercent; - if (changed) { - callLuaField("onHealthPercentChange", healthPercent); - } - - if (healthPercent <= 0) - onDeath(); -} - -void Creature::setDirection(Otc::Direction direction) -{ - VALIDATE(direction != Otc::InvalidDirection); - m_direction = direction; -} - -void Creature::setOutfit(const Outfit& outfit) -{ - Outfit oldOutfit = m_outfit; - if (outfit.getCategory() != ThingCategoryCreature) { - if (!g_things.isValidDatId(outfit.getAuxId(), outfit.getCategory())) - return; - m_outfit.setAuxId(outfit.getAuxId()); - m_outfit.setCategory(outfit.getCategory()); - } else { - if (outfit.getId() > 0 && !g_things.isValidDatId(outfit.getId(), ThingCategoryCreature)) - return; - m_outfit = outfit; - } - m_walkAnimationPhase = 0; // might happen when player is walking and outfit is changed. - - callLuaField("onOutfitChange", m_outfit, oldOutfit); -} - -void Creature::setOutfitColor(const Color& color, int duration) -{ - if (m_outfitColorUpdateEvent) { - m_outfitColorUpdateEvent->cancel(); - m_outfitColorUpdateEvent = nullptr; - } - - if (duration > 0) { - Color delta = (color - m_outfitColor) / (float)duration; - m_outfitColorTimer.restart(); - updateOutfitColor(m_outfitColor, color, delta, duration); - } else - m_outfitColor = color; -} - -void Creature::updateOutfitColor(Color color, Color finalColor, Color delta, int duration) -{ - if (m_outfitColorTimer.ticksElapsed() < duration) { - m_outfitColor = color + delta * m_outfitColorTimer.ticksElapsed(); - - auto self = static_self_cast(); - m_outfitColorUpdateEvent = g_dispatcher.scheduleEvent([=] { - self->updateOutfitColor(color, finalColor, delta, duration); - }, 100); - } else { - m_outfitColor = finalColor; - } -} - -void Creature::setSpeed(uint16 speed) -{ - uint16 oldSpeed = m_speed; - m_speed = speed; - - // speed can change while walking (utani hur, paralyze, etc..) - if (m_walking) - nextWalkUpdate(); - - callLuaField("onSpeedChange", m_speed, oldSpeed); -} - -void Creature::setBaseSpeed(double baseSpeed) -{ - if (m_baseSpeed != baseSpeed) { - double oldBaseSpeed = m_baseSpeed; - m_baseSpeed = baseSpeed; - - callLuaField("onBaseSpeedChange", baseSpeed, oldBaseSpeed); - } -} - -void Creature::setSkull(uint8 skull) -{ - m_skull = skull; - callLuaField("onSkullChange", m_skull); -} - -void Creature::setShield(uint8 shield) -{ - m_shield = shield; - callLuaField("onShieldChange", m_shield); -} - -void Creature::setEmblem(uint8 emblem) -{ - m_emblem = emblem; - callLuaField("onEmblemChange", m_emblem); -} - -void Creature::setType(uint8 type) -{ - m_type = type; - callLuaField("onTypeChange", m_type); -} - -void Creature::setIcon(uint8 icon) -{ - m_icon = icon; - callLuaField("onIconChange", m_icon); -} - -void Creature::setSkullTexture(const std::string& filename) -{ - m_skullTexture = g_textures.getTexture(filename); -} - -void Creature::setShieldTexture(const std::string& filename, bool blink) -{ - m_shieldTexture = g_textures.getTexture(filename); - m_showShieldTexture = true; - - if (blink && !m_shieldBlink) { - auto self = static_self_cast(); - g_dispatcher.scheduleEvent([self]() { - self->updateShield(); - }, SHIELD_BLINK_TICKS); - } - - m_shieldBlink = blink; -} - -void Creature::setEmblemTexture(const std::string& filename) -{ - m_emblemTexture = g_textures.getTexture(filename); -} - -void Creature::setTypeTexture(const std::string& filename) -{ - m_typeTexture = g_textures.getTexture(filename); -} - -void Creature::setIconTexture(const std::string& filename) -{ - m_iconTexture = g_textures.getTexture(filename); -} - -void Creature::setSpeedFormula(double speedA, double speedB, double speedC) -{ - m_speedFormula[Otc::SpeedFormulaA] = speedA; - m_speedFormula[Otc::SpeedFormulaB] = speedB; - m_speedFormula[Otc::SpeedFormulaC] = speedC; -} - -bool Creature::hasSpeedFormula() -{ - return m_speedFormula[Otc::SpeedFormulaA] != -1 && m_speedFormula[Otc::SpeedFormulaB] != -1 - && m_speedFormula[Otc::SpeedFormulaC] != -1; -} - -void Creature::addTimedSquare(uint8 color) -{ - m_showTimedSquare = true; - m_timedSquareColor = Color::from8bit(color); - - // schedule removal - auto self = static_self_cast(); - g_dispatcher.scheduleEvent([self]() { - self->removeTimedSquare(); - }, VOLATILE_SQUARE_DURATION); -} - - -void Creature::updateShield() -{ - m_showShieldTexture = !m_showShieldTexture; - - if (m_shield != Otc::ShieldNone && m_shieldBlink) { - auto self = static_self_cast(); - g_dispatcher.scheduleEvent([self]() { - self->updateShield(); - }, SHIELD_BLINK_TICKS); - } else if (!m_shieldBlink) - m_showShieldTexture = true; -} - -Point Creature::getDrawOffset() -{ - Point drawOffset; - if (m_walking) { - if (m_walkingTile) - drawOffset -= Point(1, 1) * m_walkingTile->getDrawElevation(); - drawOffset += m_walkOffset; - } else { - const TilePtr& tile = getTile(); - if (tile) - drawOffset -= Point(1, 1) * tile->getDrawElevation(); - } - return drawOffset; -} - -int Creature::getStepDuration(bool ignoreDiagonal, Otc::Direction dir) -{ - int speed = m_speed; - if (speed < 1) - return 0; - - if (g_game.getFeature(Otc::GameNewSpeedLaw)) - speed *= 2; - - int groundSpeed = 0; - Position tilePos; - - if (dir == Otc::InvalidDirection) - tilePos = m_lastStepToPosition; - else - tilePos = getPrewalkingPosition(true).translatedToDirection(dir); - - if (!tilePos.isValid()) - tilePos = getPrewalkingPosition(true); - - const TilePtr& tile = g_map.getTile(tilePos); - if (tile) { - groundSpeed = tile->getGroundSpeed(); - if (groundSpeed == 0) - groundSpeed = 150; - } - - int interval = 1000; - if (groundSpeed > 0 && speed > 0) - interval = 1000 * groundSpeed; - - if (g_game.getFeature(Otc::GameNewSpeedLaw) && hasSpeedFormula()) { - int formulatedSpeed = 1; - if (speed > -m_speedFormula[Otc::SpeedFormulaB]) { - formulatedSpeed = std::max(1, (int)floor((m_speedFormula[Otc::SpeedFormulaA] * log((speed / 2) - + m_speedFormula[Otc::SpeedFormulaB]) + m_speedFormula[Otc::SpeedFormulaC]) + 0.5)); - } - interval = std::floor(interval / (double)formulatedSpeed); - } else - interval /= speed; - - if (g_game.getClientVersion() >= 900 && !g_game.getFeature(Otc::GameNewWalking)) - interval = std::ceil((float)interval / (float)g_game.getServerBeat()) * g_game.getServerBeat(); - - float factor = 3; - if (g_game.getClientVersion() <= 810) - factor = 2; - - interval = std::max(interval, g_game.getServerBeat()); - - if (!ignoreDiagonal && (m_lastStepDirection == Otc::NorthWest || m_lastStepDirection == Otc::NorthEast || - m_lastStepDirection == Otc::SouthWest || m_lastStepDirection == Otc::SouthEast)) - interval *= factor; - - if (!isServerWalking() && g_game.getFeature(Otc::GameSlowerManualWalking)) { - interval += 25; - } - if (isServerWalking() && g_game.getFeature(Otc::GameNewWalking) && m_stepDuration > 0) // just use server value - { - interval = m_stepDuration; - } - - return interval; -} - -Point Creature::getDisplacement() -{ - if (m_outfit.getCategory() == ThingCategoryEffect) - return Point(8, 8); - else if (m_outfit.getCategory() == ThingCategoryItem) - return Point(0, 0); - - if (m_outfit.getMount() != 0) { - auto datType = g_things.rawGetThingType(m_outfit.getMount(), ThingCategoryCreature); - return datType->getDisplacement(); - } - - return Thing::getDisplacement(); -} - -int Creature::getDisplacementX() -{ - if (m_outfit.getCategory() == ThingCategoryEffect) - return 8; - else if (m_outfit.getCategory() == ThingCategoryItem) - return 0; - - if (m_outfit.getMount() != 0) { - auto datType = g_things.rawGetThingType(m_outfit.getMount(), ThingCategoryCreature); - return datType->getDisplacementX(); - } - - return Thing::getDisplacementX(); -} - -int Creature::getDisplacementY() -{ - if (m_outfit.getCategory() == ThingCategoryEffect) - return 8; - else if (m_outfit.getCategory() == ThingCategoryItem) - return 0; - - if (m_outfit.getMount() != 0) { - auto datType = g_things.rawGetThingType(m_outfit.getMount(), ThingCategoryCreature); - if (datType) { - return datType->getDisplacementY(); - } - } - - return Thing::getDisplacementY(); -} - -int Creature::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase) -{ - int exactSize = 0; - - animationPhase = 0; - xPattern = Otc::South; - - zPattern = 0; - if (m_outfit.getMount() != 0) - zPattern = 1; - - for (yPattern = 0; yPattern < getNumPatternY(); yPattern++) { - if (yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern - 1)))) - continue; - - for (layer = 0; layer < getLayers(); ++layer) - exactSize = std::max(exactSize, Thing::getExactSize(layer, xPattern, yPattern, zPattern, animationPhase)); - } - - return exactSize; -} - -const ThingTypePtr& Creature::getThingType() -{ - return g_things.getThingType(m_outfit.getId(), ThingCategoryCreature); -} - -ThingType* Creature::rawGetThingType() -{ - return g_things.rawGetThingType(m_outfit.getId(), ThingCategoryCreature); -} - -void Creature::setText(const std::string& text, const Color& color) -{ - if (!m_text) { - m_text = StaticTextPtr(new StaticText()); - } - m_text->setText(text); - m_text->setColor(color); -} - -std::string Creature::getText() -{ - if (!m_text) { - return ""; - } - return m_text->getText(); -} - - -// widgets -void Creature::addTopWidget(const UIWidgetPtr& widget) -{ - if (!widget) return; - if (std::find(m_topWidgets.begin(), m_topWidgets.end(), widget) == m_topWidgets.end()) { - m_topWidgets.push_back(widget); - } -} - -void Creature::addBottomWidget(const UIWidgetPtr& widget) -{ - if (!widget) return; - if (std::find(m_bottomWidgets.begin(), m_bottomWidgets.end(), widget) == m_bottomWidgets.end()) { - m_bottomWidgets.push_back(widget); - } -} - -void Creature::addDirectionalWidget(const UIWidgetPtr& widget) -{ - if (!widget) return; - if (std::find(m_directionalWidgets.begin(), m_directionalWidgets.end(), widget) == m_directionalWidgets.end()) { - m_directionalWidgets.push_back(widget); - } -} - -void Creature::removeTopWidget(const UIWidgetPtr& widget) -{ - auto it = std::remove(m_topWidgets.begin(), m_topWidgets.end(), widget); - while(it != m_topWidgets.end()) { - (*it)->destroy(); - it = m_topWidgets.erase(it); - } -} - -void Creature::removeBottomWidget(const UIWidgetPtr& widget) -{ - auto it = std::remove(m_bottomWidgets.begin(), m_bottomWidgets.end(), widget); - while (it != m_topWidgets.end()) { - (*it)->destroy(); - it = m_bottomWidgets.erase(it); - } -} - -void Creature::removeDirectionalWidget(const UIWidgetPtr& widget) -{ - auto it = m_directionalWidgets.erase(std::remove(m_directionalWidgets.begin(), m_directionalWidgets.end(), widget)); - while (it != m_topWidgets.end()) { - (*it)->destroy(); - it = m_directionalWidgets.erase(it); - } - -} - -std::list Creature::getTopWidgets() -{ - return m_topWidgets; -} - -std::list Creature::getBottomWidgets() -{ - return m_bottomWidgets; -} - -std::list Creature::getDirectionalWdigets() -{ - return m_directionalWidgets; -} - -void Creature::clearWidgets() -{ - clearTopWidgets(); - clearBottomWidgets(); - clearDirectionalWidgets(); -} - -void Creature::clearTopWidgets() -{ - for (auto& widget : m_topWidgets) { - widget->destroy(); - } - m_topWidgets.clear(); -} - -void Creature::clearBottomWidgets() -{ - for (auto& widget : m_bottomWidgets) { - widget->destroy(); - } - m_bottomWidgets.clear(); -} - -void Creature::clearDirectionalWidgets() -{ - for (auto& widget : m_directionalWidgets) { - widget->destroy(); - } - m_directionalWidgets.clear(); -} - -void Creature::drawTopWidgets(const Point& dest, const Otc::Direction direction) -{ - if (direction == Otc::North || direction == Otc::West) { - for (auto& widget : m_directionalWidgets) { - Rect dest_rect = widget->getRect(); - dest_rect = Rect(dest - Point(dest_rect.width() / 2, dest_rect.height() / 2), dest_rect.width(), dest_rect.height()); - widget->setRect(dest_rect); - widget->draw(dest_rect, Fw::ForegroundPane); - } - } - for (auto& widget : m_topWidgets) { - Rect dest_rect = widget->getRect(); - dest_rect = Rect(dest - Point(dest_rect.width() / 2, dest_rect.height() / 2), dest_rect.width(), dest_rect.height()); - widget->setRect(dest_rect); - widget->draw(dest_rect, Fw::ForegroundPane); - } -} - -void Creature::drawBottomWidgets(const Point& dest, const Otc::Direction direction) -{ - for (auto& widget : m_bottomWidgets) { - Rect dest_rect = widget->getRect(); - dest_rect = Rect(dest - Point(dest_rect.width() / 2, dest_rect.height() / 2), dest_rect.width(), dest_rect.height()); - widget->setRect(dest_rect); - widget->draw(dest_rect, Fw::ForegroundPane); - } - - if (direction == Otc::South || direction == Otc::East) { - for (auto& widget : m_directionalWidgets) { - Rect dest_rect = widget->getRect(); - dest_rect = Rect(dest - Point(dest_rect.width() / 2, dest_rect.height() / 2), dest_rect.width(), dest_rect.height()); - widget->setRect(dest_rect); - widget->draw(dest_rect, Fw::ForegroundPane); - } - } -} - -void Creature::setProgressBar(uint32 duration, bool ltr) -{ - if (m_progressBarUpdateEvent) { - m_progressBarUpdateEvent->cancel(); - m_progressBarUpdateEvent = nullptr; - } - - if (duration > 0) { - m_progressBarTimer.restart(); - updateProgressBar(duration, ltr); - } else - m_progressBarPercent = 0; - - callLuaField("onProgressBarStart", duration, ltr); -} - -void Creature::updateProgressBar(uint32 duration, bool ltr) -{ - if (m_progressBarTimer.ticksElapsed() < duration) { - if (ltr) - m_progressBarPercent = abs(m_progressBarTimer.ticksElapsed() / static_cast(duration) * 100); - else - m_progressBarPercent = abs((m_progressBarTimer.ticksElapsed() / static_cast(duration) * 100) - 100); - - auto self = static_self_cast(); - m_progressBarUpdateEvent = g_dispatcher.scheduleEvent([=] { - self->updateProgressBar(duration, ltr); - }, 50); - } else { - m_progressBarPercent = 0; - } - callLuaField("onProgressBarUpdate", m_progressBarPercent, duration, ltr); -} diff --git a/src/client/creature.h b/src/client/creature.h deleted file mode 100644 index dcfab7c..0000000 --- a/src/client/creature.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CREATURE_H -#define CREATURE_H - -#include "thing.h" -#include "outfit.h" -#include "tile.h" -#include "mapview.h" -#include -#include -#include -#include -#include -#include - - // @bindclass -class Creature : public Thing -{ -public: - enum { - SHIELD_BLINK_TICKS = 500, - VOLATILE_SQUARE_DURATION = 1000 - }; - - Creature(); - virtual ~Creature(); - - virtual void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr); - virtual void drawOutfit(const Rect& destRect, Otc::Direction direction = Otc::InvalidDirection, const Color& color = Color::white); - - void drawInformation(const Point& point, bool useGray, const Rect& parentRect, int drawFlags); - - bool isInsideOffset(Point offset); - - void setId(uint32 id) { m_id = id; } - void setName(const std::string& name); - void setManaPercent(int8 value) { m_manaPercent = value; } - void setHealthPercent(uint8 healthPercent); - void setDirection(Otc::Direction direction); - void setOutfit(const Outfit& outfit); - void setOutfitColor(const Color& color, int duration); - void setLight(const Light& light) { m_light = light; } - void setSpeed(uint16 speed); - void setBaseSpeed(double baseSpeed); - void setSkull(uint8 skull); - void setShield(uint8 shield); - void setEmblem(uint8 emblem); - void setType(uint8 type); - void setIcon(uint8 icon); - void setSkullTexture(const std::string& filename); - void setShieldTexture(const std::string& filename, bool blink); - void setEmblemTexture(const std::string& filename); - void setTypeTexture(const std::string& filename); - void setIconTexture(const std::string& filename); - void setPassable(bool passable) { m_passable = passable; } - void setSpeedFormula(double speedA, double speedB, double speedC); - - void addTimedSquare(uint8 color); - void removeTimedSquare() { m_showTimedSquare = false; } - - void showStaticSquare(const Color& color) { m_showStaticSquare = true; m_staticSquareColor = color; } - void hideStaticSquare() { m_showStaticSquare = false; } - - void setInformationColor(const Color& color) { m_useCustomInformationColor = true; m_informationColor = color; } - void resetInformationColor() { m_useCustomInformationColor = false; } - - Point getInformationOffset() { return m_informationOffset; } - void setInformationOffset(int x, int y) { m_informationOffset = Point(x, y); } - - void setText(const std::string& text, const Color& color); - std::string getText(); - void clearText() { setText("", Color::white); } - - uint32 getId() { return m_id; } - std::string getName() { return m_name; } - uint8 getHealthPercent() { return m_healthPercent; } - int8 getManaPercent() { return m_manaPercent; } - Otc::Direction getDirection() { return m_direction; } - Otc::Direction getWalkDirection() { return m_walkDirection; } - Outfit getOutfit() { return m_outfit; } - Light getLight() { return m_light; } - uint16 getSpeed() { return m_speed; } - double getBaseSpeed() { return m_baseSpeed; } - uint8 getSkull() { return m_skull; } - uint8 getShield() { return m_shield; } - uint8 getEmblem() { return m_emblem; } - uint8 getType() { return m_type; } - uint8 getIcon() { return m_icon; } - bool isPassable() { return m_passable; } - Point getDrawOffset(); - int getStepDuration(bool ignoreDiagonal = false, Otc::Direction dir = Otc::InvalidDirection); - Point getWalkOffset(bool inNextFrame = false) { return inNextFrame ? m_walkOffsetInNextFrame : m_walkOffset; } - Position getLastStepFromPosition() { return m_lastStepFromPosition; } - Position getLastStepToPosition() { return m_lastStepToPosition; } - float getStepProgress() { return m_walkTimer.ticksElapsed() / getStepDuration(); } - int getStepTicksLeft() { return getStepDuration() - m_walkTimer.ticksElapsed(); } - ticks_t getWalkTicksElapsed() { return m_walkTimer.ticksElapsed(); } - double getSpeedFormula(Otc::SpeedFormula formula) { return m_speedFormula[formula]; } - bool hasSpeedFormula(); - std::array getSpeedFormulaArray() { return m_speedFormula; } - virtual Point getDisplacement(); - virtual int getDisplacementX(); - virtual int getDisplacementY(); - virtual int getExactSize(int layer = 0, int xPattern = 0, int yPattern = 0, int zPattern = 0, int animationPhase = 0); - PointF getJumpOffset() { return m_jumpOffset; } - - void updateShield(); - - // walk related - int getWalkAnimationPhases(); - virtual void turn(Otc::Direction direction); - void jump(int height, int duration); - virtual void walk(const Position& oldPos, const Position& newPos); - virtual void stopWalk(); - void allowAppearWalk(uint16_t stepSpeed) { m_allowAppearWalk = true; m_stepDuration = stepSpeed; } - - bool isWalking() { return m_walking; } - bool isRemoved() { return m_removed; } - bool isInvisible() { return m_outfit.getCategory() == ThingCategoryEffect && m_outfit.getAuxId() == 13; } - bool isDead() { return m_healthPercent <= 0; } - bool canBeSeen() { return !isInvisible() || isPlayer(); } - - bool isCreature() { return true; } - bool canShoot(int distance); - - const ThingTypePtr& getThingType(); - ThingType *rawGetThingType(); - - virtual void onPositionChange(const Position& newPos, const Position& oldPos); - virtual void onAppear(); - virtual void onDisappear(); - virtual void onDeath(); - - virtual bool isPreWalking() { return false; } - virtual Position getPrewalkingPosition(bool beforePrewalk = false) { return m_position; } - - TilePtr getWalkingTileOrTile() { - return m_walkingTile ? m_walkingTile : getTile(); - } - - virtual bool isServerWalking() { return true; } - - void setElevation(uint8 elevation) { - m_elevation = elevation; - } - uint8 getElevation() { - return m_elevation; - } - - // widgets - void addTopWidget(const UIWidgetPtr& widget); - void addBottomWidget(const UIWidgetPtr& widget); - void addDirectionalWidget(const UIWidgetPtr& widget); - void removeTopWidget(const UIWidgetPtr& widget); - void removeBottomWidget(const UIWidgetPtr& widget); - void removeDirectionalWidget(const UIWidgetPtr& widget); - std::list getTopWidgets(); - std::list getBottomWidgets(); - std::list getDirectionalWdigets(); - void clearWidgets(); - void clearTopWidgets(); - void clearBottomWidgets(); - void clearDirectionalWidgets(); - void drawTopWidgets(const Point& rect, const Otc::Direction direction); - void drawBottomWidgets(const Point& rect, const Otc::Direction direction); - - // progress bar - uint8 getProgressBarPercent() { return m_progressBarPercent; } - void setProgressBar(uint32 duration, bool ltr); - void updateProgressBar(uint32 duration, bool ltr); - -protected: - virtual void updateWalkAnimation(int totalPixelsWalked); - virtual void updateWalkOffset(int totalPixelsWalked, bool inNextFrame = false); - void updateWalkingTile(); - virtual void nextWalkUpdate(); - virtual void updateWalk(); - virtual void terminateWalk(); - - void updateOutfitColor(Color color, Color finalColor, Color delta, int duration); - void updateJump(); - - uint32 m_id; - std::string m_name; - uint8 m_healthPercent; - int8 m_manaPercent; - Otc::Direction m_direction; - Otc::Direction m_walkDirection; - Outfit m_outfit; - Light m_light; - int m_speed; - double m_baseSpeed; - uint8 m_skull; - uint8 m_shield; - uint8 m_emblem; - uint8 m_type; - uint8 m_icon; - TexturePtr m_skullTexture; - TexturePtr m_shieldTexture; - TexturePtr m_emblemTexture; - TexturePtr m_typeTexture; - TexturePtr m_iconTexture; - stdext::boolean m_showShieldTexture; - stdext::boolean m_shieldBlink; - stdext::boolean m_passable; - Color m_timedSquareColor; - Color m_staticSquareColor; - Color m_nameColor; - stdext::boolean m_showTimedSquare; - stdext::boolean m_showStaticSquare; - stdext::boolean m_removed; - CachedText m_nameCache; - Color m_informationColor; - bool m_useCustomInformationColor = false; - Point m_informationOffset; - Color m_outfitColor; - ScheduledEventPtr m_outfitColorUpdateEvent; - Timer m_outfitColorTimer; - - static std::array m_speedFormula; - - // walk related - int m_walkAnimationPhase; - int m_walkedPixels; - uint m_footStep; - Timer m_walkTimer; - ticks_t m_footLastStep; - TilePtr m_walkingTile; - stdext::boolean m_walking; - stdext::boolean m_allowAppearWalk; - ScheduledEventPtr m_walkUpdateEvent; - ScheduledEventPtr m_walkFinishAnimEvent; - EventPtr m_disappearEvent; - Point m_walkOffset; - Point m_walkOffsetInNextFrame; - Otc::Direction m_lastStepDirection; - Position m_lastStepFromPosition; - Position m_lastStepToPosition; - Position m_oldPosition; - uint8 m_elevation = 0; - uint16 m_stepDuration = 0; - - // jump related - float m_jumpHeight = 0; - float m_jumpDuration = 0; - PointF m_jumpOffset; - Timer m_jumpTimer; - - // for bot - StaticTextPtr m_text; - - // widgets - std::list m_bottomWidgets; - std::list m_directionalWidgets; - std::list m_topWidgets; - - // progress bar - uint8 m_progressBarPercent; - ScheduledEventPtr m_progressBarUpdateEvent; - Timer m_progressBarTimer; -}; - -// @bindclass -class Npc : public Creature -{ -public: - bool isNpc() { return true; } -}; - -// @bindclass -class Monster : public Creature -{ -public: - bool isMonster() { return true; } -}; - -#endif diff --git a/src/client/creatures.cpp b/src/client/creatures.cpp deleted file mode 100644 index 8ec8c20..0000000 --- a/src/client/creatures.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "creatures.h" -#include "creature.h" -#include "map.h" - -#include -#include - -CreatureManager g_creatures; - -static bool isInZone(const Position& pos/* placePos*/, - const Position& centerPos, - int radius) -{ - if(radius == -1) - return true; - return ((pos.x >= centerPos.x - radius) && (pos.x <= centerPos.x + radius) && - (pos.y >= centerPos.y - radius) && (pos.y <= centerPos.y + radius) - ); -} - -void CreatureManager::terminate() -{ - clearSpawns(); - clear(); - m_nullCreature = nullptr; -} - -void Spawn::load(TiXmlElement* node) -{ - Position centerPos; - centerPos.x = node->readType("centerx"); - centerPos.y = node->readType("centery"); - centerPos.z = node->readType("centerz"); - - setCenterPos(centerPos); - setRadius(node->readType("radius")); - - CreatureTypePtr cType(nullptr); - for(TiXmlElement* cNode = node->FirstChildElement(); cNode; cNode = cNode->NextSiblingElement()) { - if(cNode->ValueStr() != "monster" && cNode->ValueStr() != "npc") - stdext::throw_exception(stdext::format("invalid spawn-subnode %s", cNode->ValueStr())); - - std::string cName = cNode->Attribute("name"); - stdext::tolower(cName); - stdext::trim(cName); - stdext::ucwords(cName); - - if (!(cType = g_creatures.getCreatureByName(cName))) - continue; - - cType->setSpawnTime(cNode->readType("spawntime")); - Otc::Direction dir = Otc::North; - int16 dir_ = cNode->readType("direction"); - if(dir_ >= Otc::East && dir_ <= Otc::West) - dir = (Otc::Direction)dir_; - cType->setDirection(dir); - - Position placePos; - placePos.x = centerPos.x + cNode->readType("x"); - placePos.y = centerPos.y + cNode->readType("y"); - placePos.z = cNode->readType("z"); - - cType->setRace(cNode->ValueStr() == "npc" ? CreatureRaceNpc : CreatureRaceMonster); - addCreature(placePos, cType); - } -} - -void Spawn::save(TiXmlElement* node) -{ - const Position& c = getCenterPos(); - node->SetAttribute("centerx", c.x); - node->SetAttribute("centery", c.y); - node->SetAttribute("centerz", c.z); - - node->SetAttribute("radius", getRadius()); - - TiXmlElement* creatureNode = nullptr; - - for(const auto& pair : m_creatures) { - const CreatureTypePtr& creature = pair.second; - if(!(creatureNode = new TiXmlElement(creature->getRace() == CreatureRaceNpc ? "npc" : "monster"))) - stdext::throw_exception("Spawn::save: Ran out of memory while allocating XML element! Terminating now."); - - creatureNode->SetAttribute("name", creature->getName()); - creatureNode->SetAttribute("spawntime", creature->getSpawnTime()); - creatureNode->SetAttribute("direction", creature->getDirection()); - - const Position& placePos = pair.first; - VALIDATE(placePos.isValid()); - - creatureNode->SetAttribute("x", placePos.x - c.x); - creatureNode->SetAttribute("y", placePos.y - c.y); - creatureNode->SetAttribute("z", placePos.z); - - node->LinkEndChild(creatureNode); - } -} - -void Spawn::addCreature(const Position& placePos, const CreatureTypePtr& cType) -{ - const Position& centerPos = getCenterPos(); - int m_radius = getRadius(); - if(!isInZone(placePos, centerPos, m_radius)) { - g_logger.warning(stdext::format("cannot place creature at %s (spawn's center position: %s, spawn radius: %d) (increment radius)", - stdext::to_string(placePos), stdext::to_string(centerPos), - m_radius - )); - return; - } - - g_map.addThing(cType->cast(), placePos, 4); - m_creatures.insert(std::make_pair(placePos, cType)); -} - -void Spawn::removeCreature(const Position& pos) -{ - auto iterator = m_creatures.find(pos); - if(iterator != m_creatures.end()) { - VALIDATE(iterator->first.isValid()); - VALIDATE(g_map.removeThingByPos(iterator->first, 4)); - m_creatures.erase(iterator); - } -} - -std::vector Spawn::getCreatures() -{ - std::vector creatures; - for (auto p : m_creatures) - creatures.push_back(p.second); - return creatures; -} - -CreaturePtr CreatureType::cast() -{ - CreaturePtr ret(new Creature); - - std::string cName = getName(); - stdext::tolower(cName); - stdext::trim(cName); - stdext::ucwords(cName); - ret->setName(cName); - - ret->setDirection(getDirection()); - ret->setOutfit(getOutfit()); - return ret; -} - -CreatureManager::CreatureManager() -{ - m_nullCreature = CreatureTypePtr(new CreatureType); -} - -void CreatureManager::clearSpawns() -{ - for(auto pair : m_spawns) - pair.second->clear(); - m_spawns.clear(); -} - -void CreatureManager::loadMonsters(const std::string& file) -{ - TiXmlDocument doc; - doc.Parse(g_resources.readFileContents(file).c_str()); - if(doc.Error()) - stdext::throw_exception(stdext::format("cannot open monsters file '%s': '%s'", file, doc.ErrorDesc())); - - TiXmlElement* root = doc.FirstChildElement(); - if(!root || root->ValueStr() != "monsters") - stdext::throw_exception("malformed monsters xml file"); - - for(TiXmlElement* monster = root->FirstChildElement(); monster; monster = monster->NextSiblingElement()) { - std::string fname = file.substr(0, file.find_last_of('/')) + '/' + monster->Attribute("file"); - if(fname.substr(fname.length() - 4) != ".xml") - fname += ".xml"; - - loadSingleCreature(fname); - } - - doc.Clear(); - m_loaded = true; -} - -void CreatureManager::loadSingleCreature(const std::string& file) -{ - loadCreatureBuffer(g_resources.readFileContents(file)); -} - -void CreatureManager::loadNpcs(const std::string& folder) -{ - std::string tmp = folder; - if(!stdext::ends_with(tmp, "/")) - tmp += "/"; - - if(!g_resources.directoryExists(tmp)) - stdext::throw_exception(stdext::format("NPCs folder '%s' was not found.", folder)); - - const auto& fileList = g_resources.listDirectoryFiles(tmp); - for(const std::string& file : fileList) - loadCreatureBuffer(g_resources.readFileContents(tmp + file)); -} - -void CreatureManager::loadSpawns(const std::string& fileName) -{ - if(!isLoaded()) { - g_logger.warning("creatures aren't loaded yet to load spawns."); - return; - } - - if(m_spawnLoaded) { - g_logger.warning("attempt to reload spawns."); - return; - } - - try { - TiXmlDocument doc; - doc.Parse(g_resources.readFileContents(fileName).c_str()); - if(doc.Error()) - stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc())); - - TiXmlElement* root = doc.FirstChildElement(); - if(!root || root->ValueStr() != "spawns") - stdext::throw_exception("malformed spawns file"); - - for(TiXmlElement* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) { - if(node->ValueTStr() != "spawn") - stdext::throw_exception("invalid spawn node"); - - SpawnPtr spawn(new Spawn); - spawn->load(node); - m_spawns.insert(std::make_pair(spawn->getCenterPos(), spawn)); - } - doc.Clear(); - m_spawnLoaded = true; - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what())); - } -} - -void CreatureManager::saveSpawns(const std::string& fileName) -{ - try { - TiXmlDocument doc; - doc.SetTabSize(2); - - TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", ""); - doc.LinkEndChild(decl); - - TiXmlElement* root = new TiXmlElement("spawns"); - doc.LinkEndChild(root); - - for(auto pair : m_spawns) { - TiXmlElement* elem = new TiXmlElement("spawn"); - pair.second->save(elem); - root->LinkEndChild(elem); - } - - if(!doc.SaveFile("data"+fileName)) - stdext::throw_exception(stdext::format("failed to save spawns XML %s: %s", fileName, doc.ErrorDesc())); - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what())); - } -} - -void CreatureManager::loadCreatureBuffer(const std::string& buffer) -{ - TiXmlDocument doc; - doc.Parse(buffer.c_str()); - if(doc.Error()) - stdext::throw_exception(stdext::format("cannot load creature buffer: %s", doc.ErrorDesc())); - - TiXmlElement* root = doc.FirstChildElement(); - if(!root || (root->ValueStr() != "monster" && root->ValueStr() != "npc")) - stdext::throw_exception("invalid root tag name"); - - std::string cName = root->Attribute("name"); - stdext::tolower(cName); - stdext::trim(cName); - stdext::ucwords(cName); - - CreatureTypePtr newType(new CreatureType(cName)); - for(TiXmlElement* attrib = root->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) { - if(attrib->ValueStr() != "look") - continue; - - internalLoadCreatureBuffer(attrib, newType); - break; - } - - doc.Clear(); -} - -void CreatureManager::internalLoadCreatureBuffer(TiXmlElement* attrib, const CreatureTypePtr& m) -{ - if(std::find(m_creatures.begin(), m_creatures.end(), m) != m_creatures.end()) - return; - - Outfit out; - - int32 type = attrib->readType("type"); - if(type > 0) { - out.setCategory(ThingCategoryCreature); - out.setId(type); - } else { - out.setCategory(ThingCategoryItem); - out.setAuxId(attrib->readType("typeex")); - } - - { - out.setHead(attrib->readType(("head"))); - out.setBody(attrib->readType(("body"))); - out.setLegs(attrib->readType(("legs"))); - out.setFeet(attrib->readType(("feet"))); - out.setAddons(attrib->readType(("addons"))); - out.setMount(attrib->readType(("mount"))); - } - - m->setOutfit(out); - m_creatures.push_back(m); -} - -const CreatureTypePtr& CreatureManager::getCreatureByName(std::string name) -{ - stdext::tolower(name); - stdext::trim(name); - stdext::ucwords(name); - auto it = std::find_if(m_creatures.begin(), m_creatures.end(), - [=] (const CreatureTypePtr& m) -> bool { return m->getName() == name; }); - if(it != m_creatures.end()) - return *it; - g_logger.warning(stdext::format("could not find creature with name: %s", name)); - return m_nullCreature; -} - -const CreatureTypePtr& CreatureManager::getCreatureByLook(int look) -{ - auto findFun = [=] (const CreatureTypePtr& c) -> bool - { - const Outfit& o = c->getOutfit(); - return o.getId() == look || o.getAuxId() == look; - }; - auto it = std::find_if(m_creatures.begin(), m_creatures.end(), findFun); - if(it != m_creatures.end()) - return *it; - g_logger.warning(stdext::format("could not find creature with looktype: %d", look)); - return m_nullCreature; -} - -SpawnPtr CreatureManager::getSpawn(const Position& centerPos) -{ - auto it = m_spawns.find(centerPos); - if(it != m_spawns.end()) - return it->second; - g_logger.debug(stdext::format("failed to find spawn at center %s",stdext::to_string(centerPos))); - return nullptr; -} - -SpawnPtr CreatureManager::getSpawnForPlacePos(const Position& pos) -{ - for (const auto& pair : m_spawns) { - const Position& centerPos = pair.first; - const SpawnPtr& spawn = pair.second; - - if (isInZone(pos, centerPos, spawn->getRadius())) - return spawn; - } - - return nullptr; -} - -SpawnPtr CreatureManager::addSpawn(const Position& centerPos, int radius) -{ - auto iter = m_spawns.find(centerPos); - if(iter != m_spawns.end()) { - if(iter->second->getRadius() != radius) - iter->second->setRadius(radius); - return iter->second; - } - - SpawnPtr ret(new Spawn); - - ret->setRadius(radius); - ret->setCenterPos(centerPos); - - m_spawns.insert(std::make_pair(centerPos, ret)); - return ret; -} - -void CreatureManager::deleteSpawn(const SpawnPtr& spawn) -{ - const Position& centerPos = spawn->getCenterPos(); - auto it = m_spawns.find(centerPos); - if(it != m_spawns.end()) - m_spawns.erase(it); -} - -std::vector CreatureManager::getSpawns() -{ - std::vector spawns; - for (auto p : m_spawns) - spawns.push_back(p.second); - return spawns; -} - -/* vim: set ts=4 sw=4 et: */ diff --git a/src/client/creatures.h b/src/client/creatures.h deleted file mode 100644 index 6a64f6a..0000000 --- a/src/client/creatures.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CREATURES_H -#define CREATURES_H - -#include "declarations.h" -#include -#include "outfit.h" - -enum CreatureAttr : uint8 -{ - CreatureAttrPosition = 0, - CreatureAttrName = 1, - CreatureAttrOutfit = 2, - CreatureAttrSpawnTime = 3, - CreatureAttrDir = 4, - CreatureAttrRace = 5 -}; - -enum CreatureRace : uint8 -{ - CreatureRaceNpc = 0, - CreatureRaceMonster = 1 -}; - -enum SpawnAttr : uint8 -{ - SpawnAttrRadius = 0, - SpawnAttrCenter = 1, -}; - -class Spawn : public LuaObject -{ -public: - Spawn() = default; - Spawn(int32 radius) { setRadius(radius); } - - void setRadius(int32 r) { m_attribs.set(SpawnAttrRadius, r) ;} - int32 getRadius() { return m_attribs.get(SpawnAttrRadius); } - - void setCenterPos(const Position& pos) { m_attribs.set(SpawnAttrCenter, pos); } - Position getCenterPos() { return m_attribs.get(SpawnAttrCenter); } - - std::vector getCreatures(); - void addCreature(const Position& placePos, const CreatureTypePtr& cType); - void removeCreature(const Position& pos); - void clear() { m_creatures.clear(); } - -protected: - void load(TiXmlElement* node); - void save(TiXmlElement* node); - -private: - stdext::dynamic_storage m_attribs; - std::unordered_map m_creatures; - friend class CreatureManager; -}; - -class CreatureType : public LuaObject -{ -public: - CreatureType() = default; - CreatureType(const std::string& name) { setName(name); } - - void setSpawnTime(int32 spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); } - int32 getSpawnTime() { return m_attribs.get(CreatureAttrSpawnTime); } - - void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); } - std::string getName() { return m_attribs.get(CreatureAttrName); } - - void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttrOutfit, o); } - Outfit getOutfit() { return m_attribs.get(CreatureAttrOutfit); } - - void setDirection(Otc::Direction dir) { m_attribs.set(CreatureAttrDir, dir); } - Otc::Direction getDirection() { return m_attribs.get(CreatureAttrDir); } - - void setRace(CreatureRace race) { m_attribs.set(CreatureAttrRace, race); } - CreatureRace getRace() { return m_attribs.get(CreatureAttrRace); } - - CreaturePtr cast(); - -private: - stdext::dynamic_storage m_attribs; -}; - -class CreatureManager -{ -public: - CreatureManager(); - void clear() { m_creatures.clear(); } - void clearSpawns(); - void terminate(); - - void loadMonsters(const std::string& file); - void loadSingleCreature(const std::string& file); - void loadNpcs(const std::string& folder); - void loadCreatureBuffer(const std::string& buffer); - void loadSpawns(const std::string& fileName); - void saveSpawns(const std::string& fileName); - - const CreatureTypePtr& getCreatureByName(std::string name); - const CreatureTypePtr& getCreatureByLook(int look); - - std::vector getSpawns(); - SpawnPtr getSpawn(const Position& centerPos); - SpawnPtr getSpawnForPlacePos(const Position& pos); - SpawnPtr addSpawn(const Position& centerPos, int radius); - void deleteSpawn(const SpawnPtr& spawn); - - bool isLoaded() { return m_loaded; } - bool isSpawnLoaded() { return m_spawnLoaded; } - - const std::vector& getCreatures() { return m_creatures; } - -protected: - void internalLoadCreatureBuffer(TiXmlElement* elem, const CreatureTypePtr& m); - -private: - std::vector m_creatures; - std::unordered_map m_spawns; - stdext::boolean m_loaded, m_spawnLoaded; - CreatureTypePtr m_nullCreature; -}; - -extern CreatureManager g_creatures; - -#endif diff --git a/src/client/declarations.h b/src/client/declarations.h deleted file mode 100644 index ffd46cf..0000000 --- a/src/client/declarations.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CLIENT_DECLARATIONS_H -#define CLIENT_DECLARATIONS_H - -#include "global.h" -#include -#include - -// core -class Map; -class Game; -class MapView; -class LightView; -class Tile; -class Thing; -class Item; -class Container; -class Creature; -class Monster; -class Npc; -class Player; -class LocalPlayer; -class Effect; -class Missile; -class AnimatedText; -class StaticText; -class Animator; -class ThingType; -class ItemType; -class House; -class Town; -class CreatureType; -class Spawn; -class TileBlock; - -typedef stdext::shared_object_ptr MapViewPtr; -typedef stdext::shared_object_ptr LightViewPtr; -typedef stdext::shared_object_ptr TilePtr; -typedef stdext::shared_object_ptr ThingPtr; -typedef stdext::shared_object_ptr ItemPtr; -typedef stdext::shared_object_ptr ContainerPtr; -typedef stdext::shared_object_ptr CreaturePtr; -typedef stdext::shared_object_ptr MonsterPtr; -typedef stdext::shared_object_ptr NpcPtr; -typedef stdext::shared_object_ptr PlayerPtr; -typedef stdext::shared_object_ptr LocalPlayerPtr; -typedef stdext::shared_object_ptr EffectPtr; -typedef stdext::shared_object_ptr MissilePtr; -typedef stdext::shared_object_ptr AnimatedTextPtr; -typedef stdext::shared_object_ptr StaticTextPtr; -typedef stdext::shared_object_ptr AnimatorPtr; -typedef stdext::shared_object_ptr ThingTypePtr; -typedef stdext::shared_object_ptr ItemTypePtr; -typedef stdext::shared_object_ptr HousePtr; -typedef stdext::shared_object_ptr TownPtr; -typedef stdext::shared_object_ptr CreatureTypePtr; -typedef stdext::shared_object_ptr SpawnPtr; - -typedef std::vector ThingList; -typedef std::vector ThingTypeList; -typedef std::vector ItemTypeList; -typedef std::list HouseList; -typedef std::list TownList; -typedef std::list ItemList; -typedef std::list TileList; -typedef std::vector ItemVector; -typedef std::unordered_map TileMap; -typedef std::unordered_map CreatureMap; -typedef std::unordered_map SpawnMap; - -// net -class ProtocolLogin; -class ProtocolGame; - -typedef stdext::shared_object_ptr ProtocolGamePtr; -typedef stdext::shared_object_ptr ProtocolLoginPtr; - -// ui -class UIItem; -class UICreature; -class UIMap; -class UIMinimap; -class UIProgressRect; -class UIMapAnchorLayout; -class UIPositionAnchor; -class UISprite; - -typedef stdext::shared_object_ptr UIItemPtr; -typedef stdext::shared_object_ptr UICreaturePtr; -typedef stdext::shared_object_ptr UISpritePtr; -typedef stdext::shared_object_ptr UIMapPtr; -typedef stdext::shared_object_ptr UIMinimapPtr; -typedef stdext::shared_object_ptr UIProgressRectPtr; -typedef stdext::shared_object_ptr UIMapAnchorLayoutPtr; -typedef stdext::shared_object_ptr UIPositionAnchorPtr; - -#endif diff --git a/src/client/effect.cpp b/src/client/effect.cpp deleted file mode 100644 index b650e90..0000000 --- a/src/client/effect.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "effect.h" -#include "map.h" -#include "game.h" -#include -#include - -void Effect::draw(const Point& dest, int offsetX, int offsetY, bool animate, LightView* lightView) -{ - if(m_id == 0) - return; - - if(animate) { - if(g_game.getFeature(Otc::GameEnhancedAnimations) && rawGetThingType()->getAnimator()) { - // This requires a separate getPhaseAt method as using getPhase would make all magic effects use the same phase regardless of their appearance time - m_animationPhase = rawGetThingType()->getAnimator()->getPhaseAt(m_animationTimer, m_animationPhase); - } else { - // hack to fix some animation phases duration, currently there is no better solution - int ticks = EFFECT_TICKS_PER_FRAME; - if (m_id == 33) { - ticks <<= 2; - } - - m_animationPhase = std::min((int)(m_animationTimer.ticksElapsed() / ticks), getAnimationPhases() - 1); - } - } - - int xPattern = m_position.x % getNumPatternX(); - if(xPattern < 0) - xPattern += getNumPatternX(); - - int yPattern = m_position.y % getNumPatternY(); - if(yPattern < 0) - yPattern += getNumPatternY(); - - rawGetThingType()->draw(dest, 0, xPattern, yPattern, 0, m_animationPhase, Color::white, lightView); -} - -void Effect::onAppear() -{ - m_animationTimer.restart(); - - int duration = 0; - if(g_game.getFeature(Otc::GameEnhancedAnimations)) { - duration = getThingType()->getAnimator() ? getThingType()->getAnimator()->getTotalDuration() : 1000; - } else { - duration = EFFECT_TICKS_PER_FRAME; - - // hack to fix some animation phases duration, currently there is no better solution - if(m_id == 33) { - duration <<= 2; - } - - duration *= getAnimationPhases(); - } - - // schedule removal - auto self = asEffect(); - g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, duration); -} - -void Effect::setId(uint32 id) -{ - if(!g_things.isValidDatId(id, ThingCategoryEffect)) - id = 0; - m_id = id; -} - -const ThingTypePtr& Effect::getThingType() -{ - return g_things.getThingType(m_id, ThingCategoryEffect); -} - -ThingType *Effect::rawGetThingType() -{ - return g_things.rawGetThingType(m_id, ThingCategoryEffect); -} diff --git a/src/client/effect.h b/src/client/effect.h deleted file mode 100644 index 2399499..0000000 --- a/src/client/effect.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef EFFECT_H -#define EFFECT_H - -#include -#include -#include "thing.h" - -// @bindclass -class Effect : public Thing -{ - enum { - EFFECT_TICKS_PER_FRAME = 75 - }; - -public: - void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr) override {} - void draw(const Point& dest, int offsetX = 0, int offsetY = 0, bool animate = true, LightView* lightView = nullptr); - - void setId(uint32 id) override; - uint32 getId() { return m_id; } - - EffectPtr asEffect() { return static_self_cast(); } - bool isEffect() { return true; } - - const ThingTypePtr& getThingType() override; - ThingType *rawGetThingType() override; - -protected: - void onAppear(); - -private: - uint16 m_id; - Timer m_animationTimer; - int m_animationPhase = 0; -}; - -#endif diff --git a/src/client/game.cpp b/src/client/game.cpp deleted file mode 100644 index 410dba0..0000000 --- a/src/client/game.cpp +++ /dev/null @@ -1,1648 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "game.h" -#include "localplayer.h" -#include "map.h" -#include "tile.h" -#include "creature.h" -#include "container.h" -#include "statictext.h" -#include -#include -#include -#include "luavaluecasts_client.h" -#include "protocolgame.h" -#include "protocolcodes.h" - -#include - -Game g_game; - -Game::Game() -{ - m_protocolVersion = 0; - m_clientCustomOs = -1; - m_clientVersion = 0; - m_online = false; - m_denyBotCall = false; - m_dead = false; - m_serverBeat = 50; - m_seq = 0; - m_ping = -1; - m_pingDelay = 1000; - m_newPingDelay = 250; - m_canReportBugs = false; - m_fightMode = Otc::FightBalanced; - m_chaseMode = Otc::DontChase; - m_pvpMode = Otc::WhiteDove; - m_safeFight = true; -} - -void Game::init() -{ - resetGameStates(); -} - -void Game::terminate() -{ - resetGameStates(); - m_protocolGame = nullptr; -} - -void Game::resetGameStates() -{ - m_online = false; - m_denyBotCall = false; - m_dead = false; - m_serverBeat = 50; - m_seq = 0; - m_ping = -1; - m_canReportBugs = false; - m_fightMode = Otc::FightBalanced; - m_chaseMode = Otc::DontChase; - m_pvpMode = Otc::WhiteDove; - m_safeFight = true; - m_followingCreature = nullptr; - m_attackingCreature = nullptr; - m_localPlayer = nullptr; - m_pingSent = 0; - m_pingReceived = 0; - m_walkId = 0; - m_walkPrediction = 0; - m_coins = 0; - m_transferableCoins = 0; - m_newPingIds.clear(); - m_unjustifiedPoints = UnjustifiedPoints(); - - for(auto& it : m_containers) { - const ContainerPtr& container = it.second; - if(container) - container->onClose(); - } - - if(m_pingEvent) { - m_pingEvent->cancel(); - m_pingEvent = nullptr; - } - - if (m_newPingEvent) { - m_newPingEvent->cancel(); - m_newPingEvent = nullptr; - } - - if(m_checkConnectionEvent) { - m_checkConnectionEvent->cancel(); - m_checkConnectionEvent = nullptr; - } - - m_containers.clear(); - m_vips.clear(); - m_gmActions.clear(); - g_map.resetAwareRange(); -} - -void Game::processConnectionError(const boost::system::error_code& ec) -{ - // connection errors only have meaning if we still have a protocol - if(m_protocolGame) { - // eof = end of file, a clean disconnect - if(ec != asio::error::eof) - g_lua.callGlobalField("g_game", "onConnectionError", ec.message(), ec.value()); - - processDisconnect(); - } -} - -void Game::processDisconnect() -{ - if(isOnline()) - processGameEnd(); - - if(m_protocolGame) { - m_protocolGame->disconnect(); - m_protocolGame = nullptr; - } -} - -void Game::processUpdateNeeded(const std::string& signature) -{ - g_lua.callGlobalField("g_game", "onUpdateNeeded", signature); -} - -void Game::processLoginError(const std::string& error) -{ - g_lua.callGlobalField("g_game", "onLoginError", error); -} - -void Game::processLoginAdvice(const std::string& message) -{ - g_lua.callGlobalField("g_game", "onLoginAdvice", message); -} - -void Game::processLoginWait(const std::string& message, int time) -{ - g_lua.callGlobalField("g_game", "onLoginWait", message, time); -} - -void Game::processLoginToken(bool unknown) -{ - g_lua.callGlobalField("g_game", "onLoginToken", unknown); -} - -void Game::processLogin() -{ - g_lua.callGlobalField("g_game", "onLogin"); -} - -void Game::processPendingGame() -{ - m_localPlayer->setPendingGame(true); - g_lua.callGlobalField("g_game", "onPendingGame"); - m_protocolGame->sendEnterGame(); -} - -void Game::processEnterGame() -{ - m_localPlayer->setPendingGame(false); - g_lua.callGlobalField("g_game", "onEnterGame"); -} - -void Game::processGameStart() -{ - m_online = true; - - // synchronize fight modes with the server - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); - - // NOTE: the entire map description and local player information is not known yet (bot call is allowed here) - enableBotCall(); - g_lua.callGlobalField("g_game", "onGameStart"); - disableBotCall(); - - if (g_game.getFeature(Otc::GameExtendedClientPing)) { - m_newPingEvent = g_dispatcher.scheduleEvent([] { - g_game.newPing(); - }, m_newPingDelay); - } - if(g_game.getFeature(Otc::GameClientPing)) { - m_pingEvent = g_dispatcher.scheduleEvent([] { - g_game.ping(); - }, m_pingDelay); - } - - m_checkConnectionEvent = g_dispatcher.cycleEvent([this] { - if(!g_game.isConnectionOk() && !m_connectionFailWarned) { - g_lua.callGlobalField("g_game", "onConnectionFailing", true); - m_connectionFailWarned = true; - } else if(g_game.isConnectionOk() && m_connectionFailWarned) { - g_lua.callGlobalField("g_game", "onConnectionFailing", false); - m_connectionFailWarned = false; - } - }, 1000); -} - -void Game::processGameEnd() -{ - m_online = false; - g_lua.callGlobalField("g_game", "onGameEnd"); - - if(m_connectionFailWarned) { - g_lua.callGlobalField("g_game", "onConnectionFailing", false); - m_connectionFailWarned = false; - } - - // reset game state - resetGameStates(); - - m_worldName = ""; - m_characterName = ""; - - // clean map creatures - g_map.cleanDynamicThings(); -} - -void Game::processDeath(int deathType, int penality) -{ - m_dead = true; - m_localPlayer->stopWalk(); - - g_lua.callGlobalField("g_game", "onDeath", deathType, penality); -} - -void Game::processGMActions(const std::vector& actions) -{ - m_gmActions = actions; - g_lua.callGlobalField("g_game", "onGMActions", actions); -} - -void Game::processPlayerHelpers(int helpers) -{ - g_lua.callGlobalField("g_game", "onPlayerHelpersUpdate", helpers); -} - -void Game::processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode, Otc::PVPModes pvpMode) -{ - m_fightMode = fightMode; - m_chaseMode = chaseMode; - m_safeFight = safeMode; - m_pvpMode = pvpMode; - - g_lua.callGlobalField("g_game", "onFightModeChange", fightMode); - g_lua.callGlobalField("g_game", "onChaseModeChange", chaseMode); - g_lua.callGlobalField("g_game", "onSafeFightChange", safeMode); - g_lua.callGlobalField("g_game", "onPVPModeChange", pvpMode); -} - -void Game::processPing() -{ - g_lua.callGlobalField("g_game", "onPing"); - enableBotCall(); - m_protocolGame->sendPingBack(); - disableBotCall(); -} - -void Game::processPingBack() -{ - m_pingReceived++; - - if (!g_game.getFeature(Otc::GameExtendedClientPing)) { - if (m_pingReceived == m_pingSent) - m_ping = m_pingTimer.elapsed_millis(); - - g_lua.callGlobalField("g_game", "onPingBack", m_ping); - } - - m_pingEvent = g_dispatcher.scheduleEvent([] { - g_game.ping(); - }, m_pingDelay); -} - -void Game::processNewPing(uint32_t pingId) -{ - auto it = m_newPingIds.find(pingId); - - if (it == m_newPingIds.end()) - return; - - m_ping = it->second.elapsed_millis(); - g_lua.callGlobalField("g_game", "onPingBack", m_ping); -} - -void Game::processTextMessage(Otc::MessageMode mode, const std::string& text) -{ - g_lua.callGlobalField("g_game", "onTextMessage", mode, text); -} - -void Game::processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos) -{ - g_lua.callGlobalField("g_game", "onTalk", name, level, mode, text, channelId, pos); -} - -void Game::processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector& items, bool isUnlocked, bool hasPages, int containerSize, int firstIndex) -{ - ContainerPtr previousContainer = getContainer(containerId); - ContainerPtr container = ContainerPtr(new Container(containerId, capacity, name, containerItem, hasParent, isUnlocked, hasPages, containerSize, firstIndex)); - m_containers[containerId] = container; - container->onAddItems(items); - - // we might want to close a container here - enableBotCall(); - container->onOpen(previousContainer); - disableBotCall(); - - if(previousContainer) - previousContainer->onClose(); -} - -void Game::processCloseContainer(int containerId) -{ - ContainerPtr container = getContainer(containerId); - if(!container) { - return; - } - - m_containers[containerId] = nullptr; - container->onClose(); -} - -void Game::processContainerAddItem(int containerId, const ItemPtr& item, int slot) -{ - ContainerPtr container = getContainer(containerId); - if(!container) { - return; - } - - container->onAddItem(item, slot); -} - -void Game::processContainerUpdateItem(int containerId, int slot, const ItemPtr& item) -{ - ContainerPtr container = getContainer(containerId); - if(!container) { - return; - } - - container->onUpdateItem(slot, item); -} - -void Game::processContainerRemoveItem(int containerId, int slot, const ItemPtr& lastItem) -{ - ContainerPtr container = getContainer(containerId); - if(!container) { - return; - } - - container->onRemoveItem(slot, lastItem); -} - -void Game::processInventoryChange(int slot, const ItemPtr& item) -{ - if(item) - item->setPosition(Position(65535, slot, 0)); - - m_localPlayer->setInventoryItem((Otc::InventorySlot)slot, item); -} - -void Game::processChannelList(const std::vector >& channelList) -{ - g_lua.callGlobalField("g_game", "onChannelList", channelList); -} - -void Game::processOpenChannel(int channelId, const std::string& name) -{ - g_lua.callGlobalField("g_game", "onOpenChannel", channelId, name); -} - -void Game::processOpenPrivateChannel(const std::string& name) -{ - g_lua.callGlobalField("g_game", "onOpenPrivateChannel", name); -} - -void Game::processOpenOwnPrivateChannel(int channelId, const std::string& name) -{ - g_lua.callGlobalField("g_game", "onOpenOwnPrivateChannel", channelId, name); -} - -void Game::processCloseChannel(int channelId) -{ - g_lua.callGlobalField("g_game", "onCloseChannel", channelId); -} - -void Game::processRuleViolationChannel(int channelId) -{ - g_lua.callGlobalField("g_game", "onRuleViolationChannel", channelId); -} - -void Game::processRuleViolationRemove(const std::string& name) -{ - g_lua.callGlobalField("g_game", "onRuleViolationRemove", name); -} - -void Game::processRuleViolationCancel(const std::string& name) -{ - g_lua.callGlobalField("g_game", "onRuleViolationCancel", name); -} - -void Game::processRuleViolationLock() -{ - g_lua.callGlobalField("g_game", "onRuleViolationLock"); -} - -void Game::processVipAdd(uint id, const std::string& name, uint status, const std::string& description, int iconId, bool notifyLogin) -{ - m_vips[id] = Vip(name, status, description, iconId, notifyLogin); - g_lua.callGlobalField("g_game", "onAddVip", id, name, status, description, iconId, notifyLogin); -} - -void Game::processVipStateChange(uint id, uint status) -{ - if (m_vips.find(id) == m_vips.end()) return; - std::get<1>(m_vips[id]) = status; - g_lua.callGlobalField("g_game", "onVipStateChange", id, status); -} - -void Game::processTutorialHint(int id) -{ - g_lua.callGlobalField("g_game", "onTutorialHint", id); -} - -void Game::processAddAutomapFlag(const Position& pos, int icon, const std::string& message) -{ - g_lua.callGlobalField("g_game", "onAddAutomapFlag", pos, icon, message); -} - -void Game::processRemoveAutomapFlag(const Position& pos, int icon, const std::string& message) -{ - g_lua.callGlobalField("g_game", "onRemoveAutomapFlag", pos, icon, message); -} - -void Game::processOpenOutfitWindow(const Outfit& currentOutfit, const std::vector >& outfitList, - const std::vector >& mountList) -{ - // create virtual creature outfit - CreaturePtr virtualOutfitCreature = CreaturePtr(new Creature); - virtualOutfitCreature->setDirection(Otc::South); - - Outfit outfit = currentOutfit; - outfit.setMount(0); - virtualOutfitCreature->setOutfit(outfit); - - // creature virtual mount outfit - CreaturePtr virtualMountCreature = nullptr; - if(getFeature(Otc::GamePlayerMounts)) - { - virtualMountCreature = CreaturePtr(new Creature); - virtualMountCreature->setDirection(Otc::South); - - Outfit mountOutfit; - mountOutfit.setId(0); - - int mount = currentOutfit.getMount(); - if(mount > 0) - mountOutfit.setId(mount); - - virtualMountCreature->setOutfit(mountOutfit); - } - - g_lua.callGlobalField("g_game", "onOpenOutfitWindow", virtualOutfitCreature, outfitList, virtualMountCreature, mountList); -} - -void Game::processOpenNpcTrade(const std::vector >& items) -{ - g_lua.callGlobalField("g_game", "onOpenNpcTrade", items); -} - -void Game::processPlayerGoods(uint64_t money, const std::vector >& goods) -{ - g_lua.callGlobalField("g_game", "onPlayerGoods", money, goods); -} - -void Game::processCloseNpcTrade() -{ - g_lua.callGlobalField("g_game", "onCloseNpcTrade"); -} - -void Game::processOwnTrade(const std::string& name, const std::vector& items) -{ - g_lua.callGlobalField("g_game", "onOwnTrade", name, items); -} - -void Game::processCounterTrade(const std::string& name, const std::vector& items) -{ - g_lua.callGlobalField("g_game", "onCounterTrade", name, items); -} - -void Game::processCloseTrade() -{ - g_lua.callGlobalField("g_game", "onCloseTrade"); -} - -void Game::processEditText(uint id, int itemId, int maxLength, const std::string& text, const std::string& writer, const std::string& date) -{ - g_lua.callGlobalField("g_game", "onEditText", id, itemId, maxLength, text, writer, date); -} - -void Game::processEditList(uint id, int doorId, const std::string& text) -{ - g_lua.callGlobalField("g_game", "onEditList", id, doorId, text); -} - -void Game::processQuestLog(const std::vector >& questList) -{ - g_lua.callGlobalField("g_game", "onQuestLog", questList); -} - -void Game::processQuestLine(int questId, const std::vector >& questMissions) -{ - g_lua.callGlobalField("g_game", "onQuestLine", questId, questMissions); -} - -void Game::processModalDialog(uint32 id, std::string title, std::string message, std::vector > buttonList, int enterButton, int escapeButton, std::vector > choiceList, bool priority) -{ - g_lua.callGlobalField("g_game", "onModalDialog", id, title, message, buttonList, enterButton, escapeButton, choiceList, priority); -} - -void Game::processAttackCancel(uint seq) -{ - if(seq == 0 || m_seq == seq) - cancelAttack(); -} - -void Game::processWalkCancel(Otc::Direction direction) -{ - m_localPlayer->cancelWalk(direction); -} - -void Game::processNewWalkCancel(Otc::Direction dir) -{ - m_walkId += 1; - m_localPlayer->cancelNewWalk(dir); -} - -void Game::processPredictiveWalkCancel(const Position& pos, Otc::Direction dir) -{ - m_walkPrediction += 1; - if (m_localPlayer->predictiveCancelWalk(pos, m_walkPrediction, dir)) { - m_walkId += 1; - } -} - -void Game::processWalkId(uint32_t walkId) -{ - m_walkId = std::max(m_walkId, walkId); // fixes desync -} - -void Game::loginWorld(const std::string& account, const std::string& password, const std::string& worldName, const std::string& worldHost, int worldPort, const std::string& characterName, const std::string& authenticatorToken, const std::string& sessionKey) -{ - if(m_protocolGame || isOnline()) - stdext::throw_exception("Unable to login into a world while already online or logging."); - - if(m_protocolVersion == 0) - stdext::throw_exception("Must set a valid game protocol version before logging."); - - // reset the new game state - resetGameStates(); - - m_localPlayer = LocalPlayerPtr(new LocalPlayer); - m_localPlayer->setName(characterName); - - m_protocolGame = ProtocolGamePtr(new ProtocolGame); - m_protocolGame->login(account, password, worldHost, (uint16)worldPort, characterName, authenticatorToken, sessionKey); - m_characterName = characterName; - m_worldName = worldName; -} - -void Game::cancelLogin() -{ - // send logout even if the game has not started yet, to make sure that the player doesn't stay logged there - if(m_protocolGame) - m_protocolGame->sendLogout(); - - g_lua.callGlobalField("g_game", "onLogout"); - processDisconnect(); -} - -void Game::forceLogout() -{ - if(!isOnline()) - return; - - g_lua.callGlobalField("g_game", "onLogout"); - m_protocolGame->sendLogout(); - processDisconnect(); -} - -void Game::safeLogout() -{ - if(!isOnline()) - return; - - g_lua.callGlobalField("g_game", "onLogout"); - m_protocolGame->sendLogout(); -} - -void Game::autoWalk(const std::vector& dirs, Position startPos) -{ - if(!canPerformGameAction()) - return; - - if (dirs.size() == 0) - return; - - // protocol limits walk path - if((!g_game.getFeature(Otc::GameNewWalking) || dirs.size() > 4097) && dirs.size() > 127) { - g_logger.error("Auto walk path too great"); - return; - } - - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] Game::autoWalk", (int)g_clock.millis())); - } - - // must cancel follow before any new walk - if (isFollowing()) { - cancelFollow(); - } - - auto it = dirs.begin(); - Otc::Direction direction = *it; - - uint8_t flags = 0x04; // auto walk flag - - TilePtr toTile = g_map.getTile(startPos.translatedToDirection(direction)); - if(startPos == m_localPlayer->getPrewalkingPosition() && toTile && toTile->isWalkable() && !m_localPlayer->isWalking() && m_localPlayer->canWalk(direction, true)) { - m_localPlayer->preWalk(direction); - m_localPlayer->startServerWalking(); - flags |= 0x01; // prewalk flag - } - - g_lua.callGlobalField("g_game", "onAutoWalk", dirs); - - if (g_game.getFeature(Otc::GameNewWalking)) - m_protocolGame->sendNewWalk(m_walkId, m_walkPrediction, startPos, flags, dirs); - else - m_protocolGame->sendAutoWalk(dirs); -} - -void Game::walk(Otc::Direction direction, bool withPreWalk) -{ - m_denyBotCall = false; - if (!canPerformGameAction()) { - m_denyBotCall = true; - return; - } - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] Game::walk", (int)g_clock.millis())); - } - - g_lua.callGlobalField("g_game", "onWalk", direction, withPreWalk); - - if (g_game.getFeature(Otc::GameNewWalking)) { - //hidden - return; - } - - switch(direction) { - case Otc::North: - m_protocolGame->sendWalkNorth(); - break; - case Otc::East: - m_protocolGame->sendWalkEast(); - break; - case Otc::South: - m_protocolGame->sendWalkSouth(); - break; - case Otc::West: - m_protocolGame->sendWalkWest(); - break; - case Otc::NorthEast: - m_protocolGame->sendWalkNorthEast(); - break; - case Otc::SouthEast: - m_protocolGame->sendWalkSouthEast(); - break; - case Otc::SouthWest: - m_protocolGame->sendWalkSouthWest(); - break; - case Otc::NorthWest: - m_protocolGame->sendWalkNorthWest(); - break; - default: - break; - } - m_denyBotCall = true; -} - -void Game::turn(Otc::Direction direction) -{ - m_denyBotCall = false; - if (!canPerformGameAction()) { - m_denyBotCall = true; - return; - } - - if (g_game.getFeature(Otc::GameNewWalking)) { - m_localPlayer->setDirection(direction); - } - - switch(direction) { - case Otc::North: - m_protocolGame->sendTurnNorth(); - break; - case Otc::East: - m_protocolGame->sendTurnEast(); - break; - case Otc::South: - m_protocolGame->sendTurnSouth(); - break; - case Otc::West: - m_protocolGame->sendTurnWest(); - break; - default: - break; - } - m_denyBotCall = true; -} - -void Game::stop() -{ - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] Game::stop", (int)g_clock.millis())); - } - - m_denyBotCall = false; - if (!canPerformGameAction()) { - m_denyBotCall = true; - return; - } - - if(isFollowing()) - cancelFollow(); // can change m_denyBotCall - m_denyBotCall = false; - - m_protocolGame->sendStop(); - m_denyBotCall = true; -} - -void Game::look(const ThingPtr& thing, bool isBattleList) -{ - if(!canPerformGameAction() || !thing) - return; - - if(thing->isCreature() && isBattleList && m_protocolVersion >= 961) - m_protocolGame->sendLookCreature(thing->getId()); - else - m_protocolGame->sendLook(thing->getPosition(), thing->getId(), thing->getStackPos()); -} - -void Game::move(const ThingPtr& thing, const Position& toPos, int count) -{ - if (count <= 0) - count = 1; - - if (!canPerformGameAction() || !thing || thing->getPosition() == toPos) - return; - - uint id = thing->getId(); - if (thing->isCreature()) { - CreaturePtr creature = thing->static_self_cast(); - id = Proto::Creature; - } - - m_protocolGame->sendMove(thing->getPosition(), id, thing->getStackPos(), toPos, count); -} - -void Game::moveRaw(const Position& pos, int id, int stackpos, const Position& toPos, int count) -{ - if (!canPerformGameAction()) - return; - - m_protocolGame->sendMove(pos, id, stackpos, toPos, count); -} - -void Game::moveToParentContainer(const ThingPtr& thing, int count) -{ - if(!canPerformGameAction() || !thing || count <= 0) - return; - - Position position = thing->getPosition(); - move(thing, Position(position.x, position.y, 254), count); -} - -void Game::rotate(const ThingPtr& thing) -{ - if(!canPerformGameAction() || !thing) - return; - - m_protocolGame->sendRotateItem(thing->getPosition(), thing->getId(), thing->getStackPos()); -} - -void Game::wrap(const ThingPtr& thing) -{ - if (!canPerformGameAction() || !thing) - return; - - m_protocolGame->sendWrapableItem(thing->getPosition(), thing->getId(), thing->getStackPos()); -} - -void Game::use(const ThingPtr& thing) -{ - if(!canPerformGameAction() || !thing) - return; - - Position pos = thing->getPosition(); - if(!pos.isValid()) // virtual item - pos = Position(0xFFFF, 0, 0); // inventory item - - // some items, e.g. parcel, are not set as containers but they are. - // always try to use these items in free container slots. - m_protocolGame->sendUseItem(pos, thing->getId(), thing->getStackPos(), findEmptyContainerId()); - - g_lua.callGlobalField("g_game", "onUse", pos, thing->getId(), thing->getStackPos(), 0); -} - -void Game::useInventoryItem(int itemId, int subType) -{ - if(!canPerformGameAction() || !g_things.isValidDatId(itemId, ThingCategoryItem)) - return; - - Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory - - m_protocolGame->sendUseItem(pos, itemId, 0, subType); - - g_lua.callGlobalField("g_game", "onUse", pos, itemId, 0, subType); -} - -void Game::useWith(const ItemPtr& item, const ThingPtr& toThing, int subType) -{ - if(!canPerformGameAction() || !item || !toThing) - return; - - Position pos = item->getPosition(); - if(!pos.isValid()) // virtual item - pos = Position(0xFFFF, 0, 0); // means that is an item in inventory - - if(toThing->isCreature() && g_game.getProtocolVersion() >= 780) - m_protocolGame->sendUseOnCreature(pos, item->getId(), subType ? subType : item->getStackPos(), toThing->getId()); - else - m_protocolGame->sendUseItemWith(pos, item->getId(), subType ? subType : item->getStackPos(), toThing->getPosition(), toThing->getId(), toThing->getStackPos()); - - g_lua.callGlobalField("g_game", "onUseWith", pos, item->getId(), toThing, subType); -} - -void Game::useInventoryItemWith(int itemId, const ThingPtr& toThing, int subType) -{ - if(!canPerformGameAction() || !toThing) - return; - - Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory - - if(toThing->isCreature()) - m_protocolGame->sendUseOnCreature(pos, itemId, subType, toThing->getId()); - else - m_protocolGame->sendUseItemWith(pos, itemId, subType, toThing->getPosition(), toThing->getId(), toThing->getStackPos()); - - g_lua.callGlobalField("g_game", "onUseWith", pos, itemId, toThing, subType); -} - -ItemPtr Game::findItemInContainers(uint itemId, int subType) -{ - for(auto& it : m_containers) { - const ContainerPtr& container = it.second; - - if(container) { - ItemPtr item = container->findItemById(itemId, subType); - if(item != nullptr) - return item; - } - } - return nullptr; -} - -int Game::open(const ItemPtr& item, const ContainerPtr& previousContainer) -{ - if(!canPerformGameAction() || !item) - return -1; - - int id = 0; - if(!previousContainer) - id = findEmptyContainerId(); - else - id = previousContainer->getId(); - - m_protocolGame->sendUseItem(item->getPosition(), item->getId(), item->getStackPos(), id); - return id; -} - -void Game::openParent(const ContainerPtr& container) -{ - if(!canPerformGameAction() || !container) - return; - - m_protocolGame->sendUpContainer(container->getId()); -} - -void Game::close(const ContainerPtr& container) -{ - if(!canPerformGameAction() || !container) - return; - - m_protocolGame->sendCloseContainer(container->getId()); -} - -void Game::refreshContainer(const ContainerPtr& container) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRefreshContainer(container->getId()); -} - -void Game::attack(CreaturePtr creature, bool cancel) -{ - if(!canPerformGameAction() || creature == m_localPlayer) - return; - - // cancel when attacking again - if(creature && creature == m_attackingCreature) - creature = nullptr; - - if(creature && isFollowing()) - cancelFollow(); - - setAttackingCreature(creature); - m_localPlayer->stopAutoWalk(); - - if(m_protocolVersion >= 963) { - if(creature) - m_seq = creature->getId(); - } else - m_seq++; - - if(!cancel) - m_protocolGame->sendAttack(creature ? creature->getId() : 0, m_seq); -} - -void Game::follow(CreaturePtr creature) -{ - m_denyBotCall = false; - if (!canPerformGameAction() || creature == m_localPlayer) { - m_denyBotCall = true; - return; - } - - // cancel when following again - if(creature && creature == m_followingCreature) - creature = nullptr; - - if(creature && isAttacking()) - cancelAttack(); - - setFollowingCreature(creature); - m_localPlayer->stopAutoWalk(); - - if(m_protocolVersion >= 963) { - if(creature) - m_seq = creature->getId(); - } else - m_seq++; - - m_protocolGame->sendFollow(creature ? creature->getId() : 0, m_seq); - m_denyBotCall = true; -} - -void Game::cancelAttackAndFollow() -{ - if(!canPerformGameAction()) - return; - - if(isFollowing()) - setFollowingCreature(nullptr); - if(isAttacking()) - setAttackingCreature(nullptr); - - m_localPlayer->stopAutoWalk(); - - m_protocolGame->sendCancelAttackAndFollow(); - - g_lua.callGlobalField("g_game", "onCancelAttackAndFollow"); -} - -void Game::talk(const std::string& message) -{ - if(!canPerformGameAction() || message.empty()) - return; - - talkChannel(Otc::MessageSay, 0, message); -} - -void Game::talkChannel(Otc::MessageMode mode, int channelId, const std::string& message) -{ - if(!canPerformGameAction() || message.empty()) - return; - - m_protocolGame->sendTalk(mode, channelId, "", message, m_localPlayer->getPosition(), m_localPlayer->getDirection()); -} - -void Game::talkPrivate(Otc::MessageMode mode, const std::string& receiver, const std::string& message) -{ - if(!canPerformGameAction() || receiver.empty() || message.empty()) - return; - m_protocolGame->sendTalk(mode, 0, receiver, message, m_localPlayer->getPosition(), m_localPlayer->getDirection()); -} - -void Game::openPrivateChannel(const std::string& receiver) -{ - if(!canPerformGameAction() || receiver.empty()) - return; - m_protocolGame->sendOpenPrivateChannel(receiver); -} - -void Game::requestChannels() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRequestChannels(); -} - -void Game::joinChannel(int channelId) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendJoinChannel(channelId); -} - -void Game::leaveChannel(int channelId) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendLeaveChannel(channelId); -} - -void Game::closeNpcChannel() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendCloseNpcChannel(); -} - -void Game::openOwnChannel() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendOpenOwnChannel(); -} - -void Game::inviteToOwnChannel(const std::string& name) -{ - if(!canPerformGameAction() || name.empty()) - return; - m_protocolGame->sendInviteToOwnChannel(name); -} - -void Game::excludeFromOwnChannel(const std::string& name) -{ - if(!canPerformGameAction() || name.empty()) - return; - m_protocolGame->sendExcludeFromOwnChannel(name); -} - -void Game::partyInvite(int creatureId) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendInviteToParty(creatureId); -} - -void Game::partyJoin(int creatureId) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendJoinParty(creatureId); -} - -void Game::partyRevokeInvitation(int creatureId) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRevokeInvitation(creatureId); -} - -void Game::partyPassLeadership(int creatureId) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendPassLeadership(creatureId); -} - -void Game::partyLeave() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendLeaveParty(); -} - -void Game::partyShareExperience(bool active) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendShareExperience(active); -} - -void Game::requestOutfit() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRequestOutfit(); -} - -void Game::changeOutfit(const Outfit& outfit) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendChangeOutfit(outfit); -} - -void Game::addVip(const std::string& name) -{ - if(!canPerformGameAction() || name.empty()) - return; - m_protocolGame->sendAddVip(name); -} - -void Game::removeVip(int playerId) -{ - if(!canPerformGameAction()) - return; - - auto it = m_vips.find(playerId); - if(it == m_vips.end()) - return; - m_vips.erase(it); - m_protocolGame->sendRemoveVip(playerId); -} - -void Game::editVip(int playerId, const std::string& description, int iconId, bool notifyLogin) -{ - if(!canPerformGameAction()) - return; - - auto it = m_vips.find(playerId); - if(it == m_vips.end()) - return; - - std::get<2>(m_vips[playerId]) = description; - std::get<3>(m_vips[playerId]) = iconId; - std::get<4>(m_vips[playerId]) = notifyLogin; - - if(getFeature(Otc::GameAdditionalVipInfo)) - m_protocolGame->sendEditVip(playerId, description, iconId, notifyLogin); -} - -void Game::setChaseMode(Otc::ChaseModes chaseMode) -{ - if(!canPerformGameAction()) - return; - if(m_chaseMode == chaseMode) - return; - m_chaseMode = chaseMode; - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); - g_lua.callGlobalField("g_game", "onChaseModeChange", chaseMode); -} - -void Game::setFightMode(Otc::FightModes fightMode) -{ - if(!canPerformGameAction()) - return; - if(m_fightMode == fightMode) - return; - m_fightMode = fightMode; - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); - g_lua.callGlobalField("g_game", "onFightModeChange", fightMode); -} - -void Game::setSafeFight(bool on) -{ - if(!canPerformGameAction()) - return; - if(m_safeFight == on) - return; - m_safeFight = on; - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); - g_lua.callGlobalField("g_game", "onSafeFightChange", on); -} - -void Game::setPVPMode(Otc::PVPModes pvpMode) -{ - if(!canPerformGameAction()) - return; - if(!getFeature(Otc::GamePVPMode)) - return; - if(m_pvpMode == pvpMode) - return; - m_pvpMode = pvpMode; - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); - g_lua.callGlobalField("g_game", "onPVPModeChange", pvpMode); -} - -void Game::setUnjustifiedPoints(UnjustifiedPoints unjustifiedPoints) -{ - if(!canPerformGameAction()) - return; - if(!getFeature(Otc::GameUnjustifiedPoints)) - return; - if(m_unjustifiedPoints == unjustifiedPoints) - return; - - m_unjustifiedPoints = unjustifiedPoints; - g_lua.callGlobalField("g_game", "onUnjustifiedPointsChange", unjustifiedPoints); -} - -void Game::setOpenPvpSituations(int openPvpSituations) -{ - if(!canPerformGameAction()) - return; - if(m_openPvpSituations == openPvpSituations) - return; - - m_openPvpSituations = openPvpSituations; - g_lua.callGlobalField("g_game", "onOpenPvpSituationsChange", openPvpSituations); -} - - -void Game::inspectNpcTrade(const ItemPtr& item) -{ - if(!canPerformGameAction() || !item) - return; - m_protocolGame->sendInspectNpcTrade(item->getId(), item->getCount()); -} - -void Game::buyItem(const ItemPtr& item, int amount, bool ignoreCapacity, bool buyWithBackpack) -{ - if(!canPerformGameAction() || !item) - return; - m_protocolGame->sendBuyItem(item->getId(), item->getCountOrSubType(), amount, ignoreCapacity, buyWithBackpack); -} - -void Game::sellItem(const ItemPtr& item, int amount, bool ignoreEquipped) -{ - if(!canPerformGameAction() || !item) - return; - m_protocolGame->sendSellItem(item->getId(), item->getCountOrSubType(), amount, ignoreEquipped); -} - -void Game::closeNpcTrade() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendCloseNpcTrade(); -} - -void Game::requestTrade(const ItemPtr& item, const CreaturePtr& creature) -{ - if(!canPerformGameAction() || !item || !creature) - return; - m_protocolGame->sendRequestTrade(item->getPosition(), item->getId(), item->getStackPos(), creature->getId()); -} - -void Game::inspectTrade(bool counterOffer, int index) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendInspectTrade(counterOffer, index); -} - -void Game::acceptTrade() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendAcceptTrade(); -} - -void Game::rejectTrade() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRejectTrade(); -} - -void Game::editText(uint id, const std::string& text) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendEditText(id, text); -} - -void Game::editList(uint id, int doorId, const std::string& text) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendEditList(id, doorId, text); -} - -void Game::openRuleViolation(const std::string& reporter) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendOpenRuleViolation(reporter); -} - -void Game::closeRuleViolation(const std::string& reporter) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendCloseRuleViolation(reporter); -} - -void Game::cancelRuleViolation() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendCancelRuleViolation(); -} - -void Game::reportBug(const std::string& comment) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendBugReport(comment); -} - -void Game::reportRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRuleViolation(target, reason, action, comment, statement, statementId, ipBanishment); -} - -void Game::debugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d) -{ - m_protocolGame->sendDebugReport(a, b, c, d); -} - -void Game::requestQuestLog() -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRequestQuestLog(); -} - -void Game::requestQuestLine(int questId) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRequestQuestLine(questId); -} - -void Game::equipItem(const ItemPtr& item) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendEquipItem(item->getId(), item->getCountOrSubType()); -} - -void Game::mount(bool mount) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendOutfitExtensionStatus(mount ? 1 : 0); -} - -void Game::setOutfitExtensions(int mount, int wings, int aura, int shader) -{ - if (!canPerformGameAction()) - return; - m_protocolGame->sendOutfitExtensionStatus(mount, wings, aura, shader); -} - -void Game::requestItemInfo(const ItemPtr& item, int index) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRequestItemInfo(item->getId(), item->getSubType(), index); -} - -void Game::answerModalDialog(uint32 dialog, int button, int choice) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendAnswerModalDialog(dialog, button, choice); -} - -void Game::browseField(const Position& position) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendBrowseField(position); -} - -void Game::seekInContainer(int cid, int index) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendSeekInContainer(cid, index); -} - -void Game::buyStoreOffer(int offerId, int productType, const std::string& name) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendBuyStoreOffer(offerId, productType, name); -} - -void Game::requestTransactionHistory(int page, int entriesPerPage) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRequestTransactionHistory(page, entriesPerPage); -} - -void Game::requestStoreOffers(const std::string& categoryName, int serviceType) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendRequestStoreOffers(categoryName, serviceType); -} - -void Game::openStore(int serviceType) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendOpenStore(serviceType); -} - -void Game::transferCoins(const std::string& recipient, int amount) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendTransferCoins(recipient, amount); -} - -void Game::openTransactionHistory(int entriesPerPage) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendOpenTransactionHistory(entriesPerPage); -} - -void Game::preyAction(int slot, int actionType, int index) -{ - if (!canPerformGameAction()) - return; - m_protocolGame->sendPreyAction(slot, actionType, index); -} - -void Game::preyRequest() -{ - if (!canPerformGameAction()) - return; - m_protocolGame->sendPreyRequest(); -} - - -void Game::applyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm) -{ - if (!canPerformGameAction()) - return; - m_protocolGame->sendApplyImbuement(slot, imbuementId, protectionCharm); -} - -void Game::clearImbuement(uint8_t slot) -{ - if (!canPerformGameAction()) - return; - m_protocolGame->sendClearImbuement(slot); -} - -void Game::closeImbuingWindow() -{ - if (!canPerformGameAction()) - return; - m_protocolGame->sendCloseImbuingWindow(); -} - -void Game::ping() -{ - if(!m_protocolGame || !m_protocolGame->isConnected()) - return; - - if(m_pingReceived != m_pingSent) - return; - - m_denyBotCall = false; - m_protocolGame->sendPing(); - m_denyBotCall = true; - m_pingSent++; - m_pingTimer.restart(); -} - -void Game::newPing() -{ - if(!m_protocolGame || !m_protocolGame->isConnected()) - return; - - static uint32_t pingId = 1; - pingId += 1; - m_newPingIds[pingId] = stdext::timer(); - - m_protocolGame->sendNewPing(pingId, (int16_t)m_ping, (int16_t)g_app.getFps()); - m_newPingEvent = g_dispatcher.scheduleEvent([] { - g_game.newPing(); - }, m_newPingDelay); -} - -void Game::changeMapAwareRange(int xrange, int yrange) -{ - if(!canPerformGameAction()) - return; - m_protocolGame->sendChangeMapAwareRange(xrange, yrange); -} - -bool Game::checkBotProtection() -{ - if (getFeature(Otc::GameBotProtection)) { - // accepts calls comming from a stacktrace containing only C++ functions, - // if the stacktrace contains a lua function, then only accept if the engine is processing an input event - if (m_denyBotCall && g_lua.isInCppCallback() && !g_app.isOnInputEvent() && !g_dispatcher.isBotSafe()) { - g_logger.error(g_lua.traceback("caught a lua call to a bot protected game function, the call was cancelled")); - return false; - } - } - - return true; -} - -bool Game::canPerformGameAction() -{ - // we can only perform game actions if we meet these conditions: - // - the game is online - // - the local player exists - // - the local player is not dead - // - we have a game protocol - // - the game protocol is connected - // - its not a bot action - return m_online && m_localPlayer && !m_localPlayer->isDead() && !m_dead && m_protocolGame && m_protocolGame->isConnected() && checkBotProtection(); -} - -void Game::setProtocolVersion(int version) -{ - if(m_protocolVersion == version) - return; - - if(isOnline()) - stdext::throw_exception("Unable to change protocol version while online"); - - m_protocolVersion = version; - - Proto::buildMessageModesMap(version); - - g_lua.callGlobalField("g_game", "onProtocolVersionChange", version); -} - -void Game::setClientVersion(int version) -{ - if(isOnline()) - stdext::throw_exception("Unable to change client version while online"); - - m_clientVersion = version; - g_lua.callGlobalField("g_game", "onClientVersionChange", version); -} - -void Game::setAttackingCreature(const CreaturePtr& creature) -{ - if(creature != m_attackingCreature) { - CreaturePtr oldCreature = m_attackingCreature; - m_attackingCreature = creature; - - g_lua.callGlobalField("g_game", "onAttackingCreatureChange", creature, oldCreature); - } -} - -void Game::setFollowingCreature(const CreaturePtr& creature) -{ - CreaturePtr oldCreature = m_followingCreature; - m_followingCreature = creature; - - g_lua.callGlobalField("g_game", "onFollowingCreatureChange", creature, oldCreature); -} - -std::string Game::formatCreatureName(const std::string& name) -{ - std::string formatedName = name; - if(getFeature(Otc::GameFormatCreatureName) && name.length() > 0) { - bool upnext = true; - for(uint i=0;i= 0) - return m_clientCustomOs; - - if(g_app.getOs() == "windows") - return 20; - if(g_app.getOs() == "mac") - return 22; - if (g_app.getOs() == "android") - return 23; - if (g_app.getOs() == "ios") - return 24; - return 21; // linux -} diff --git a/src/client/game.h b/src/client/game.h deleted file mode 100644 index b1863ab..0000000 --- a/src/client/game.h +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef GAME_H -#define GAME_H - -#include "declarations.h" -#include "item.h" -#include "animatedtext.h" -#include "effect.h" -#include "creature.h" -#include "container.h" -#include "protocolgame.h" -#include "localplayer.h" -#include "outfit.h" -#include - -#include - -struct UnjustifiedPoints { - bool operator==(const UnjustifiedPoints& other) { - return killsDay == other.killsDay && - killsDayRemaining == other.killsDayRemaining && - killsWeek == other.killsWeek && - killsWeekRemaining == other.killsWeekRemaining && - killsMonth == other.killsMonth && - killsMonthRemaining == other.killsMonthRemaining && - skullTime == other.skullTime; - } - uint8 killsDay; - uint8 killsDayRemaining; - uint8 killsWeek; - uint8 killsWeekRemaining; - uint8 killsMonth; - uint8 killsMonthRemaining; - uint8 skullTime; -}; - -typedef std::tuple Vip; - -//@bindsingleton g_game -class Game -{ -public: - Game(); - - void init(); - void terminate(); - -private: - void resetGameStates(); - -protected: - void processConnectionError(const boost::system::error_code& error); - void processDisconnect(); - void processPing(); - void processPingBack(); - void processNewPing(uint32_t pingId); - - void processUpdateNeeded(const std::string& signature); - void processLoginError(const std::string& error); - void processLoginAdvice(const std::string& message); - void processLoginWait(const std::string& message, int time); - void processLoginToken(bool unknown); - void processLogin(); - void processPendingGame(); - void processEnterGame(); - - void processGameStart(); - void processGameEnd(); - void processDeath(int deathType, int penality); - - void processGMActions(const std::vector& actions); - void processInventoryChange(int slot, const ItemPtr& item); - void processAttackCancel(uint seq); - void processWalkCancel(Otc::Direction direction); - - void processNewWalkCancel(Otc::Direction dir); - void processPredictiveWalkCancel(const Position& pos, Otc::Direction dir); - void processWalkId(uint32_t walkId); - - void processPlayerHelpers(int helpers); - void processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode, Otc::PVPModes pvpMode); - - // message related - void processTextMessage(Otc::MessageMode mode, const std::string& text); - void processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos); - - // container related - void processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector& items, bool isUnlocked, bool hasPages, int containerSize, int firstIndex); - void processCloseContainer(int containerId); - void processContainerAddItem(int containerId, const ItemPtr& item, int slot); - void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item); - void processContainerRemoveItem(int containerId, int slot, const ItemPtr& lastItem); - - // channel related - void processChannelList(const std::vector >& channelList); - void processOpenChannel(int channelId, const std::string& name); - void processOpenPrivateChannel(const std::string& name); - void processOpenOwnPrivateChannel(int channelId, const std::string& name); - void processCloseChannel(int channelId); - - // rule violations - void processRuleViolationChannel(int channelId); - void processRuleViolationRemove(const std::string& name); - void processRuleViolationCancel(const std::string& name); - void processRuleViolationLock(); - - // vip related - void processVipAdd(uint id, const std::string& name, uint status, const std::string& description, int iconId, bool notifyLogin); - void processVipStateChange(uint id, uint status); - - // tutorial hint - void processTutorialHint(int id); - void processAddAutomapFlag(const Position& pos, int icon, const std::string& message); - void processRemoveAutomapFlag(const Position& pos, int icon, const std::string& message); - - // outfit - void processOpenOutfitWindow(const Outfit& currentOutfit, const std::vector >& outfitList, - const std::vector >& mountList); - - // npc trade - void processOpenNpcTrade(const std::vector >& items); - void processPlayerGoods(uint64_t money, const std::vector >& goods); - void processCloseNpcTrade(); - - // player trade - void processOwnTrade(const std::string& name, const std::vector& items); - void processCounterTrade(const std::string& name, const std::vector& items); - void processCloseTrade(); - - // edit text/list - void processEditText(uint id, int itemId, int maxLength, const std::string& text, const std::string& writer, const std::string& date); - void processEditList(uint id, int doorId, const std::string& text); - - // questlog - void processQuestLog(const std::vector >& questList); - void processQuestLine(int questId, const std::vector >& questMissions); - - // modal dialogs >= 970 - void processModalDialog(uint32 id, std::string title, std::string message, std::vector > buttonList, int enterButton, int escapeButton, std::vector > choiceList, bool priority); - - friend class ProtocolGame; - friend class Map; - -public: - // login related - void loginWorld(const std::string& account, const std::string& password, const std::string& worldName, const std::string& worldHost, int worldPort, const std::string& characterName, const std::string& authenticatorToken, const std::string& sessionKey); - void cancelLogin(); - void forceLogout(); - void safeLogout(); - - // walk related - void walk(Otc::Direction direction, bool withPreWalk); - void autoWalk(const std::vector& dirs, Position startPos); - void turn(Otc::Direction direction); - void stop(); - - // item related - void look(const ThingPtr& thing, bool isBattleList = false); - void move(const ThingPtr& thing, const Position& toPos, int count); - void moveRaw(const Position& pos, int id, int stackpos, const Position& toPos, int count); - void moveToParentContainer(const ThingPtr& thing, int count); - void rotate(const ThingPtr& thing); - void wrap(const ThingPtr& thing); - void use(const ThingPtr& thing); - void useWith(const ItemPtr& fromThing, const ThingPtr& toThing, int subType = 0); - void useInventoryItem(int itemId, int subType = 0); - void useInventoryItemWith(int itemId, const ThingPtr& toThing, int subType = 0); - ItemPtr findItemInContainers(uint itemId, int subType); - - // container related - int open(const ItemPtr& item, const ContainerPtr& previousContainer); - void openParent(const ContainerPtr& container); - void close(const ContainerPtr& container); - void refreshContainer(const ContainerPtr& container); - - // attack/follow related - void attack(CreaturePtr creature, bool cancel = false); - void cancelAttack() { attack(nullptr, true); } - void follow(CreaturePtr creature); - void cancelFollow() { follow(nullptr); } - void cancelAttackAndFollow(); - - // talk related - void talk(const std::string& message); - void talkChannel(Otc::MessageMode mode, int channelId, const std::string& message); - void talkPrivate(Otc::MessageMode mode, const std::string& receiver, const std::string& message); - - // channel related - void openPrivateChannel(const std::string& receiver); - void requestChannels(); - void joinChannel(int channelId); - void leaveChannel(int channelId); - void closeNpcChannel(); - void openOwnChannel(); - void inviteToOwnChannel(const std::string& name); - void excludeFromOwnChannel(const std::string& name); - - // party related - void partyInvite(int creatureId); - void partyJoin(int creatureId); - void partyRevokeInvitation(int creatureId); - void partyPassLeadership(int creatureId); - void partyLeave(); - void partyShareExperience(bool active); - - // outfit related - void requestOutfit(); - void changeOutfit(const Outfit& outfit); - - // vip related - void addVip(const std::string& name); - void removeVip(int playerId); - void editVip(int playerId, const std::string& description, int iconId, bool notifyLogin); - - // fight modes related - void setChaseMode(Otc::ChaseModes chaseMode); - void setFightMode(Otc::FightModes fightMode); - void setSafeFight(bool on); - void setPVPMode(Otc::PVPModes pvpMode); - Otc::ChaseModes getChaseMode() { return m_chaseMode; } - Otc::FightModes getFightMode() { return m_fightMode; } - bool isSafeFight() { return m_safeFight; } - Otc::PVPModes getPVPMode() { return m_pvpMode; } - - // pvp related - void setUnjustifiedPoints(UnjustifiedPoints unjustifiedPoints); - UnjustifiedPoints getUnjustifiedPoints() { return m_unjustifiedPoints; }; - void setOpenPvpSituations(int openPvpSitations); - int getOpenPvpSituations() { return m_openPvpSituations; } - - // npc trade related - void inspectNpcTrade(const ItemPtr& item); - void buyItem(const ItemPtr& item, int amount, bool ignoreCapacity, bool buyWithBackpack); - void sellItem(const ItemPtr& item, int amount, bool ignoreEquipped); - void closeNpcTrade(); - - // player trade related - void requestTrade(const ItemPtr& item, const CreaturePtr& creature); - void inspectTrade(bool counterOffer, int index); - void acceptTrade(); - void rejectTrade(); - - // house window and editable items related - void editText(uint id, const std::string& text); - void editList(uint id, int doorId, const std::string& text); - - // rule violations (only gms) - void openRuleViolation(const std::string& reporter); - void closeRuleViolation(const std::string& reporter); - void cancelRuleViolation(); - - // reports - void reportBug(const std::string& comment); - void reportRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment); - void debugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d); - - // questlog related - void requestQuestLog(); - void requestQuestLine(int questId); - - // 870 only - void equipItem(const ItemPtr& item); - void mount(bool mount); - void setOutfitExtensions(int mount, int wings, int aura, int shader); - - // 910 only - void requestItemInfo(const ItemPtr& item, int index); - - // >= 970 modal dialog - void answerModalDialog(uint32 dialog, int button, int choice); - - // >= 984 browse field - void browseField(const Position& position); - void seekInContainer(int cid, int index); - - // >= 1080 ingame store - void buyStoreOffer(int offerId, int productType, const std::string& name = ""); - void requestTransactionHistory(int page, int entriesPerPage); - void requestStoreOffers(const std::string& categoryName, int serviceType = 0); - void openStore(int serviceType = 0); - void transferCoins(const std::string& recipient, int amount); - void openTransactionHistory(int entriesPerPage); - - // >= 1100 - void preyAction(int slot, int actionType, int index); - void preyRequest(); - - void applyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm); - void clearImbuement(uint8_t slot); - void closeImbuingWindow(); - - //void reportRuleViolation2(); - void ping(); - void newPing(); - void setPingDelay(int delay) { m_pingDelay = delay; } - - // otclient only - void changeMapAwareRange(int xrange, int yrange); - - // dynamic support for game features - void resetFeatures() { m_features.reset(); } - void enableFeature(Otc::GameFeature feature) { m_features.set(feature, true); } - void disableFeature(Otc::GameFeature feature) { m_features.set(feature, false); } - void setFeature(Otc::GameFeature feature, bool enabled) { m_features.set(feature, enabled); } - bool getFeature(Otc::GameFeature feature) { return m_features.test(feature); } - - void setProtocolVersion(int version); - int getProtocolVersion() { return m_protocolVersion; } - void setCustomProtocolVersion(int version) { m_customProtocolVersion = version; } - int getCustomProtocolVersion() { return m_customProtocolVersion != 0 ? m_customProtocolVersion : m_protocolVersion; } - - void setClientVersion(int version); - int getClientVersion() { return m_clientVersion; } - - void setCustomOs(int os) { m_clientCustomOs = os; } - int getOs(); - - bool canPerformGameAction(); - bool checkBotProtection(); - - bool isOnline() { return m_online; } - bool isLogging() { return !m_online && m_protocolGame; } - bool isDead() { return m_dead; } - bool isAttacking() { return !!m_attackingCreature && !m_attackingCreature->isRemoved(); } - bool isFollowing() { return !!m_followingCreature && !m_followingCreature->isRemoved(); } - bool isConnectionOk() { return m_protocolGame && m_protocolGame->getElapsedTicksSinceLastRead() < 5000; } - - int getPing() { return m_ping; } - ContainerPtr getContainer(int index) { if (m_containers.find(index) == m_containers.end()) { return nullptr; } return m_containers[index]; } - std::map getContainers() { return m_containers; } - std::map getVips() { return m_vips; } - CreaturePtr getAttackingCreature() { return m_attackingCreature; } - CreaturePtr getFollowingCreature() { return m_followingCreature; } - void setServerBeat(int beat) { m_serverBeat = beat; } - int getServerBeat() { return m_serverBeat; } - void setCanReportBugs(bool enable) { m_canReportBugs = enable; } - bool canReportBugs() { return m_canReportBugs; } - void setExpertPvpMode(bool enable) { m_expertPvpMode = enable; } - bool getExpertPvpMode() { return m_expertPvpMode; } - LocalPlayerPtr getLocalPlayer() { return m_localPlayer; } - ProtocolGamePtr getProtocolGame() { return m_protocolGame; } - std::string getCharacterName() { return m_characterName; } - std::string getWorldName() { return m_worldName; } - std::vector getGMActions() { return m_gmActions; } - bool isGM() { return m_gmActions.size() > 0; } - Otc::Direction getLastWalkDir() { return m_lastWalkDir; } - - std::string formatCreatureName(const std::string &name); - int findEmptyContainerId(); - - void setTibiaCoins(int coins, int transferableCoins) - { - m_coins = coins; - m_transferableCoins = transferableCoins; - } - int getTibiaCoins() - { - return m_coins; - } - int getTransferableTibiaCoins() - { - return m_transferableCoins; - } - - void setMaxPreWalkingSteps(uint value) { m_maxPreWalkingSteps = value; } - uint getMaxPreWalkingSteps() { return m_maxPreWalkingSteps; } - - void showRealDirection(bool value) { m_showRealDirection = value; } - bool shouldShowingRealDirection() { return m_showRealDirection; } - - uint getWalkId() { return m_walkId; } - uint getWalkPreditionId() { return m_walkPrediction; } - - void ignoreServerDirection(bool value) { m_ignoreServerDirection = value; } - bool isIgnoringServerDirection() - { - return m_ignoreServerDirection; - } - - void enableTileThingLuaCallback(bool value) { m_tileThingsLuaCallback = value; } - bool isTileThingLuaCallbackEnabled() { return m_tileThingsLuaCallback; } - - int getRecivedPacketsCount() - { - return m_protocolGame ? m_protocolGame->getRecivedPacketsCount() : 0; - } - - int getRecivedPacketsSize() - { - return m_protocolGame ? m_protocolGame->getRecivedPacketsSize() : 0; - } - -protected: - void enableBotCall() { m_denyBotCall = false; } - void disableBotCall() { m_denyBotCall = true; } - -private: - void setAttackingCreature(const CreaturePtr& creature); - void setFollowingCreature(const CreaturePtr& creature); - - LocalPlayerPtr m_localPlayer; - CreaturePtr m_attackingCreature; - CreaturePtr m_followingCreature; - ProtocolGamePtr m_protocolGame; - std::map m_containers; - std::map m_vips; - - bool m_online; - bool m_denyBotCall; - bool m_dead; - bool m_expertPvpMode; - int m_serverBeat; - ticks_t m_ping; - uint m_pingSent; - uint m_pingReceived; - uint m_walkId = 0; - uint m_walkPrediction = 0; - uint m_maxPreWalkingSteps = 2; - stdext::timer m_pingTimer; - std::map m_newPingIds; - uint m_seq; - int m_pingDelay; - int m_newPingDelay; - Otc::FightModes m_fightMode; - Otc::ChaseModes m_chaseMode; - Otc::PVPModes m_pvpMode; - Otc::Direction m_lastWalkDir; - bool m_waitingForAnotherDir = false; - UnjustifiedPoints m_unjustifiedPoints; - int m_openPvpSituations; - bool m_safeFight; - bool m_canReportBugs; - std::vector m_gmActions; - std::string m_characterName; - std::string m_worldName; - std::bitset m_features; - ScheduledEventPtr m_pingEvent; - ScheduledEventPtr m_newPingEvent; - ScheduledEventPtr m_checkConnectionEvent; - bool m_connectionFailWarned; - int m_protocolVersion; - int m_customProtocolVersion = 0; - int m_clientVersion; - std::string m_clientSignature; - int m_clientCustomOs; - int m_coins; - int m_transferableCoins; - - bool m_showRealDirection = false; - bool m_ignoreServerDirection = true; - bool m_tileThingsLuaCallback = false; -}; - -extern Game g_game; - -#endif diff --git a/src/client/global.h b/src/client/global.h deleted file mode 100644 index fd1b413..0000000 --- a/src/client/global.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CLIENT_GLOBAL_H -#define CLIENT_GLOBAL_H - -#include - -// widely used headers -#include "const.h" -#include "position.h" - -#endif diff --git a/src/client/houses.cpp b/src/client/houses.cpp deleted file mode 100644 index 8a71cd9..0000000 --- a/src/client/houses.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "map.h" - -#include - -HouseManager g_houses; - -House::House() -{ -} - -House::House(uint32 hId, const std::string &name, const Position &pos) -{ - setId(hId); - setName(name); - if(pos.isValid()) - setEntry(pos); -} - -void House::setTile(const TilePtr& tile) -{ - tile->setFlag(TILESTATE_HOUSE); - tile->setHouseId(getId()); - m_tiles.insert(std::make_pair(tile->getPosition(), tile)); -} - -TilePtr House::getTile(const Position& position) -{ - TileMap::const_iterator iter = m_tiles.find(position); - if(iter != m_tiles.end()) - return iter->second; - return nullptr; -} - -void House::addDoor(const ItemPtr& door) -{ - if (!door) return; - door->setDoorId(m_lastDoorId); - m_doors[m_lastDoorId++] = door; -} - -void House::removeDoorById(uint32 doorId) -{ - if(doorId >= m_lastDoorId) - stdext::throw_exception(stdext::format("Failed to remove door of id %d (would overflow), max id: %d", - doorId, m_lastDoorId)); - m_doors[doorId] = nullptr; -} - -void House::load(const TiXmlElement *elem) -{ - std::string name = elem->Attribute("name"); - if(name.empty()) - name = stdext::format("Unnamed house #%lu", getId()); - - setName(name); - setRent(elem->readType("rent")); - setSize(elem->readType("size")); - setTownId(elem->readType("townid")); - m_isGuildHall = elem->readType("guildhall"); - - Position entryPos; - entryPos.x = elem->readType("entryx"); - entryPos.y = elem->readType("entryy"); - entryPos.z = elem->readType("entryz"); - setEntry(entryPos); -} - -void House::save(TiXmlElement* elem) -{ - elem->SetAttribute("name", getName()); - elem->SetAttribute("houseid", getId()); - - Position entry = getEntry(); - elem->SetAttribute("entryx", entry.x); - elem->SetAttribute("entryy", entry.y); - elem->SetAttribute("entryz", entry.z); - - elem->SetAttribute("rent", getRent()); - elem->SetAttribute("townid", getTownId()); - elem->SetAttribute("size", getSize()); - elem->SetAttribute("guildhall", (int)m_isGuildHall); -} - -HouseManager::HouseManager() -{ -} - -void HouseManager::addHouse(const HousePtr& house) -{ - if(findHouse(house->getId()) == m_houses.end()) - m_houses.push_back(house); -} - -void HouseManager::removeHouse(uint32 houseId) -{ - auto it = findHouse(houseId); - if(it != m_houses.end()) - m_houses.erase(it); -} - -HousePtr HouseManager::getHouse(uint32 houseId) -{ - auto it = findHouse(houseId); - return it != m_houses.end() ? *it : nullptr; -} - -HousePtr HouseManager::getHouseByName(std::string name) -{ - auto it = std::find_if(m_houses.begin(), m_houses.end(), - [=] (const HousePtr& house) -> bool { return house->getName() == name; }); - return it != m_houses.end() ? *it : nullptr; -} - -void HouseManager::load(const std::string& fileName) -{ - try { - TiXmlDocument doc; - doc.Parse(g_resources.readFileContents(fileName).c_str()); - if(doc.Error()) - stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc())); - - TiXmlElement *root = doc.FirstChildElement(); - if(!root || root->ValueTStr() != "houses") - stdext::throw_exception("invalid root tag name"); - - for(TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) { - if(elem->ValueTStr() != "house") - stdext::throw_exception("invalid house tag."); - - uint32 houseId = elem->readType("houseid"); - HousePtr house = getHouse(houseId); - if(!house) - house = HousePtr(new House(houseId)), addHouse(house); - - house->load(elem); - } - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what())); - } - sort(); -} - -void HouseManager::save(const std::string& fileName) -{ - try { - TiXmlDocument doc; - doc.SetTabSize(2); - - TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", ""); - doc.LinkEndChild(decl); - - TiXmlElement* root = new TiXmlElement("houses"); - doc.LinkEndChild(root); - - for(auto house : m_houses) { - TiXmlElement *elem = new TiXmlElement("house"); - house->save(elem); - root->LinkEndChild(elem); - } - - if(!doc.SaveFile("data"+fileName)) - stdext::throw_exception(stdext::format("failed to save houses XML %s: %s", fileName, doc.ErrorDesc())); - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what())); - } -} - -HouseList HouseManager::filterHouses(uint32 townId) -{ - HouseList ret; - for(const HousePtr& house : m_houses) - if(house->getTownId() == townId) - ret.push_back(house); - return ret; -} - -HouseList::iterator HouseManager::findHouse(uint32 houseId) -{ - return std::find_if(m_houses.begin(), m_houses.end(), - [=] (const HousePtr& house) -> bool { return house->getId() == houseId; }); -} - -void HouseManager::sort() -{ - m_houses.sort([] (const HousePtr& lhs, const HousePtr& rhs) { return lhs->getName() < rhs->getName(); }); -} - -/* vim: set ts=4 sw=4 et: */ diff --git a/src/client/houses.h b/src/client/houses.h deleted file mode 100644 index 2fa12c0..0000000 --- a/src/client/houses.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef HOUSES_H -#define HOUSES_H - -#include "declarations.h" -#include "tile.h" - -#include - -enum HouseAttr : uint8 -{ - HouseAttrId, - HouseAttrName, - HouseAttrTown, - HouseAttrEntry, - HouseAttrSize, - HouseAttrRent -}; - -class House : public LuaObject -{ -public: - House(); - House(uint32 hId, const std::string& name = "", const Position& pos=Position()); - ~House() { m_tiles.clear(); } - - void setTile(const TilePtr& tile); - TilePtr getTile(const Position& pos); - - void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); } - std::string getName() { return m_attribs.get(HouseAttrName); } - - void setId(uint32 hId) { m_attribs.set(HouseAttrId, hId); } - uint32 getId() { return m_attribs.get(HouseAttrId); } - - void setTownId(uint32 tid) { m_attribs.set(HouseAttrTown, tid); } - uint32 getTownId() { return m_attribs.get(HouseAttrTown); } - - void setSize(uint32 s) { m_attribs.set(HouseAttrSize, s); } - uint32 getSize() { return m_attribs.get(HouseAttrSize); } - - void setRent(uint32 r) { m_attribs.set(HouseAttrRent, r); } - uint32 getRent() { return m_attribs.get(HouseAttrRent); } - - void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); } - Position getEntry() { return m_attribs.get(HouseAttrEntry); } - - void addDoor(const ItemPtr& door); - void removeDoor(const ItemPtr& door) { removeDoorById(door->getDoorId()); } - void removeDoorById(uint32 doorId); - -protected: - void load(const TiXmlElement* elem); - void save(TiXmlElement* elem); - -private: - stdext::packed_storage m_attribs; - TileMap m_tiles; - ItemVector m_doors; - uint32 m_lastDoorId; - stdext::boolean m_isGuildHall; - - friend class HouseManager; -}; - -class HouseManager { -public: - HouseManager(); - - void addHouse(const HousePtr& house); - void removeHouse(uint32 houseId); - HousePtr getHouse(uint32 houseId); - HousePtr getHouseByName(std::string name); - - void load(const std::string& fileName); - void save(const std::string& fileName); - - void sort(); - void clear() { m_houses.clear(); } - HouseList getHouseList() { return m_houses; } - HouseList filterHouses(uint32 townId); - -private: - HouseList m_houses; - -protected: - HouseList::iterator findHouse(uint32 houseId); -}; - -extern HouseManager g_houses; - -#endif diff --git a/src/client/item.cpp b/src/client/item.cpp deleted file mode 100644 index b72a7fc..0000000 --- a/src/client/item.cpp +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "item.h" -#include "thingtypemanager.h" -#include "spritemanager.h" -#include "thing.h" -#include "tile.h" -#include "shadermanager.h" -#include "container.h" -#include "map.h" -#include "houses.h" -#include "game.h" - -#include -#include -#include -#include -#include - -#include - -Item::Item() : - m_clientId(0), - m_serverId(0), - m_countOrSubType(1), - m_color(Color::alpha), - m_async(true), - m_phase(0), - m_lastPhase(0) -{ -} - -ItemPtr Item::create(int id, int countOrSubtype) -{ - ItemPtr item(new Item); - item->setId(id); - item->setCountOrSubType(countOrSubtype); - return item; -} - -ItemPtr Item::createFromOtb(int id) -{ - ItemPtr item(new Item); - item->setOtbId(id); - return item; -} - -std::string Item::getName() -{ - return g_things.findItemTypeByClientId(m_clientId)->getName(); -} - -void Item::draw(const Point& dest, bool animate, LightView* lightView) -{ - if (m_clientId == 0) - return; - - // determine animation phase - int animationPhase = calculateAnimationPhase(animate); - - // determine x,y,z patterns - int xPattern = 0, yPattern = 0, zPattern = 0; - calculatePatterns(xPattern, yPattern, zPattern); - - Color color(Color::white); - if (m_color != Color::alpha) - color = m_color; - size_t drawQueueSize = g_drawQueue->size(); - rawGetThingType()->draw(dest, 0, xPattern, yPattern, zPattern, animationPhase, color, lightView); - if (m_marked) { - g_drawQueue->setMark(drawQueueSize, updatedMarkedColor()); - } -} - -void Item::draw(const Rect& dest, bool animate) -{ - if (m_clientId == 0) - return; - - // determine animation phase - int animationPhase = calculateAnimationPhase(animate); - - // determine x,y,z patterns - int xPattern = 0, yPattern = 0, zPattern = 0; - calculatePatterns(xPattern, yPattern, zPattern); - - Color color(Color::white); - if (m_color != Color::alpha) - color = m_color; - - rawGetThingType()->draw(dest, 0, xPattern, yPattern, zPattern, animationPhase, color); -} - -void Item::setId(uint32 id) -{ - if(!g_things.isValidDatId(id, ThingCategoryItem)) - id = 0; - m_serverId = g_things.findItemTypeByClientId(id)->getServerId(); - m_clientId = id; -} - -void Item::setOtbId(uint16 id) -{ - if(!g_things.isValidOtbId(id)) - id = 0; - auto itemType = g_things.getItemType(id); - m_serverId = id; - - id = itemType->getClientId(); - if(!g_things.isValidDatId(id, ThingCategoryItem)) - id = 0; - m_clientId = id; -} - -bool Item::isValid() -{ - return g_things.isValidDatId(m_clientId, ThingCategoryItem); -} - -void Item::unserializeItem(const BinaryTreePtr &in) -{ - try { - while(in->canRead()) { - int attrib = in->getU8(); - if(attrib == 0) - break; - - switch(attrib) { - case ATTR_COUNT: - case ATTR_RUNE_CHARGES: - setCount(in->getU8()); - break; - case ATTR_CHARGES: - setCount(in->getU16()); - break; - case ATTR_HOUSEDOORID: - case ATTR_SCRIPTPROTECTED: - case ATTR_DUALWIELD: - case ATTR_DECAYING_STATE: - m_attribs.set(attrib, in->getU8()); - break; - case ATTR_ACTION_ID: - case ATTR_UNIQUE_ID: - case ATTR_DEPOT_ID: - m_attribs.set(attrib, in->getU16()); - break; - case ATTR_CONTAINER_ITEMS: - case ATTR_ATTACK: - case ATTR_EXTRAATTACK: - case ATTR_DEFENSE: - case ATTR_EXTRADEFENSE: - case ATTR_ARMOR: - case ATTR_ATTACKSPEED: - case ATTR_HITCHANCE: - case ATTR_DURATION: - case ATTR_WRITTENDATE: - case ATTR_SLEEPERGUID: - case ATTR_SLEEPSTART: - case ATTR_ATTRIBUTE_MAP: - m_attribs.set(attrib, in->getU32()); - break; - case ATTR_TELE_DEST: { - Position pos; - pos.x = in->getU16(); - pos.y = in->getU16(); - pos.z = in->getU8(); - m_attribs.set(attrib, pos); - break; - } - case ATTR_NAME: - case ATTR_TEXT: - case ATTR_DESC: - case ATTR_ARTICLE: - case ATTR_WRITTENBY: - m_attribs.set(attrib, in->getString()); - break; - default: - stdext::throw_exception(stdext::format("invalid item attribute %d", attrib)); - } - } - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Failed to unserialize OTBM item: %s", e.what())); - } -} - -void Item::serializeItem(const OutputBinaryTreePtr& out) -{ - out->startNode(OTBM_ITEM); - out->addU16(getServerId()); - - out->addU8(ATTR_COUNT); - out->addU8(getCount()); - - out->addU8(ATTR_CHARGES); - out->addU16(getCountOrSubType()); - - Position dest = m_attribs.get(ATTR_TELE_DEST); - if(dest.isValid()) { - out->addU8(ATTR_TELE_DEST); - out->addPos(dest.x, dest.y, dest.z); - } - - if(isDepot()) { - out->addU8(ATTR_DEPOT_ID); - out->addU16(getDepotId()); - } - - if(isHouseDoor()) { - out->addU8(ATTR_HOUSEDOORID); - out->addU8(getDoorId()); - } - - uint16 aid = m_attribs.get(ATTR_ACTION_ID); - uint16 uid = m_attribs.get(ATTR_UNIQUE_ID); - if(aid) { - out->addU8(ATTR_ACTION_ID); - out->addU16(aid); - } - - if(uid) { - out->addU8(ATTR_UNIQUE_ID); - out->addU16(uid); - } - - std::string text = getText(); - if(g_things.getItemType(m_serverId)->isWritable() && !text.empty()) { - out->addU8(ATTR_TEXT); - out->addString(text); - } - std::string desc = getDescription(); - if(!desc.empty()) { - out->addU8(ATTR_DESC); - out->addString(desc); - } - - out->endNode(); - for(auto i : m_containerItems) - i->serializeItem(out); -} - -int Item::getSubType() -{ - if(isSplash() || isFluidContainer()) - return m_countOrSubType; - if(g_game.getClientVersion() >= 860) - return 0; - return 1; -} - -int Item::getCount() -{ - if(isStackable()) - return m_countOrSubType; - return 1; -} - -bool Item::isMoveable() -{ - return !rawGetThingType()->isNotMoveable(); -} - -bool Item::isGround() -{ - return rawGetThingType()->isGround(); -} - -ItemPtr Item::clone() -{ - ItemPtr item = ItemPtr(new Item); - *(item.get()) = *this; - return item; -} - -void Item::calculatePatterns(int& xPattern, int& yPattern, int& zPattern) -{ - // Avoid crashes with invalid items - if(!isValid()) - return; - - if(isStackable() && getNumPatternX() == 4 && getNumPatternY() == 2) { - if(m_countOrSubType <= 0) { - xPattern = 0; - yPattern = 0; - } else if(m_countOrSubType < 5) { - xPattern = m_countOrSubType-1; - yPattern = 0; - } else if(m_countOrSubType < 10) { - xPattern = 0; - yPattern = 1; - } else if(m_countOrSubType < 25) { - xPattern = 1; - yPattern = 1; - } else if(m_countOrSubType < 50) { - xPattern = 2; - yPattern = 1; - } else { - xPattern = 3; - yPattern = 1; - } - } else if(isHangable()) { - const TilePtr& tile = getTile(); - if(tile) { - if(tile->mustHookSouth()) - xPattern = getNumPatternX() >= 2 ? 1 : 0; - else if(tile->mustHookEast()) - xPattern = getNumPatternX() >= 3 ? 2 : 0; - } - } else if(isSplash() || isFluidContainer()) { - int color = Otc::FluidTransparent; - if(g_game.getFeature(Otc::GameNewFluids)) { - switch(m_countOrSubType) { - case Otc::FluidNone: - color = Otc::FluidTransparent; - break; - case Otc::FluidWater: - color = Otc::FluidBlue; - break; - case Otc::FluidMana: - color = Otc::FluidPurple; - break; - case Otc::FluidBeer: - color = Otc::FluidBrown; - break; - case Otc::FluidOil: - color = Otc::FluidBrown; - break; - case Otc::FluidBlood: - color = Otc::FluidRed; - break; - case Otc::FluidSlime: - color = Otc::FluidGreen; - break; - case Otc::FluidMud: - color = Otc::FluidBrown; - break; - case Otc::FluidLemonade: - color = Otc::FluidYellow; - break; - case Otc::FluidMilk: - color = Otc::FluidWhite; - break; - case Otc::FluidWine: - color = Otc::FluidPurple; - break; - case Otc::FluidHealth: - color = Otc::FluidRed; - break; - case Otc::FluidUrine: - color = Otc::FluidYellow; - break; - case Otc::FluidRum: - color = Otc::FluidBrown; - break; - case Otc::FluidFruidJuice: - color = Otc::FluidYellow; - break; - case Otc::FluidCoconutMilk: - color = Otc::FluidWhite; - break; - case Otc::FluidTea: - color = Otc::FluidBrown; - break; - case Otc::FluidMead: - color = Otc::FluidBrown; - break; - default: - color = Otc::FluidTransparent; - break; - } - } else - color = m_countOrSubType; - - xPattern = (color % 4) % getNumPatternX(); - yPattern = (color / 4) % getNumPatternY(); - } else { - xPattern = m_position.x % std::max(1, getNumPatternX()); - yPattern = m_position.y % std::max(1, getNumPatternY()); - zPattern = m_position.z % std::max(1, getNumPatternZ()); - } -} - -int Item::calculateAnimationPhase(bool animate) -{ - if(getAnimationPhases() > 1) { - if(animate) { - if(getAnimator() != nullptr) - return getAnimator()->getPhase(); - - if(m_async) - return (g_clock.millis() % ((g_game.getFeature(Otc::GameEnhancedAnimations) ? Otc::ITEM_TICKS_PER_FRAME_FAST : Otc::ITEM_TICKS_PER_FRAME) * getAnimationPhases())) / Otc::ITEM_TICKS_PER_FRAME; - else { - if(g_clock.millis() - m_lastPhase >= (g_game.getFeature(Otc::GameEnhancedAnimations) ? Otc::ITEM_TICKS_PER_FRAME_FAST : Otc::ITEM_TICKS_PER_FRAME)) { - m_phase = (m_phase + 1) % getAnimationPhases(); - m_lastPhase = g_clock.millis(); - } - return m_phase; - } - } else - return getAnimationPhases()-1; - } - return 0; -} - -int Item::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase) -{ - calculatePatterns(xPattern, yPattern, zPattern); - animationPhase = calculateAnimationPhase(true); - return Thing::getExactSize(layer, xPattern, yPattern, zPattern, animationPhase); -} - -const ThingTypePtr& Item::getThingType() -{ - return g_things.getThingType(m_clientId, ThingCategoryItem); -} - -ThingType* Item::rawGetThingType() -{ - return g_things.rawGetThingType(m_clientId, ThingCategoryItem); -} -/* vim: set ts=4 sw=4 et :*/ diff --git a/src/client/item.h b/src/client/item.h deleted file mode 100644 index 681efbb..0000000 --- a/src/client/item.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef ITEM_H -#define ITEM_H - -#include - -#include "thing.h" -#include "effect.h" -#include "itemtype.h" - -enum ItemAttr : uint8 -{ - ATTR_END = 0, - //ATTR_DESCRIPTION = 1, - //ATTR_EXT_FILE = 2, - ATTR_TILE_FLAGS = 3, - ATTR_ACTION_ID = 4, - ATTR_UNIQUE_ID = 5, - ATTR_TEXT = 6, - ATTR_DESC = 7, - ATTR_TELE_DEST = 8, - ATTR_ITEM = 9, - ATTR_DEPOT_ID = 10, - //ATTR_EXT_SPAWN_FILE = 11, - ATTR_RUNE_CHARGES = 12, - //ATTR_EXT_HOUSE_FILE = 13, - ATTR_HOUSEDOORID = 14, - ATTR_COUNT = 15, - ATTR_DURATION = 16, - ATTR_DECAYING_STATE = 17, - ATTR_WRITTENDATE = 18, - ATTR_WRITTENBY = 19, - ATTR_SLEEPERGUID = 20, - ATTR_SLEEPSTART = 21, - ATTR_CHARGES = 22, - ATTR_CONTAINER_ITEMS = 23, - ATTR_NAME = 30, - ATTR_PLURALNAME = 31, - ATTR_ATTACK = 33, - ATTR_EXTRAATTACK = 34, - ATTR_DEFENSE = 35, - ATTR_EXTRADEFENSE = 36, - ATTR_ARMOR = 37, - ATTR_ATTACKSPEED = 38, - ATTR_HITCHANCE = 39, - ATTR_SHOOTRANGE = 40, - ATTR_ARTICLE = 41, - ATTR_SCRIPTPROTECTED = 42, - ATTR_DUALWIELD = 43, - ATTR_ATTRIBUTE_MAP = 128 -}; - -// @bindclass -#pragma pack(push,1) // disable memory alignment -class Item : public Thing -{ -public: - Item(); - virtual ~Item() { } - - static ItemPtr create(int id, int countOrSubtype = 1); - static ItemPtr createFromOtb(int id); - - void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr); - void draw(const Rect& dest, bool animate = true); - - void setId(uint32 id); - void setOtbId(uint16 id); - void setCountOrSubType(int value) { m_countOrSubType = value; } - void setCount(int count) { m_countOrSubType = count; } - void setSubType(int subType) { m_countOrSubType = subType; } - void setColor(const Color& c) { m_color = c; } - void setTooltip(const std::string& str) { m_tooltip = str; } - - int getCountOrSubType() { return m_countOrSubType; } - int getSubType(); - int getCount(); - uint32 getId() { return m_clientId; } - uint16 getClientId() { return m_clientId; } - uint16 getServerId() { return m_serverId; } - std::string getName(); - bool isValid(); - std::string getTooltip() { return m_tooltip; } - - void unserializeItem(const BinaryTreePtr& in); - void serializeItem(const OutputBinaryTreePtr& out); - - void setDepotId(uint16 depotId) { m_attribs.set(ATTR_DEPOT_ID, depotId); } - uint16 getDepotId() { return m_attribs.get(ATTR_DEPOT_ID); } - - void setDoorId(uint8 doorId) { m_attribs.set(ATTR_HOUSEDOORID, doorId); } - uint8 getDoorId() { return m_attribs.get(ATTR_HOUSEDOORID); } - - uint16 getUniqueId() { return m_attribs.get(ATTR_ACTION_ID); } - uint16 getActionId() { return m_attribs.get(ATTR_UNIQUE_ID); } - void setActionId(uint16 actionId) { m_attribs.set(ATTR_ACTION_ID, actionId); } - void setUniqueId(uint16 uniqueId) { m_attribs.set(ATTR_UNIQUE_ID, uniqueId); } - - std::string getText() { return m_attribs.get(ATTR_TEXT); } - std::string getDescription() { return m_attribs.get(ATTR_DESC); } - void setDescription(std::string desc) { m_attribs.set(ATTR_DESC, desc); } - void setText(std::string txt) { m_attribs.set(ATTR_TEXT, txt); } - - Position getTeleportDestination() { return m_attribs.get(ATTR_TELE_DEST); } - void setTeleportDestination(const Position& pos) { m_attribs.set(ATTR_TELE_DEST, pos); } - - void setAsync(bool enable) { m_async = enable; } - - bool isHouseDoor() { return m_attribs.has(ATTR_HOUSEDOORID); } - bool isDepot() { return m_attribs.has(ATTR_DEPOT_ID); } - bool isContainer() { return m_attribs.has(ATTR_CONTAINER_ITEMS); } - bool isDoor() { return m_attribs.has(ATTR_HOUSEDOORID); } - bool isTeleport() { return m_attribs.has(ATTR_TELE_DEST); } - bool isMoveable(); - bool isGround(); - - ItemPtr clone(); - ItemPtr asItem() { return static_self_cast(); } - bool isItem() { return true; } - - ItemVector getContainerItems() { return m_containerItems; } - ItemPtr getContainerItem(int slot) { return m_containerItems[slot]; } - void addContainerItemIndexed(const ItemPtr& i, int slot) { m_containerItems[slot] = i; } - void addContainerItem(const ItemPtr& i) { m_containerItems.push_back(i); } - void removeContainerItem(int slot) { m_containerItems[slot] = nullptr; } - void clearContainerItems() { m_containerItems.clear(); } - - void calculatePatterns(int& xPattern, int& yPattern, int& zPattern); - int calculateAnimationPhase(bool animate); - int getExactSize(int layer = 0, int xPattern = 0, int yPattern = 0, int zPattern = 0, int animationPhase = 0); - - const ThingTypePtr& getThingType(); - ThingType *rawGetThingType(); - -private: - uint16 m_clientId; - uint16 m_serverId; - uint16 m_countOrSubType; - stdext::packed_storage m_attribs; - ItemVector m_containerItems; - Color m_color; - bool m_async; - std::string m_tooltip; - - uint8 m_phase; - ticks_t m_lastPhase; -}; - -#pragma pack(pop) - -#endif diff --git a/src/client/itemtype.cpp b/src/client/itemtype.cpp deleted file mode 100644 index 3e61709..0000000 --- a/src/client/itemtype.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#include "thingtypemanager.h" -#include "thingtype.h" -#include "game.h" - -#include -#include - -ItemType::ItemType() -{ - m_category = ItemCategoryInvalid; -} - -void ItemType::unserialize(const BinaryTreePtr& node) -{ - m_null = false; - - m_category = (ItemCategory)node->getU8(); - - node->getU32(); // flags - - static uint16 lastId = 99; - while(node->canRead()) { - uint8 attr = node->getU8(); - if(attr == 0 || attr == 0xFF) - break; - - uint16 len = node->getU16(); - switch(attr) { - case ItemTypeAttrServerId: { - uint16 serverId = node->getU16(); - if(g_game.getClientVersion() < 960) { - if(serverId > 20000 && serverId < 20100) { - serverId -= 20000; - } else if(lastId > 99 && lastId != serverId - 1) { - while(lastId != serverId - 1) { - ItemTypePtr tmp(new ItemType); - tmp->setServerId(lastId++); - g_things.addItemType(tmp); - } - } - } else { - if(serverId > 30000 && serverId < 30100) { - serverId -= 30000; - } else if(lastId > 99 && lastId != serverId - 1) { - while(lastId != serverId - 1) { - ItemTypePtr tmp(new ItemType); - tmp->setServerId(lastId++); - g_things.addItemType(tmp); - } - } - } - setServerId(serverId); - lastId = serverId; - break; - } - case ItemTypeAttrClientId: - setClientId(node->getU16()); - break; - case ItemTypeAttrName: - setName(node->getString(len)); - break; - case ItemTypeAttrWritable: - m_attribs.set(ItemTypeAttrWritable, true); - break; - default: - node->skip(len); // skip attribute - break; - } - } -} diff --git a/src/client/itemtype.h b/src/client/itemtype.h deleted file mode 100644 index 3aa62c6..0000000 --- a/src/client/itemtype.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef ITEMTYPE_H -#define ITEMTYPE_H - -#include -#include -#include - -enum ItemCategory : uint8 { - ItemCategoryInvalid = 0, - ItemCategoryGround = 1, - ItemCategoryContainer = 2, - ItemCategoryWeapon = 3, - ItemCategoryAmmunition = 4, - ItemCategoryArmor = 5, - ItemCategoryCharges = 6, - ItemCategoryTeleport = 7, - ItemCategoryMagicField = 8, - ItemCategoryWritable = 9, - ItemCategoryKey = 10, - ItemCategorySplash = 11, - ItemCategoryFluid = 12, - ItemCategoryDoor = 13, - ItemCategoryDeprecated = 14, - ItemCategoryLast = 15 -}; - -enum ItemTypeAttr : uint8 { - ItemTypeAttrServerId = 16, - ItemTypeAttrClientId = 17, - ItemTypeAttrName = 18, // deprecated - ItemTypeAttrDesc = 19, // deprecated - ItemTypeAttrSpeed = 20, - ItemTypeAttrSlot = 21, // deprecated - ItemTypeAttrMaxItems = 22, // deprecated - ItemTypeAttrWeight = 23, // deprecated - ItemTypeAttrWeapon = 24, // deprecated - ItemTypeAttrAmmunition = 25, // deprecated - ItemTypeAttrArmor = 26, // deprecated - ItemTypeAttrMagicLevel = 27, // deprecated - ItemTypeAttrMagicField = 28, // deprecated - ItemTypeAttrWritable = 29, // deprecated - ItemTypeAttrRotateTo = 30, // deprecated - ItemTypeAttrDecay = 31, // deprecated - ItemTypeAttrSpriteHash = 32, - ItemTypeAttrMinimapColor = 33, - ItemTypeAttr07 = 34, - ItemTypeAttr08 = 35, - ItemTypeAttrLight = 36, - ItemTypeAttrDecay2 = 37, // deprecated - ItemTypeAttrWeapon2 = 38, // deprecated - ItemTypeAttrAmmunition2 = 39, // deprecated - ItemTypeAttrArmor2 = 40, // deprecated - ItemTypeAttrWritable2 = 41, // deprecated - ItemTypeAttrLight2 = 42, - ItemTypeAttrTopOrder = 43, - ItemTypeAttrWrtiable3 = 44, // deprecated - ItemTypeAttrWareId = 45, - ItemTypeAttrLast = 46 -}; - -enum ClientVersion -{ - ClientVersion750 = 1, - ClientVersion755 = 2, - ClientVersion760 = 3, - ClientVersion770 = 3, - ClientVersion780 = 4, - ClientVersion790 = 5, - ClientVersion792 = 6, - ClientVersion800 = 7, - ClientVersion810 = 8, - ClientVersion811 = 9, - ClientVersion820 = 10, - ClientVersion830 = 11, - ClientVersion840 = 12, - ClientVersion841 = 13, - ClientVersion842 = 14, - ClientVersion850 = 15, - ClientVersion854_OLD = 16, - ClientVersion854 = 17, - ClientVersion855 = 18, - ClientVersion860_OLD = 19, - ClientVersion860 = 20, - ClientVersion861 = 21, - ClientVersion862 = 22, - ClientVersion870 = 23, - ClientVersion871 = 24, - ClientVersion872 = 25, - ClientVersion873 = 26, - ClientVersion900 = 27, - ClientVersion910 = 28, - ClientVersion920 = 29, - ClientVersion940 = 30, - ClientVersion944_V1 = 31, - ClientVersion944_V2 = 32, - ClientVersion944_V3 = 33, - ClientVersion944_V4 = 34, - ClientVersion946 = 35, - ClientVersion950 = 36, - ClientVersion952 = 37, - ClientVersion953 = 38, - ClientVersion954 = 39, - ClientVersion960 = 40, - ClientVersion961 = 41 -}; - -class ItemType : public LuaObject -{ -public: - ItemType(); - - void unserialize(const BinaryTreePtr& node); - - void setServerId(uint16 serverId) { m_attribs.set(ItemTypeAttrServerId, serverId); } - uint16 getServerId() { return m_attribs.get(ItemTypeAttrServerId); } - - void setClientId(uint16 clientId) { m_attribs.set(ItemTypeAttrClientId, clientId); } - uint16 getClientId() { return m_attribs.get(ItemTypeAttrClientId); } - - void setCategory(ItemCategory category) { m_category = category; } - ItemCategory getCategory() { return m_category; } - - void setName(const std::string& name) { m_attribs.set(ItemTypeAttrName, name); } - std::string getName() { return m_attribs.get(ItemTypeAttrName); } - - void setDesc(const std::string& desc) { m_attribs.set(ItemTypeAttrDesc, desc); } - std::string getDesc() { return m_attribs.get(ItemTypeAttrDesc); } - - bool isNull() { return m_null; } - bool isWritable() { return m_attribs.get(ItemTypeAttrWritable); } - -private: - ItemCategory m_category; - stdext::boolean m_null; - - stdext::dynamic_storage m_attribs; -}; - -#endif diff --git a/src/client/lightview.cpp b/src/client/lightview.cpp deleted file mode 100644 index c89ad1a..0000000 --- a/src/client/lightview.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "lightview.h" -#include - -void LightView::addLight(const Point& pos, uint8_t color, uint8_t intensity) -{ - if (!m_lights.empty()) { - Light& prevLight = m_lights.back(); - if (prevLight.pos == pos && prevLight.color == color) { - prevLight.intensity = std::max(prevLight.intensity, intensity); - return; - } - } - m_lights.push_back(Light{ pos, color, intensity }); -} - -void LightView::setFieldBrightness(const Point& pos, size_t start, uint8_t color) -{ - size_t index = (pos.y / Otc::TILE_PIXELS) * m_mapSize.width() + (pos.x / Otc::TILE_PIXELS); - if (index >= m_tiles.size()) return; - m_tiles[index].start = start; - m_tiles[index].color = color; -} - -void LightView::draw() // render thread -{ - static std::vector buffer; - if(buffer.size() < 4u * m_mapSize.area()) - buffer.resize(m_mapSize.area() * 4); - - // hidden code - - m_lightTexture->update(); - glBindTexture(GL_TEXTURE_2D, m_lightTexture->getId()); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_mapSize.width(), m_mapSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); - - Point offset = m_src.topLeft(); - Size size = m_src.size(); - CoordsBuffer coords; - coords.addRect(RectF(m_dest.left(), m_dest.top(), m_dest.width(), m_dest.height()), - RectF((float)offset.x / Otc::TILE_PIXELS, (float)offset.y / Otc::TILE_PIXELS, - (float)size.width() / Otc::TILE_PIXELS, (float)size.height() / Otc::TILE_PIXELS)); - - g_painterNew->resetColor(); - g_painterNew->setCompositionMode(Painter::CompositionMode_Multiply); - g_painterNew->drawTextureCoords(coords, m_lightTexture); - g_painterNew->resetCompositionMode(); -} diff --git a/src/client/lightview.h b/src/client/lightview.h deleted file mode 100644 index 2b67f4c..0000000 --- a/src/client/lightview.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LIGHTVIEW_H -#define LIGHTVIEW_H - -#include "declarations.h" -#include "thingtype.h" -#include -#include -#include - -struct TileLight { - size_t start; - uint8_t color; -}; - -class LightView : public DrawQueueItem -{ -public: - LightView(TexturePtr& lightTexture, const Size& mapSize, const Rect& dest, const Rect& src, uint8_t color, uint8_t intensity) : - DrawQueueItem(nullptr), m_lightTexture(lightTexture), m_mapSize(mapSize), m_dest(dest), m_src(src) { - m_globalLight = Color::from8bit(color) * ((float)intensity / 255.f); - m_tiles.resize(m_mapSize.area(), TileLight{ 0, 0 }); - } - - inline void addLight(const Point& pos, const Light& light) - { - return addLight(pos, light.color, light.intensity); - } - void addLight(const Point& pos, uint8_t color, uint8_t intensity); - void setFieldBrightness(const Point& pos, size_t start, uint8_t color); - size_t size() { return m_lights.size(); } - - void draw() override; - -private: - TexturePtr m_lightTexture; - Size m_mapSize; - Rect m_dest, m_src; - Color m_globalLight; - std::vector m_lights; - std::vector m_tiles; -}; - -#endif - diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp deleted file mode 100644 index 60dd1be..0000000 --- a/src/client/localplayer.cpp +++ /dev/null @@ -1,623 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "localplayer.h" -#include "map.h" -#include "game.h" -#include "tile.h" -#include -#include -#include - -LocalPlayer::LocalPlayer() -{ - m_states = 0; - m_vocation = 0; - m_blessings = Otc::BlessingNone; - m_walkLockExpiration = 0; - - m_skillsLevel.fill(-1); - m_skillsBaseLevel.fill(-1); - m_skillsLevelPercent.fill(-1); - - m_health = -1; - m_maxHealth = -1; - m_freeCapacity = -1; - m_experience = -1; - m_level = -1; - m_levelPercent = -1; - m_mana = -1; - m_maxMana = -1; - m_magicLevel = -1; - m_magicLevelPercent = -1; - m_baseMagicLevel = -1; - m_soul = -1; - m_stamina = -1; - m_baseSpeed = -1; - m_regenerationTime = -1; - m_offlineTrainingTime = -1; - m_totalCapacity = -1; -} - -void LocalPlayer::draw(const Point& dest, bool animate, LightView* lightView) -{ - Creature::draw(dest, animate, lightView); -} - - -void LocalPlayer::lockWalk(int millis) -{ - m_walkLockExpiration = std::max(m_walkLockExpiration, (ticks_t) g_clock.millis() + millis); -} - -bool LocalPlayer::canWalk(Otc::Direction direction, bool ignoreLock) { - // cannot walk while locked - if ((m_walkLockExpiration != 0 && g_clock.millis() < m_walkLockExpiration) && !ignoreLock) - return false; - - // paralyzed - if (m_speed == 0) - return false; - - // last walk is not done yet - if (m_walking && (m_walkTimer.ticksElapsed() < getStepDuration()) && !isAutoWalking() && !isServerWalking()) - return false; - - auto tile = g_map.getTile(getPrewalkingPosition(true)); - if (isPreWalking() && (!m_lastPrewalkDone || (tile && tile->isBlocking()))) - return false; - - // cannot walk while already walking - if ((m_walking && !isAutoWalking() && !isServerWalking()) && (!isPreWalking() || !m_lastPrewalkDone)) - return false; - - // Without new walking limit only to 1 prewalk - if (!m_preWalking.empty() && !g_game.getFeature(Otc::GameNewWalking)) - return false; - - // Limit pre walking steps - if (m_preWalking.size() >= g_game.getMaxPreWalkingSteps()) // max 3 extra steps - return false; - - if (!m_preWalking.empty()) { // disallow diagonal extented prewalking walking - auto dir = m_position.getDirectionFromPosition(m_preWalking.back()); - if ((dir == Otc::NorthWest || dir == Otc::NorthEast || dir == Otc::SouthWest || dir == Otc::SouthEast)) { - return false; - } - if (!g_map.getTile(getPrewalkingPosition())->isWalkable()) - return false; - } - - return true; -} - -void LocalPlayer::walk(const Position& oldPos, const Position& newPos) -{ - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] LocalPlayer::walk", (int)g_clock.millis())); - } - - m_lastAutoWalkRetries = 0; - // a prewalk was going on - if (isPreWalking()) { - for (auto it = m_preWalking.begin(); it != m_preWalking.end(); ++it) { - if (*it == newPos) { - m_preWalking.erase(m_preWalking.begin(), ++it); - if(!isPreWalking()) // reset pre walking - updateWalk(); - return; - } - } - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] LocalPlayer::walk invalid prewalk", (int)g_clock.millis())); - } - - // invalid pre walk - m_preWalking.clear(); - m_serverWalking = true; - if(m_serverWalkEndEvent) - m_serverWalkEndEvent->cancel(); - - Creature::walk(oldPos, newPos); - } else { // no prewalk was going on, this must be an server side automated walk - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] LocalPlayer::walk server walk", (int)g_clock.millis())); - } - - m_serverWalking = true; - if(m_serverWalkEndEvent) - m_serverWalkEndEvent->cancel(); - m_lastAutoWalkRetries = 0; - - Creature::walk(oldPos, newPos); - } -} - -void LocalPlayer::preWalk(Otc::Direction direction) -{ - -} - - -void LocalPlayer::cancelWalk(Otc::Direction direction) -{ - if (g_game.getFeature(Otc::GameNewWalking)) { - return; - } - - return cancelNewWalk(direction); -} - -void LocalPlayer::cancelNewWalk(Otc::Direction dir) -{ - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] cancelWalk", (int)g_clock.millis())); - } - - bool clearedPrewalk = !m_preWalking.empty(); - - m_preWalking.clear(); - g_map.requestVisibleTilesCacheUpdate(); - - if (clearedPrewalk) { - stopWalk(); - } - - m_idleTimer.restart(); - - if (retryAutoWalk()) return; - - if (!g_game.isIgnoringServerDirection() || !g_game.getFeature(Otc::GameNewWalking)) { - setDirection(dir); - } - callLuaField("onCancelWalk", dir); -} - -bool LocalPlayer::predictiveCancelWalk(const Position& pos, uint32_t predictionId, Otc::Direction dir) -{ - if (g_extras.debugPredictiveWalking) { - g_logger.info(stdext::format("[%i] predictiveCancelWalk: %i - %i", (int)g_clock.millis(), predictionId, (int)m_preWalking.size())); - } - return false; -} - -bool LocalPlayer::retryAutoWalk() -{ - return false; -} - - -bool LocalPlayer::autoWalk(Position destination, bool retry) -{ - // reset state - m_autoWalkDestination = Position(); - m_lastAutoWalkPosition = Position(); - if(m_autoWalkContinueEvent) - m_autoWalkContinueEvent->cancel(); - m_autoWalkContinueEvent = nullptr; - - if (!retry) - m_lastAutoWalkRetries = 0; - - if(destination == getPrewalkingPosition()) - return true; - - m_autoWalkDestination = destination; - auto self(asLocalPlayer()); - g_map.findPathAsync(getPrewalkingPosition(), destination, [self](PathFindResult_ptr result) { - if (self->m_autoWalkDestination != result->destination) - return; - if (g_extras.debugWalking) { - g_logger.info(stdext::format("Async path search finished with complexity %i/50000", result->complexity)); - } - - if (result->status != Otc::PathFindResultOk) { - if (self->m_lastAutoWalkRetries > 0 && self->m_lastAutoWalkRetries <= 3) { // try again in 300, 700, 1200 ms if canceled by server - self->m_autoWalkContinueEvent = g_dispatcher.scheduleEvent(std::bind(&LocalPlayer::autoWalk, self, result->destination, true), 200 + self->m_lastAutoWalkRetries * 100); - return; - } - self->m_autoWalkDestination = Position(); - self->callLuaField("onAutoWalkFail", result->status); - return; - } - - if(!g_game.getFeature(Otc::GameNewWalking) && result->path.size() > 127) - result->path.resize(127); - else if(result->path.size() > 4095) - result->path.resize(4095); - - if (result->path.empty()) { - self->m_autoWalkDestination = Position(); - self->callLuaField("onAutoWalkFail", result->status); - return; - } - - auto finalAutowalkPos = self->getPrewalkingPosition().translatedToDirections(result->path).back(); - if (self->m_autoWalkDestination != finalAutowalkPos) { - self->m_lastAutoWalkPosition = finalAutowalkPos; - } - - g_game.autoWalk(result->path, result->start); - }); - - if(!retry) - lockWalk(); - return true; -} - -void LocalPlayer::stopAutoWalk() -{ - m_autoWalkDestination = Position(); - m_lastAutoWalkPosition = Position(); - - if (m_autoWalkContinueEvent) { - m_autoWalkContinueEvent->cancel(); - m_autoWalkContinueEvent = nullptr; - } -} - -void LocalPlayer::stopWalk() { - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] stopWalk", (int)g_clock.millis())); - } - - Creature::stopWalk(); // will call terminateWalk - - m_preWalking.clear(); -} - -void LocalPlayer::updateWalkOffset(int totalPixelsWalked, bool inNextFrame) -{ - // pre walks offsets are calculated in the oposite direction - if(isPreWalking()) { - Point& walkOffset = inNextFrame ? m_walkOffsetInNextFrame : m_walkOffset; - walkOffset = Point(0,0); - if(m_walkDirection == Otc::North || m_walkDirection == Otc::NorthEast || m_walkDirection == Otc::NorthWest) - walkOffset.y = -totalPixelsWalked; - else if(m_walkDirection == Otc::South || m_walkDirection == Otc::SouthEast || m_walkDirection == Otc::SouthWest) - walkOffset.y = totalPixelsWalked; - - if(m_walkDirection == Otc::East || m_walkDirection == Otc::NorthEast || m_walkDirection == Otc::SouthEast) - walkOffset.x = totalPixelsWalked; - else if(m_walkDirection == Otc::West || m_walkDirection == Otc::NorthWest || m_walkDirection == Otc::SouthWest) - walkOffset.x = -totalPixelsWalked; - } else - Creature::updateWalkOffset(totalPixelsWalked, inNextFrame); -} - -void LocalPlayer::updateWalk() -{ - if (!m_walking) - return; - - float walkTicksPerPixel = ((float)(getStepDuration(true) + 10)) / 32.0f; - int totalPixelsWalked = std::min(m_walkTimer.ticksElapsed() / walkTicksPerPixel, 32.0f); - int totalPixelsWalkedInNextFrame = std::min((m_walkTimer.ticksElapsed() + 15) / walkTicksPerPixel, 32.0f); - - // needed for paralyze effect - m_walkedPixels = std::max(m_walkedPixels, totalPixelsWalked); - int walkedPixelsInNextFrame = std::max(m_walkedPixels, totalPixelsWalkedInNextFrame); - - // update walk animation and offsets - updateWalkAnimation(totalPixelsWalked); - updateWalkOffset(m_walkedPixels); - updateWalkOffset(walkedPixelsInNextFrame, true); - updateWalkingTile(); - - int stepDuration = getStepDuration(); - - // terminate walk only when client and server side walk are completed - if (m_walking && m_walkTimer.ticksElapsed() >= stepDuration) - m_lastPrewalkDone = true; - if(m_walking && m_walkTimer.ticksElapsed() >= stepDuration && !isPreWalking()) - terminateWalk(); -} - -void LocalPlayer::terminateWalk() -{ - if (g_extras.debugWalking) { - g_logger.info(stdext::format("[%i] terminateWalk", (int)g_clock.millis())); - } - - Creature::terminateWalk(); - m_idleTimer.restart(); - m_preWalking.clear(); - m_walking = false; - - auto self = asLocalPlayer(); - - if(m_serverWalking) { - if(m_serverWalkEndEvent) - m_serverWalkEndEvent->cancel(); - m_serverWalkEndEvent = g_dispatcher.scheduleEvent([self] { - self->m_serverWalking = false; - }, 100); - } - - callLuaField("onWalkFinish"); -} - -void LocalPlayer::onAppear() -{ - Creature::onAppear(); - - /* Does not seem to be needed anymore - // on teleports lock the walk - if(!m_oldPosition.isInRange(m_position,1,1)) - lockWalk(); - */ -} - -void LocalPlayer::onPositionChange(const Position& newPos, const Position& oldPos) -{ - Creature::onPositionChange(newPos, oldPos); - - if(newPos == m_autoWalkDestination) - stopAutoWalk(); - else if(m_autoWalkDestination.isValid() && newPos == m_lastAutoWalkPosition) - autoWalk(m_autoWalkDestination); - - m_walkMatrix.updatePosition(newPos); -} - -void LocalPlayer::turn(Otc::Direction direction) -{ - Creature::setDirection(direction); - callLuaField("onTurn", direction); -} - -void LocalPlayer::setStates(int states) -{ - if(m_states != states) { - int oldStates = m_states; - m_states = states; - - callLuaField("onStatesChange", states, oldStates); - } -} - -void LocalPlayer::setSkill(Otc::Skill skill, int level, int levelPercent) -{ - if(skill >= Otc::LastSkill) { - g_logger.traceError("invalid skill"); - return; - } - - int oldLevel = m_skillsLevel[skill]; - int oldLevelPercent = m_skillsLevelPercent[skill]; - - if(level != oldLevel || levelPercent != oldLevelPercent) { - m_skillsLevel[skill] = level; - m_skillsLevelPercent[skill] = levelPercent; - - callLuaField("onSkillChange", skill, level, levelPercent, oldLevel, oldLevelPercent); - } -} - -void LocalPlayer::setBaseSkill(Otc::Skill skill, int baseLevel) -{ - if(skill >= Otc::LastSkill) { - g_logger.traceError("invalid skill"); - return; - } - - int oldBaseLevel = m_skillsBaseLevel[skill]; - if(baseLevel != oldBaseLevel) { - m_skillsBaseLevel[skill] = baseLevel; - - callLuaField("onBaseSkillChange", skill, baseLevel, oldBaseLevel); - } -} - -void LocalPlayer::setHealth(double health, double maxHealth) -{ - if(m_health != health || m_maxHealth != maxHealth) { - double oldHealth = m_health; - double oldMaxHealth = m_maxHealth; - m_health = health; - m_maxHealth = maxHealth; - - callLuaField("onHealthChange", health, maxHealth, oldHealth, oldMaxHealth); - - // cannot walk while dying - if(health == 0) { - if(isPreWalking()) - stopWalk(); - lockWalk(); - } - } -} - -void LocalPlayer::setFreeCapacity(double freeCapacity) -{ - if(m_freeCapacity != freeCapacity) { - double oldFreeCapacity = m_freeCapacity; - m_freeCapacity = freeCapacity; - - callLuaField("onFreeCapacityChange", freeCapacity, oldFreeCapacity); - } -} - -void LocalPlayer::setTotalCapacity(double totalCapacity) -{ - if(m_totalCapacity != totalCapacity) { - double oldTotalCapacity = m_totalCapacity; - m_totalCapacity = totalCapacity; - - callLuaField("onTotalCapacityChange", totalCapacity, oldTotalCapacity); - } -} - -void LocalPlayer::setExperience(double experience) -{ - if(m_experience != experience) { - double oldExperience = m_experience; - m_experience = experience; - - callLuaField("onExperienceChange", experience, oldExperience); - } -} - -void LocalPlayer::setLevel(double level, double levelPercent) -{ - if(m_level != level || m_levelPercent != levelPercent) { - double oldLevel = m_level; - double oldLevelPercent = m_levelPercent; - m_level = level; - m_levelPercent = levelPercent; - - callLuaField("onLevelChange", level, levelPercent, oldLevel, oldLevelPercent); - } -} - -void LocalPlayer::setMana(double mana, double maxMana) -{ - if(m_mana != mana || m_maxMana != maxMana) { - double oldMana = m_mana; - double oldMaxMana; - m_mana = mana; - m_maxMana = maxMana; - - callLuaField("onManaChange", mana, maxMana, oldMana, oldMaxMana); - } -} - -void LocalPlayer::setMagicLevel(double magicLevel, double magicLevelPercent) -{ - if(m_magicLevel != magicLevel || m_magicLevelPercent != magicLevelPercent) { - double oldMagicLevel = m_magicLevel; - double oldMagicLevelPercent = m_magicLevelPercent; - m_magicLevel = magicLevel; - m_magicLevelPercent = magicLevelPercent; - - callLuaField("onMagicLevelChange", magicLevel, magicLevelPercent, oldMagicLevel, oldMagicLevelPercent); - } -} - -void LocalPlayer::setBaseMagicLevel(double baseMagicLevel) -{ - if(m_baseMagicLevel != baseMagicLevel) { - double oldBaseMagicLevel = m_baseMagicLevel; - m_baseMagicLevel = baseMagicLevel; - - callLuaField("onBaseMagicLevelChange", baseMagicLevel, oldBaseMagicLevel); - } -} - -void LocalPlayer::setSoul(double soul) -{ - if(m_soul != soul) { - double oldSoul = m_soul; - m_soul = soul; - - callLuaField("onSoulChange", soul, oldSoul); - } -} - -void LocalPlayer::setStamina(double stamina) -{ - if(m_stamina != stamina) { - double oldStamina = m_stamina; - m_stamina = stamina; - - callLuaField("onStaminaChange", stamina, oldStamina); - } -} - -void LocalPlayer::setInventoryItem(Otc::InventorySlot inventory, const ItemPtr& item) -{ - if(inventory >= Otc::LastInventorySlot) { - g_logger.traceError("invalid slot"); - return; - } - - if(m_inventoryItems[inventory] != item) { - ItemPtr oldItem = m_inventoryItems[inventory]; - m_inventoryItems[inventory] = item; - - callLuaField("onInventoryChange", inventory, item, oldItem); - } -} - -void LocalPlayer::setVocation(int vocation) -{ - if(m_vocation != vocation) { - int oldVocation = m_vocation; - m_vocation = vocation; - - callLuaField("onVocationChange", vocation, oldVocation); - } -} - -void LocalPlayer::setPremium(bool premium) -{ - if(m_premium != premium) { - m_premium = premium; - - callLuaField("onPremiumChange", premium); - } -} - -void LocalPlayer::setRegenerationTime(double regenerationTime) -{ - if(m_regenerationTime != regenerationTime) { - double oldRegenerationTime = m_regenerationTime; - m_regenerationTime = regenerationTime; - - callLuaField("onRegenerationChange", regenerationTime, oldRegenerationTime); - } -} - -void LocalPlayer::setOfflineTrainingTime(double offlineTrainingTime) -{ - if(m_offlineTrainingTime != offlineTrainingTime) { - double oldOfflineTrainingTime = m_offlineTrainingTime; - m_offlineTrainingTime = offlineTrainingTime; - - callLuaField("onOfflineTrainingChange", offlineTrainingTime, oldOfflineTrainingTime); - } -} - -void LocalPlayer::setSpells(const std::vector& spells) -{ - if(m_spells != spells) { - std::vector oldSpells = m_spells; - m_spells = spells; - - callLuaField("onSpellsChange", spells, oldSpells); - } -} - -void LocalPlayer::setBlessings(int blessings) -{ - if(blessings != m_blessings) { - int oldBlessings = m_blessings; - m_blessings = blessings; - - callLuaField("onBlessingsChange", blessings, oldBlessings); - } -} - -bool LocalPlayer::hasSight(const Position& pos) -{ - return m_position.isInRange(pos, g_map.getAwareRange().left - 1, g_map.getAwareRange().top - 1); -} diff --git a/src/client/localplayer.h b/src/client/localplayer.h deleted file mode 100644 index f2788f0..0000000 --- a/src/client/localplayer.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LOCALPLAYER_H -#define LOCALPLAYER_H - -#include "player.h" -#include "walkmatrix.h" - -// @bindclass -class LocalPlayer : public Player -{ - enum { - PREWALK_TIMEOUT = 1000 - }; - -public: - LocalPlayer(); - - void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr) override; - - void unlockWalk() { m_walkLockExpiration = 0; } - void lockWalk(int millis = 200); - void stopAutoWalk(); - bool autoWalk(Position destination, bool retry = false); - bool canWalk(Otc::Direction direction, bool ignoreLock = false); - bool isWalkLocked() { - return (m_walkLockExpiration != 0 && g_clock.millis() < m_walkLockExpiration); - } - void turn(Otc::Direction) override; - - void setStates(int states); - void setSkill(Otc::Skill skill, int level, int levelPercent); - void setBaseSkill(Otc::Skill skill, int baseLevel); - void setHealth(double health, double maxHealth); - void setFreeCapacity(double freeCapacity); - void setTotalCapacity(double totalCapacity); - void setExperience(double experience); - void setLevel(double level, double levelPercent); - void setMana(double mana, double maxMana); - void setMagicLevel(double magicLevel, double magicLevelPercent); - void setBaseMagicLevel(double baseMagicLevel); - void setSoul(double soul); - void setStamina(double stamina); - void setKnown(bool known) { m_known = known; } - void setPendingGame(bool pending) { m_pending = pending; } - void setInventoryItem(Otc::InventorySlot inventory, const ItemPtr& item); - void setVocation(int vocation); - void setPremium(bool premium); - void setRegenerationTime(double regenerationTime); - void setOfflineTrainingTime(double offlineTrainingTime); - void setSpells(const std::vector& spells); - void setBlessings(int blessings); - - int getStates() { return m_states; } - int getSkillLevel(Otc::Skill skill) { return m_skillsLevel[skill]; } - int getSkillBaseLevel(Otc::Skill skill) { return m_skillsBaseLevel[skill]; } - int getSkillLevelPercent(Otc::Skill skill) { return m_skillsLevelPercent[skill]; } - int getVocation() { return m_vocation; } - double getHealth() { return m_health; } - double getMaxHealth() { return m_maxHealth; } - double getFreeCapacity() { return m_freeCapacity; } - double getTotalCapacity() { return m_totalCapacity; } - double getExperience() { return m_experience; } - double getLevel() { return m_level; } - double getLevelPercent() { return m_levelPercent; } - double getMana() { return m_mana; } - double getMaxMana() { return std::max(m_mana, m_maxMana); } - double getMagicLevel() { return m_magicLevel; } - double getMagicLevelPercent() { return m_magicLevelPercent; } - double getBaseMagicLevel() { return m_baseMagicLevel; } - double getSoul() { return m_soul; } - double getStamina() { return m_stamina; } - double getRegenerationTime() { return m_regenerationTime; } - double getOfflineTrainingTime() { return m_offlineTrainingTime; } - std::vector getSpells() { return m_spells; } - ItemPtr getInventoryItem(Otc::InventorySlot inventory) { return m_inventoryItems[inventory]; } - int getBlessings() { return m_blessings; } - - bool hasSight(const Position& pos); - bool isKnown() { return m_known; } - bool isAutoWalking() { return m_autoWalkDestination.isValid(); } - bool isServerWalking() override { return m_serverWalking; } - bool isPremium() { return m_premium; } - bool isPendingGame() { return m_pending; } - - LocalPlayerPtr asLocalPlayer() { return static_self_cast(); } - bool isLocalPlayer() override { return true; } - - void onAppear() override; - void onPositionChange(const Position& newPos, const Position& oldPos) override; - - // pre walking - void preWalk(Otc::Direction direction); - bool isPreWalking() override { return !m_preWalking.empty(); } - Position getPrewalkingPosition(bool beforePrewalk = false) override { - if(m_preWalking.empty()) - return m_position; - else if (!beforePrewalk && m_preWalking.size() == 1) - return m_position; - auto ret = m_preWalking.rbegin(); - if(!beforePrewalk) - ret++; - return *ret; - } - - uint32_t getWalkPrediction(const Position& pos) - { - return m_walkMatrix.get(pos); - }; - - std::string dumpWalkMatrix() - { - return m_walkMatrix.dump(); - } - - void startServerWalking() { m_serverWalking = true; } - void finishServerWalking() { m_serverWalking = false; } - -protected: - void walk(const Position& oldPos, const Position& newPos); - void cancelWalk(Otc::Direction direction = Otc::InvalidDirection); - - void cancelNewWalk(Otc::Direction dir); - bool predictiveCancelWalk(const Position& pos, uint32_t predictionId, Otc::Direction dir); - - bool retryAutoWalk(); - void stopWalk(); - - friend class Game; - -protected: - void updateWalkOffset(int totalPixelsWalked, bool inNextFrame = false) override; - void updateWalk() override; - void terminateWalk() override; - -private: - // walk related - Position m_autoWalkDestination; - Position m_lastAutoWalkPosition; - int m_lastAutoWalkRetries = 0; - ScheduledEventPtr m_serverWalkEndEvent; - ScheduledEventPtr m_autoWalkContinueEvent; - ticks_t m_walkLockExpiration; - - // walking and pre walking - std::list m_preWalking; - bool m_serverWalking = false; - bool m_lastPrewalkDone = false; - WalkMatrix m_walkMatrix; - - bool m_premium = false; - bool m_known = false; - bool m_pending = false; - - ItemPtr m_inventoryItems[Otc::LastInventorySlot]; - Timer m_idleTimer; - - std::array m_skillsLevel; - std::array m_skillsBaseLevel; - std::array m_skillsLevelPercent; - std::vector m_spells; - - int m_states; - int m_vocation; - int m_blessings; - - double m_health; - double m_maxHealth; - double m_freeCapacity; - double m_totalCapacity; - double m_experience; - double m_level; - double m_levelPercent; - double m_mana; - double m_maxMana; - double m_magicLevel; - double m_magicLevelPercent; - double m_baseMagicLevel; - double m_soul; - double m_stamina; - double m_regenerationTime; - double m_offlineTrainingTime; -}; - -#endif diff --git a/src/client/luafunctions_client.cpp b/src/client/luafunctions_client.cpp deleted file mode 100644 index 68b7f42..0000000 --- a/src/client/luafunctions_client.cpp +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "client.h" -#include "luavaluecasts_client.h" -#include "game.h" -#include "tile.h" -#include "houses.h" -#include "towns.h" -#include "container.h" -#include "item.h" -#include "effect.h" -#include "missile.h" -#include "statictext.h" -#include "animatedtext.h" -#include "creature.h" -#include "player.h" -#include "localplayer.h" -#include "map.h" -#include "minimap.h" -#include "thingtypemanager.h" -#include "spritemanager.h" -#include "shadermanager.h" -#include "protocolgame.h" -#include "uiitem.h" -#include "uicreature.h" -#include "uimap.h" -#include "uiminimap.h" -#include "uimapanchorlayout.h" -#include "uiprogressrect.h" -#include "uisprite.h" -#include "outfit.h" - -#include - -void Client::registerLuaFunctions() -{ - g_lua.registerSingletonClass("g_things"); - g_lua.bindSingletonFunction("g_things", "loadDat", &ThingTypeManager::loadDat, &g_things); -#ifdef WITH_ENCRYPTION - g_lua.bindSingletonFunction("g_things", "saveDat", &ThingTypeManager::saveDat, &g_things); - g_lua.bindSingletonFunction("g_things", "dumpTextures", &ThingTypeManager::dumpTextures, &g_things); - g_lua.bindSingletonFunction("g_things", "replaceTextures", &ThingTypeManager::replaceTextures, &g_things); -#endif - g_lua.bindSingletonFunction("g_things", "loadOtb", &ThingTypeManager::loadOtb, &g_things); - g_lua.bindSingletonFunction("g_things", "loadXml", &ThingTypeManager::loadXml, &g_things); - g_lua.bindSingletonFunction("g_things", "loadOtml", &ThingTypeManager::loadOtml, &g_things); - g_lua.bindSingletonFunction("g_things", "isDatLoaded", &ThingTypeManager::isDatLoaded, &g_things); - g_lua.bindSingletonFunction("g_things", "isOtbLoaded", &ThingTypeManager::isOtbLoaded, &g_things); - g_lua.bindSingletonFunction("g_things", "getDatSignature", &ThingTypeManager::getDatSignature, &g_things); - g_lua.bindSingletonFunction("g_things", "getContentRevision", &ThingTypeManager::getContentRevision, &g_things); - g_lua.bindSingletonFunction("g_things", "getThingType", &ThingTypeManager::getThingType, &g_things); - g_lua.bindSingletonFunction("g_things", "getItemType", &ThingTypeManager::getItemType, &g_things); - g_lua.bindSingletonFunction("g_things", "getThingTypes", &ThingTypeManager::getThingTypes, &g_things); - g_lua.bindSingletonFunction("g_things", "findItemTypeByClientId", &ThingTypeManager::findItemTypeByClientId, &g_things); - g_lua.bindSingletonFunction("g_things", "findItemTypeByName", &ThingTypeManager::findItemTypeByName, &g_things); - g_lua.bindSingletonFunction("g_things", "findItemTypesByName", &ThingTypeManager::findItemTypesByName, &g_things); - g_lua.bindSingletonFunction("g_things", "findItemTypesByString", &ThingTypeManager::findItemTypesByString, &g_things); - g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things); - g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things); - g_lua.bindSingletonFunction("g_things", "getMarketCategories", &ThingTypeManager::getMarketCategories, &g_things); - - g_lua.registerSingletonClass("g_houses"); - g_lua.bindSingletonFunction("g_houses", "clear", &HouseManager::clear, &g_houses); - g_lua.bindSingletonFunction("g_houses", "load", &HouseManager::load, &g_houses); - g_lua.bindSingletonFunction("g_houses", "save", &HouseManager::save, &g_houses); - g_lua.bindSingletonFunction("g_houses", "getHouse", &HouseManager::getHouse, &g_houses); - g_lua.bindSingletonFunction("g_houses", "getHouseByName", &HouseManager::getHouseByName, &g_houses); - g_lua.bindSingletonFunction("g_houses", "addHouse", &HouseManager::addHouse, &g_houses); - g_lua.bindSingletonFunction("g_houses", "removeHouse", &HouseManager::removeHouse, &g_houses); - g_lua.bindSingletonFunction("g_houses", "getHouseList", &HouseManager::getHouseList, &g_houses); - g_lua.bindSingletonFunction("g_houses", "filterHouses", &HouseManager::filterHouses, &g_houses); - g_lua.bindSingletonFunction("g_houses", "sort", &HouseManager::sort, &g_houses); - - g_lua.registerSingletonClass("g_towns"); - g_lua.bindSingletonFunction("g_towns", "getTown", &TownManager::getTown, &g_towns); - g_lua.bindSingletonFunction("g_towns", "getTownByName",&TownManager::getTownByName,&g_towns); - g_lua.bindSingletonFunction("g_towns", "addTown", &TownManager::addTown, &g_towns); - g_lua.bindSingletonFunction("g_towns", "removeTown", &TownManager::removeTown, &g_towns); - g_lua.bindSingletonFunction("g_towns", "getTowns", &TownManager::getTowns, &g_towns); - g_lua.bindSingletonFunction("g_towns", "sort", &TownManager::sort, &g_towns); - - g_lua.registerSingletonClass("g_sprites"); - g_lua.bindSingletonFunction("g_sprites", "loadSpr", &SpriteManager::loadSpr, &g_sprites); -#ifdef WITH_ENCRYPTION - g_lua.bindSingletonFunction("g_sprites", "saveSpr", &SpriteManager::saveSpr, &g_sprites); - g_lua.bindSingletonFunction("g_sprites", "dumpSprites", &SpriteManager::dumpSprites, &g_sprites); - g_lua.bindSingletonFunction("g_sprites", "encryptSprites", &SpriteManager::encryptSprites, &g_sprites); -#endif - g_lua.bindSingletonFunction("g_sprites", "unload", &SpriteManager::unload, &g_sprites); - g_lua.bindSingletonFunction("g_sprites", "isLoaded", &SpriteManager::isLoaded, &g_sprites); - g_lua.bindSingletonFunction("g_sprites", "getSprSignature", &SpriteManager::getSignature, &g_sprites); - g_lua.bindSingletonFunction("g_sprites", "getSpritesCount", &SpriteManager::getSpritesCount, &g_sprites); - - g_lua.registerSingletonClass("g_map"); - g_lua.bindSingletonFunction("g_map", "isLookPossible", &Map::isLookPossible, &g_map); - g_lua.bindSingletonFunction("g_map", "isCovered", &Map::isCovered, &g_map); - g_lua.bindSingletonFunction("g_map", "isCompletelyCovered", &Map::isCompletelyCovered, &g_map); - g_lua.bindSingletonFunction("g_map", "addThing", &Map::addThing, &g_map); - g_lua.bindSingletonFunction("g_map", "getThing", &Map::getThing, &g_map); - g_lua.bindSingletonFunction("g_map", "removeThingByPos", &Map::removeThingByPos, &g_map); - g_lua.bindSingletonFunction("g_map", "removeThing", &Map::removeThing, &g_map); - g_lua.bindSingletonFunction("g_map", "colorizeThing", &Map::colorizeThing, &g_map); - g_lua.bindSingletonFunction("g_map", "removeThingColor", &Map::removeThingColor, &g_map); - g_lua.bindSingletonFunction("g_map", "clean", &Map::clean, &g_map); - g_lua.bindSingletonFunction("g_map", "cleanTile", &Map::cleanTile, &g_map); - g_lua.bindSingletonFunction("g_map", "cleanTexts", &Map::cleanTexts, &g_map); - g_lua.bindSingletonFunction("g_map", "getTile", &Map::getTile, &g_map); - g_lua.bindSingletonFunction("g_map", "getOrCreateTile", &Map::getOrCreateTile, &g_map); - g_lua.bindSingletonFunction("g_map", "getTiles", &Map::getTiles, &g_map); - g_lua.bindSingletonFunction("g_map", "setCentralPosition", &Map::setCentralPosition, &g_map); - g_lua.bindSingletonFunction("g_map", "getCentralPosition", &Map::getCentralPosition, &g_map); - g_lua.bindSingletonFunction("g_map", "getCreatureById", &Map::getCreatureById, &g_map); - g_lua.bindSingletonFunction("g_map", "removeCreatureById", &Map::removeCreatureById, &g_map); - g_lua.bindSingletonFunction("g_map", "getSpectators", &Map::getSpectators, &g_map); - g_lua.bindSingletonFunction("g_map", "getSpectatorsInRange", &Map::getSpectatorsInRange, &g_map); - g_lua.bindSingletonFunction("g_map", "getSpectatorsInRangeEx", &Map::getSpectatorsInRangeEx, &g_map); - g_lua.bindSingletonFunction("g_map", "getSpectatorsByPattern", &Map::getSpectatorsByPattern, &g_map); - g_lua.bindSingletonFunction("g_map", "findPath", &Map::findPath, &g_map); - g_lua.bindSingletonFunction("g_map", "loadOtbm", &Map::loadOtbm, &g_map); - g_lua.bindSingletonFunction("g_map", "saveOtbm", &Map::saveOtbm, &g_map); - g_lua.bindSingletonFunction("g_map", "loadOtcm", &Map::loadOtcm, &g_map); - g_lua.bindSingletonFunction("g_map", "saveOtcm", &Map::saveOtcm, &g_map); - g_lua.bindSingletonFunction("g_map", "getHouseFile", &Map::getHouseFile, &g_map); - g_lua.bindSingletonFunction("g_map", "setHouseFile", &Map::setHouseFile, &g_map); - g_lua.bindSingletonFunction("g_map", "getSpawnFile", &Map::getSpawnFile, &g_map); - g_lua.bindSingletonFunction("g_map", "setSpawnFile", &Map::setSpawnFile, &g_map); - g_lua.bindSingletonFunction("g_map", "createTile", &Map::createTile, &g_map); - g_lua.bindSingletonFunction("g_map", "setWidth", &Map::setWidth, &g_map); - g_lua.bindSingletonFunction("g_map", "setHeight", &Map::setHeight, &g_map); - g_lua.bindSingletonFunction("g_map", "getSize", &Map::getSize, &g_map); - g_lua.bindSingletonFunction("g_map", "setDescription", &Map::setDescription, &g_map); - g_lua.bindSingletonFunction("g_map", "getDescriptions", &Map::getDescriptions, &g_map); - g_lua.bindSingletonFunction("g_map", "clearDescriptions", &Map::clearDescriptions, &g_map); - g_lua.bindSingletonFunction("g_map", "setShowZone", &Map::setShowZone, &g_map); - g_lua.bindSingletonFunction("g_map", "setShowZones", &Map::setShowZones, &g_map); - g_lua.bindSingletonFunction("g_map", "setZoneColor", &Map::setZoneColor, &g_map); - g_lua.bindSingletonFunction("g_map", "setZoneOpacity", &Map::setZoneOpacity, &g_map); - g_lua.bindSingletonFunction("g_map", "getZoneOpacity", &Map::getZoneOpacity, &g_map); - g_lua.bindSingletonFunction("g_map", "getZoneColor", &Map::getZoneColor, &g_map); - g_lua.bindSingletonFunction("g_map", "showZones", &Map::showZones, &g_map); - g_lua.bindSingletonFunction("g_map", "showZone", &Map::showZone, &g_map); - g_lua.bindSingletonFunction("g_map", "setForceShowAnimations", &Map::setForceShowAnimations, &g_map); - g_lua.bindSingletonFunction("g_map", "isForcingAnimations", &Map::isForcingAnimations, &g_map); - g_lua.bindSingletonFunction("g_map", "isShowingAnimations", &Map::isShowingAnimations, &g_map); - g_lua.bindSingletonFunction("g_map", "setShowAnimations", &Map::setShowAnimations, &g_map); - g_lua.bindSingletonFunction("g_map", "findItemsById", &Map::findItemsById, &g_map); - g_lua.bindSingletonFunction("g_map", "getAwareRange", &Map::getAwareRangeAsSize, &g_map); - g_lua.bindSingletonFunction("g_map", "findEveryPath", &Map::findEveryPath, &g_map); - g_lua.bindSingletonFunction("g_map", "getMinimapColor", &Map::getMinimapColor, &g_map); - g_lua.bindSingletonFunction("g_map", "isPatchable", &Map::isPatchable, &g_map); - g_lua.bindSingletonFunction("g_map", "isWalkable", &Map::isWalkable, &g_map); - g_lua.bindSingletonFunction("g_map", "checkSightLine", &Map::checkSightLine, &g_map); - g_lua.bindSingletonFunction("g_map", "isSightClear", &Map::isSightClear, &g_map); - - g_lua.registerSingletonClass("g_minimap"); - g_lua.bindSingletonFunction("g_minimap", "clean", &Minimap::clean, &g_minimap); - g_lua.bindSingletonFunction("g_minimap", "loadImage", &Minimap::loadImage, &g_minimap); - g_lua.bindSingletonFunction("g_minimap", "saveImage", &Minimap::saveImage, &g_minimap); - g_lua.bindSingletonFunction("g_minimap", "loadOtmm", &Minimap::loadOtmm, &g_minimap); - g_lua.bindSingletonFunction("g_minimap", "saveOtmm", &Minimap::saveOtmm, &g_minimap); - - g_lua.registerSingletonClass("g_creatures"); - g_lua.bindSingletonFunction("g_creatures", "getCreatures", &CreatureManager::getCreatures, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "getCreatureByName", &CreatureManager::getCreatureByName, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "getCreatureByLook", &CreatureManager::getCreatureByLook, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "getSpawn", &CreatureManager::getSpawn, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "getSpawnForPlacePos", &CreatureManager::getSpawnForPlacePos, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "addSpawn", &CreatureManager::addSpawn, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "loadMonsters", &CreatureManager::loadMonsters, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "loadNpcs", &CreatureManager::loadNpcs, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "loadSingleCreature", &CreatureManager::loadSingleCreature, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "loadSpawns", &CreatureManager::loadSpawns, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "saveSpawns", &CreatureManager::saveSpawns, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "isLoaded", &CreatureManager::isLoaded, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "isSpawnLoaded", &CreatureManager::isSpawnLoaded, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "clear", &CreatureManager::clear, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "clearSpawns", &CreatureManager::clearSpawns, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "getSpawns", &CreatureManager::getSpawns, &g_creatures); - g_lua.bindSingletonFunction("g_creatures", "deleteSpawn", &CreatureManager::deleteSpawn, &g_creatures); - - g_lua.registerSingletonClass("g_game"); - g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game); - g_lua.bindSingletonFunction("g_game", "cancelLogin", &Game::cancelLogin, &g_game); - g_lua.bindSingletonFunction("g_game", "forceLogout", &Game::forceLogout, &g_game); - g_lua.bindSingletonFunction("g_game", "safeLogout", &Game::safeLogout, &g_game); - g_lua.bindSingletonFunction("g_game", "walk", &Game::walk, &g_game); - g_lua.bindSingletonFunction("g_game", "autoWalk", &Game::autoWalk, &g_game); - g_lua.bindSingletonFunction("g_game", "turn", &Game::turn, &g_game); - g_lua.bindSingletonFunction("g_game", "stop", &Game::stop, &g_game); - g_lua.bindSingletonFunction("g_game", "look", &Game::look, &g_game); - g_lua.bindSingletonFunction("g_game", "move", &Game::move, &g_game); - g_lua.bindSingletonFunction("g_game", "moveRaw", &Game::moveRaw, &g_game); - g_lua.bindSingletonFunction("g_game", "moveToParentContainer", &Game::moveToParentContainer, &g_game); - g_lua.bindSingletonFunction("g_game", "rotate", &Game::rotate, &g_game); - g_lua.bindSingletonFunction("g_game", "wrap", &Game::wrap, &g_game); - g_lua.bindSingletonFunction("g_game", "use", &Game::use, &g_game); - g_lua.bindSingletonFunction("g_game", "useWith", &Game::useWith, &g_game); - g_lua.bindSingletonFunction("g_game", "useInventoryItem", &Game::useInventoryItem, &g_game); - g_lua.bindSingletonFunction("g_game", "useInventoryItemWith", &Game::useInventoryItemWith, &g_game); - g_lua.bindSingletonFunction("g_game", "findItemInContainers", &Game::findItemInContainers, &g_game); - g_lua.bindSingletonFunction("g_game", "open", &Game::open, &g_game); - g_lua.bindSingletonFunction("g_game", "openParent", &Game::openParent, &g_game); - g_lua.bindSingletonFunction("g_game", "close", &Game::close, &g_game); - g_lua.bindSingletonFunction("g_game", "refreshContainer", &Game::refreshContainer, &g_game); - g_lua.bindSingletonFunction("g_game", "attack", &Game::attack, &g_game); - g_lua.bindSingletonFunction("g_game", "cancelAttack", &Game::cancelAttack, &g_game); - g_lua.bindSingletonFunction("g_game", "follow", &Game::follow, &g_game); - g_lua.bindSingletonFunction("g_game", "cancelFollow", &Game::cancelFollow, &g_game); - g_lua.bindSingletonFunction("g_game", "cancelAttackAndFollow", &Game::cancelAttackAndFollow, &g_game); - g_lua.bindSingletonFunction("g_game", "talk", &Game::talk, &g_game); - g_lua.bindSingletonFunction("g_game", "talkChannel", &Game::talkChannel, &g_game); - g_lua.bindSingletonFunction("g_game", "talkPrivate", &Game::talkPrivate, &g_game); - g_lua.bindSingletonFunction("g_game", "openPrivateChannel", &Game::openPrivateChannel, &g_game); - g_lua.bindSingletonFunction("g_game", "requestChannels", &Game::requestChannels, &g_game); - g_lua.bindSingletonFunction("g_game", "joinChannel", &Game::joinChannel, &g_game); - g_lua.bindSingletonFunction("g_game", "leaveChannel", &Game::leaveChannel, &g_game); - g_lua.bindSingletonFunction("g_game", "closeNpcChannel", &Game::closeNpcChannel, &g_game); - g_lua.bindSingletonFunction("g_game", "openOwnChannel", &Game::openOwnChannel, &g_game); - g_lua.bindSingletonFunction("g_game", "inviteToOwnChannel", &Game::inviteToOwnChannel, &g_game); - g_lua.bindSingletonFunction("g_game", "excludeFromOwnChannel", &Game::excludeFromOwnChannel, &g_game); - g_lua.bindSingletonFunction("g_game", "partyInvite", &Game::partyInvite, &g_game); - g_lua.bindSingletonFunction("g_game", "partyJoin", &Game::partyJoin, &g_game); - g_lua.bindSingletonFunction("g_game", "partyRevokeInvitation", &Game::partyRevokeInvitation, &g_game); - g_lua.bindSingletonFunction("g_game", "partyPassLeadership", &Game::partyPassLeadership, &g_game); - g_lua.bindSingletonFunction("g_game", "partyLeave", &Game::partyLeave, &g_game); - g_lua.bindSingletonFunction("g_game", "partyShareExperience", &Game::partyShareExperience, &g_game); - g_lua.bindSingletonFunction("g_game", "requestOutfit", &Game::requestOutfit, &g_game); - g_lua.bindSingletonFunction("g_game", "changeOutfit", &Game::changeOutfit, &g_game); - g_lua.bindSingletonFunction("g_game", "addVip", &Game::addVip, &g_game); - g_lua.bindSingletonFunction("g_game", "removeVip", &Game::removeVip, &g_game); - g_lua.bindSingletonFunction("g_game", "editVip", &Game::editVip, &g_game); - g_lua.bindSingletonFunction("g_game", "setChaseMode", &Game::setChaseMode, &g_game); - g_lua.bindSingletonFunction("g_game", "setFightMode", &Game::setFightMode, &g_game); - g_lua.bindSingletonFunction("g_game", "setPVPMode", &Game::setPVPMode, &g_game); - g_lua.bindSingletonFunction("g_game", "setSafeFight", &Game::setSafeFight, &g_game); - g_lua.bindSingletonFunction("g_game", "getChaseMode", &Game::getChaseMode, &g_game); - g_lua.bindSingletonFunction("g_game", "getFightMode", &Game::getFightMode, &g_game); - g_lua.bindSingletonFunction("g_game", "getPVPMode", &Game::getPVPMode, &g_game); - g_lua.bindSingletonFunction("g_game", "getUnjustifiedPoints", &Game::getUnjustifiedPoints, &g_game); - g_lua.bindSingletonFunction("g_game", "getOpenPvpSituations", &Game::getOpenPvpSituations, &g_game); - g_lua.bindSingletonFunction("g_game", "isSafeFight", &Game::isSafeFight, &g_game); - g_lua.bindSingletonFunction("g_game", "inspectNpcTrade", &Game::inspectNpcTrade, &g_game); - g_lua.bindSingletonFunction("g_game", "buyItem", &Game::buyItem, &g_game); - g_lua.bindSingletonFunction("g_game", "sellItem", &Game::sellItem, &g_game); - g_lua.bindSingletonFunction("g_game", "closeNpcTrade", &Game::closeNpcTrade, &g_game); - g_lua.bindSingletonFunction("g_game", "requestTrade", &Game::requestTrade, &g_game); - g_lua.bindSingletonFunction("g_game", "inspectTrade", &Game::inspectTrade, &g_game); - g_lua.bindSingletonFunction("g_game", "acceptTrade", &Game::acceptTrade, &g_game); - g_lua.bindSingletonFunction("g_game", "rejectTrade", &Game::rejectTrade, &g_game); - g_lua.bindSingletonFunction("g_game", "openRuleViolation", &Game::openRuleViolation, &g_game); - g_lua.bindSingletonFunction("g_game", "closeRuleViolation", &Game::closeRuleViolation, &g_game); - g_lua.bindSingletonFunction("g_game", "cancelRuleViolation", &Game::cancelRuleViolation, &g_game); - g_lua.bindSingletonFunction("g_game", "reportBug", &Game::reportBug, &g_game); - g_lua.bindSingletonFunction("g_game", "reportRuleViolation", &Game::reportRuleViolation, &g_game); - g_lua.bindSingletonFunction("g_game", "debugReport", &Game::debugReport, &g_game); - g_lua.bindSingletonFunction("g_game", "editText", &Game::editText, &g_game); - g_lua.bindSingletonFunction("g_game", "editList", &Game::editList, &g_game); - g_lua.bindSingletonFunction("g_game", "requestQuestLog", &Game::requestQuestLog, &g_game); - g_lua.bindSingletonFunction("g_game", "requestQuestLine", &Game::requestQuestLine, &g_game); - g_lua.bindSingletonFunction("g_game", "equipItem", &Game::equipItem, &g_game); - g_lua.bindSingletonFunction("g_game", "equipItemId", &Game::equipItemId, &g_game); - g_lua.bindSingletonFunction("g_game", "mount", &Game::mount, &g_game); - g_lua.bindSingletonFunction("g_game", "setOutfitExtensions", &Game::setOutfitExtensions, &g_game); - g_lua.bindSingletonFunction("g_game", "requestItemInfo", &Game::requestItemInfo, &g_game); - g_lua.bindSingletonFunction("g_game", "ping", &Game::ping, &g_game); - g_lua.bindSingletonFunction("g_game", "setPingDelay", &Game::setPingDelay, &g_game); - g_lua.bindSingletonFunction("g_game", "changeMapAwareRange", &Game::changeMapAwareRange, &g_game); - g_lua.bindSingletonFunction("g_game", "canPerformGameAction", &Game::canPerformGameAction, &g_game); - g_lua.bindSingletonFunction("g_game", "canReportBugs", &Game::canReportBugs, &g_game); - g_lua.bindSingletonFunction("g_game", "checkBotProtection", &Game::checkBotProtection, &g_game); - g_lua.bindSingletonFunction("g_game", "isOnline", &Game::isOnline, &g_game); - g_lua.bindSingletonFunction("g_game", "isLogging", &Game::isLogging, &g_game); - g_lua.bindSingletonFunction("g_game", "isDead", &Game::isDead, &g_game); - g_lua.bindSingletonFunction("g_game", "isAttacking", &Game::isAttacking, &g_game); - g_lua.bindSingletonFunction("g_game", "isFollowing", &Game::isFollowing, &g_game); - g_lua.bindSingletonFunction("g_game", "isConnectionOk", &Game::isConnectionOk, &g_game); - g_lua.bindSingletonFunction("g_game", "getPing", &Game::getPing, &g_game); - g_lua.bindSingletonFunction("g_game", "getContainer", &Game::getContainer, &g_game); - g_lua.bindSingletonFunction("g_game", "getContainers", &Game::getContainers, &g_game); - g_lua.bindSingletonFunction("g_game", "getVips", &Game::getVips, &g_game); - g_lua.bindSingletonFunction("g_game", "getAttackingCreature", &Game::getAttackingCreature, &g_game); - g_lua.bindSingletonFunction("g_game", "getFollowingCreature", &Game::getFollowingCreature, &g_game); - g_lua.bindSingletonFunction("g_game", "getServerBeat", &Game::getServerBeat, &g_game); - g_lua.bindSingletonFunction("g_game", "getLocalPlayer", &Game::getLocalPlayer, &g_game); - g_lua.bindSingletonFunction("g_game", "getProtocolGame", &Game::getProtocolGame, &g_game); - g_lua.bindSingletonFunction("g_game", "getProtocolVersion", &Game::getProtocolVersion, &g_game); - g_lua.bindSingletonFunction("g_game", "setProtocolVersion", &Game::setProtocolVersion, &g_game); - g_lua.bindSingletonFunction("g_game", "getCustomProtocolVersion", &Game::getCustomProtocolVersion, &g_game); - g_lua.bindSingletonFunction("g_game", "setCustomProtocolVersion", &Game::setCustomProtocolVersion, &g_game); - g_lua.bindSingletonFunction("g_game", "getClientVersion", &Game::getClientVersion, &g_game); - g_lua.bindSingletonFunction("g_game", "setClientVersion", &Game::setClientVersion, &g_game); - g_lua.bindSingletonFunction("g_game", "setCustomOs", &Game::setCustomOs, &g_game); - g_lua.bindSingletonFunction("g_game", "getOs", &Game::getOs, &g_game); - g_lua.bindSingletonFunction("g_game", "getCharacterName", &Game::getCharacterName, &g_game); - g_lua.bindSingletonFunction("g_game", "getWorldName", &Game::getWorldName, &g_game); - g_lua.bindSingletonFunction("g_game", "getGMActions", &Game::getGMActions, &g_game); - g_lua.bindSingletonFunction("g_game", "getFeature", &Game::getFeature, &g_game); - g_lua.bindSingletonFunction("g_game", "setFeature", &Game::setFeature, &g_game); - g_lua.bindSingletonFunction("g_game", "enableFeature", &Game::enableFeature, &g_game); - g_lua.bindSingletonFunction("g_game", "disableFeature", &Game::disableFeature, &g_game); - g_lua.bindSingletonFunction("g_game", "resetFeatures", &Game::resetFeatures, &g_game); - g_lua.bindSingletonFunction("g_game", "isGM", &Game::isGM, &g_game); - g_lua.bindSingletonFunction("g_game", "answerModalDialog", &Game::answerModalDialog, &g_game); - g_lua.bindSingletonFunction("g_game", "browseField", &Game::browseField, &g_game); - g_lua.bindSingletonFunction("g_game", "seekInContainer", &Game::seekInContainer, &g_game); - g_lua.bindSingletonFunction("g_game", "getLastWalkDir", &Game::getLastWalkDir, &g_game); - g_lua.bindSingletonFunction("g_game", "buyStoreOffer", &Game::buyStoreOffer, &g_game); - g_lua.bindSingletonFunction("g_game", "requestTransactionHistory", &Game::requestTransactionHistory, &g_game); - g_lua.bindSingletonFunction("g_game", "requestStoreOffers", &Game::requestStoreOffers, &g_game); - g_lua.bindSingletonFunction("g_game", "openStore", &Game::openStore, &g_game); - g_lua.bindSingletonFunction("g_game", "transferCoins", &Game::transferCoins, &g_game); - g_lua.bindSingletonFunction("g_game", "openTransactionHistory", &Game::openTransactionHistory, &g_game); - g_lua.bindSingletonFunction("g_game", "preyAction", &Game::preyAction, &g_game); - g_lua.bindSingletonFunction("g_game", "preyRequest", &Game::preyRequest, &g_game); - g_lua.bindSingletonFunction("g_game", "applyImbuement", &Game::applyImbuement, &g_game); - g_lua.bindSingletonFunction("g_game", "clearImbuement", &Game::clearImbuement, &g_game); - g_lua.bindSingletonFunction("g_game", "closeImbuingWindow", &Game::closeImbuingWindow, &g_game); - g_lua.bindSingletonFunction("g_game", "setTibiaCoins", &Game::setTibiaCoins, &g_game); - g_lua.bindSingletonFunction("g_game", "getTibiaCoins", &Game::getTibiaCoins, &g_game); - g_lua.bindSingletonFunction("g_game", "getTransferableTibiaCoins", &Game::getTransferableTibiaCoins, &g_game); - - g_lua.bindSingletonFunction("g_game", "getMaxPreWalkingSteps", &Game::getMaxPreWalkingSteps, &g_game); - g_lua.bindSingletonFunction("g_game", "setMaxPreWalkingSteps", &Game::setMaxPreWalkingSteps, &g_game); - g_lua.bindSingletonFunction("g_game", "ignoreServerDirection", &Game::ignoreServerDirection, &g_game); - g_lua.bindSingletonFunction("g_game", "showRealDirection", &Game::showRealDirection, &g_game); - g_lua.bindSingletonFunction("g_game", "enableTileThingLuaCallback", &Game::enableTileThingLuaCallback, &g_game); - g_lua.bindSingletonFunction("g_game", "isTileThingLuaCallbackEnabled", &Game::isTileThingLuaCallbackEnabled, &g_game); - g_lua.bindSingletonFunction("g_game", "getRecivedPacketsCount", &Game::getRecivedPacketsCount, &g_game); - g_lua.bindSingletonFunction("g_game", "getRecivedPacketsSize", &Game::getRecivedPacketsSize, &g_game); - - g_lua.registerSingletonClass("g_shaders"); - g_lua.bindSingletonFunction("g_shaders", "createShader", &ShaderManager::createShader, &g_shaders); - g_lua.bindSingletonFunction("g_shaders", "createOutfitShader", &ShaderManager::createOutfitShader, &g_shaders); - g_lua.bindSingletonFunction("g_shaders", "addTexture", &ShaderManager::addTexture, &g_shaders); - - g_lua.bindGlobalFunction("getOutfitColor", Outfit::getColor); - g_lua.bindGlobalFunction("getAngleFromPos", Position::getAngleFromPositions); - g_lua.bindGlobalFunction("getDirectionFromPos", Position::getDirectionFromPositions); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return ProtocolGamePtr(new ProtocolGame); }); - g_lua.bindClassMemberFunction("login", &ProtocolGame::login); - g_lua.bindClassMemberFunction("sendExtendedOpcode", &ProtocolGame::sendExtendedOpcode); - g_lua.bindClassMemberFunction("addPosition", &ProtocolGame::addPosition); - g_lua.bindClassMemberFunction("setMapDescription", &ProtocolGame::setMapDescription); - g_lua.bindClassMemberFunction("setFloorDescription", &ProtocolGame::setFloorDescription); - g_lua.bindClassMemberFunction("setTileDescription", &ProtocolGame::setTileDescription); - g_lua.bindClassMemberFunction("getOutfit", &ProtocolGame::getOutfit); - g_lua.bindClassMemberFunction("getThing", &ProtocolGame::getThing); - g_lua.bindClassMemberFunction("getCreature", &ProtocolGame::getCreature); - g_lua.bindClassMemberFunction("getItem", &ProtocolGame::getItem); - g_lua.bindClassMemberFunction("getPosition", &ProtocolGame::getPosition); - - g_lua.registerClass(); - g_lua.bindClassMemberFunction("getItem", &Container::getItem); - g_lua.bindClassMemberFunction("getItems", &Container::getItems); - g_lua.bindClassMemberFunction("getItemsCount", &Container::getItemsCount); - g_lua.bindClassMemberFunction("getSlotPosition", &Container::getSlotPosition); - g_lua.bindClassMemberFunction("getName", &Container::getName); - g_lua.bindClassMemberFunction("getId", &Container::getId); - g_lua.bindClassMemberFunction("getCapacity", &Container::getCapacity); - g_lua.bindClassMemberFunction("getContainerItem", &Container::getContainerItem); - g_lua.bindClassMemberFunction("hasParent", &Container::hasParent); - g_lua.bindClassMemberFunction("isClosed", &Container::isClosed); - g_lua.bindClassMemberFunction("isUnlocked", &Container::isUnlocked); - g_lua.bindClassMemberFunction("hasPages", &Container::hasPages); - g_lua.bindClassMemberFunction("getSize", &Container::getSize); - g_lua.bindClassMemberFunction("getFirstIndex", &Container::getFirstIndex); - - g_lua.registerClass(); - g_lua.bindClassMemberFunction("setId", &Thing::setId); - g_lua.bindClassMemberFunction("setPosition", &Thing::setPosition); - g_lua.bindClassMemberFunction("getId", &Thing::getId); - g_lua.bindClassMemberFunction("getPosition", &Thing::getPosition); - g_lua.bindClassMemberFunction("getStackPriority", &Thing::getStackPriority); - g_lua.bindClassMemberFunction("getStackPos", &Thing::getStackPos); - g_lua.bindClassMemberFunction("getAnimationPhases", &Thing::getAnimationPhases); - g_lua.bindClassMemberFunction("getTile", &Thing::getTile); - g_lua.bindClassMemberFunction("setMarked", &Thing::setMarked); - g_lua.bindClassMemberFunction("isItem", &Thing::isItem); - g_lua.bindClassMemberFunction("isMonster", &Thing::isMonster); - g_lua.bindClassMemberFunction("isNpc", &Thing::isNpc); - g_lua.bindClassMemberFunction("isCreature", &Thing::isCreature); - g_lua.bindClassMemberFunction("isEffect", &Thing::isEffect); - g_lua.bindClassMemberFunction("isMissile", &Thing::isMissile); - g_lua.bindClassMemberFunction("isPlayer", &Thing::isPlayer); - g_lua.bindClassMemberFunction("isLocalPlayer", &Thing::isLocalPlayer); - g_lua.bindClassMemberFunction("isAnimatedText", &Thing::isAnimatedText); - g_lua.bindClassMemberFunction("isStaticText", &Thing::isStaticText); - g_lua.bindClassMemberFunction("isGround", &Thing::isGround); - g_lua.bindClassMemberFunction("isGroundBorder", &Thing::isGroundBorder); - g_lua.bindClassMemberFunction("isOnBottom", &Thing::isOnBottom); - g_lua.bindClassMemberFunction("isOnTop", &Thing::isOnTop); - g_lua.bindClassMemberFunction("isContainer", &Thing::isContainer); - g_lua.bindClassMemberFunction("isForceUse", &Thing::isForceUse); - g_lua.bindClassMemberFunction("isMultiUse", &Thing::isMultiUse); - g_lua.bindClassMemberFunction("isRotateable", &Thing::isRotateable); - g_lua.bindClassMemberFunction("isNotMoveable", &Thing::isNotMoveable); - g_lua.bindClassMemberFunction("isPickupable", &Thing::isPickupable); - g_lua.bindClassMemberFunction("isIgnoreLook", &Thing::isIgnoreLook); - g_lua.bindClassMemberFunction("isStackable", &Thing::isStackable); - g_lua.bindClassMemberFunction("isHookSouth", &Thing::isHookSouth); - g_lua.bindClassMemberFunction("isTranslucent", &Thing::isTranslucent); - g_lua.bindClassMemberFunction("isFullGround", &Thing::isFullGround); - g_lua.bindClassMemberFunction("isMarketable", &Thing::isMarketable); - g_lua.bindClassMemberFunction("getMarketData", &Thing::getMarketData); - g_lua.bindClassMemberFunction("isUsable", &Thing::isUsable); - g_lua.bindClassMemberFunction("isWrapable", &Thing::isWrapable); - g_lua.bindClassMemberFunction("isUnwrapable", &Thing::isUnwrapable); - g_lua.bindClassMemberFunction("isTopEffect", &Thing::isTopEffect); - g_lua.bindClassMemberFunction("isLyingCorpse", &Thing::isLyingCorpse); - g_lua.bindClassMemberFunction("getParentContainer", &Thing::getParentContainer); - g_lua.bindClassMemberFunction("hide", &Thing::hide); - g_lua.bindClassMemberFunction("show", &Thing::show); - g_lua.bindClassMemberFunction("setHidden", &Thing::setHidden); - g_lua.bindClassMemberFunction("isHidden", &Thing::isHidden); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return HousePtr(new House); }); - g_lua.bindClassMemberFunction("setId", &House::setId); - g_lua.bindClassMemberFunction("getId", &House::getId); - g_lua.bindClassMemberFunction("setName", &House::setName); - g_lua.bindClassMemberFunction("getName", &House::getName); - g_lua.bindClassMemberFunction("setTownId", &House::setTownId); - g_lua.bindClassMemberFunction("getTownId", &House::getTownId); - g_lua.bindClassMemberFunction("setTile", &House::setTile); - g_lua.bindClassMemberFunction("getTile", &House::getTile); - g_lua.bindClassMemberFunction("setEntry", &House::setEntry); - g_lua.bindClassMemberFunction("getEntry", &House::getEntry); - g_lua.bindClassMemberFunction("addDoor", &House::addDoor); - g_lua.bindClassMemberFunction("removeDoor", &House::removeDoor); - g_lua.bindClassMemberFunction("removeDoorById", &House::removeDoorById); - g_lua.bindClassMemberFunction("setSize", &House::setSize); - g_lua.bindClassMemberFunction("getSize", &House::getSize); - g_lua.bindClassMemberFunction("setRent", &House::setRent); - g_lua.bindClassMemberFunction("getRent", &House::getRent); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return SpawnPtr(new Spawn); }); - g_lua.bindClassMemberFunction("setRadius", &Spawn::setRadius); - g_lua.bindClassMemberFunction("getRadius", &Spawn::getRadius); - g_lua.bindClassMemberFunction("setCenterPos", &Spawn::setCenterPos); - g_lua.bindClassMemberFunction("getCenterPos", &Spawn::getCenterPos); - g_lua.bindClassMemberFunction("addCreature", &Spawn::addCreature); - g_lua.bindClassMemberFunction("removeCreature", &Spawn::removeCreature); - g_lua.bindClassMemberFunction("getCreatures", &Spawn::getCreatures); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return TownPtr(new Town); }); - g_lua.bindClassMemberFunction("setId", &Town::setId); - g_lua.bindClassMemberFunction("setName", &Town::setName); - g_lua.bindClassMemberFunction("setPos", &Town::setPos); - g_lua.bindClassMemberFunction("setTemplePos", &Town::setPos); // alternative method - g_lua.bindClassMemberFunction("getId", &Town::getId); - g_lua.bindClassMemberFunction("getName", &Town::getName); - g_lua.bindClassMemberFunction("getPos", &Town::getPos); - g_lua.bindClassMemberFunction("getTemplePos", &Town::getPos); // alternative method - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return CreatureTypePtr(new CreatureType); }); - g_lua.bindClassMemberFunction("setName", &CreatureType::setName); - g_lua.bindClassMemberFunction("setOutfit", &CreatureType::setOutfit); - g_lua.bindClassMemberFunction("setSpawnTime", &CreatureType::setSpawnTime); - g_lua.bindClassMemberFunction("getName", &CreatureType::getName); - g_lua.bindClassMemberFunction("getOutfit", &CreatureType::getOutfit); - g_lua.bindClassMemberFunction("getSpawnTime", &CreatureType::getSpawnTime); - g_lua.bindClassMemberFunction("cast", &CreatureType::cast); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return CreaturePtr(new Creature); }); - g_lua.bindClassMemberFunction("getId", &Creature::getId); - g_lua.bindClassMemberFunction("getName", &Creature::getName); - g_lua.bindClassMemberFunction("setName", &Creature::setName); - g_lua.bindClassMemberFunction("setManaPercent", &LocalPlayer::setManaPercent); - g_lua.bindClassMemberFunction("getManaPercent", &LocalPlayer::getManaPercent); - g_lua.bindClassMemberFunction("setHealthPercent", &Creature::setHealthPercent); - g_lua.bindClassMemberFunction("getHealthPercent", &Creature::getHealthPercent); - g_lua.bindClassMemberFunction("getSpeed", &Creature::getSpeed); - g_lua.bindClassMemberFunction("setSpeed", &Creature::setSpeed); - g_lua.bindClassMemberFunction("getBaseSpeed", &Creature::getBaseSpeed); - g_lua.bindClassMemberFunction("setBaseSpeed", &Creature::setBaseSpeed); - g_lua.bindClassMemberFunction("getSkull", &Creature::getSkull); - g_lua.bindClassMemberFunction("getShield", &Creature::getShield); - g_lua.bindClassMemberFunction("getEmblem", &Creature::getEmblem); - g_lua.bindClassMemberFunction("setSkull", &Creature::setSkull); - g_lua.bindClassMemberFunction("setShield", &Creature::setShield); - g_lua.bindClassMemberFunction("setEmblem", &Creature::setEmblem); - g_lua.bindClassMemberFunction("getType", &Creature::getType); - g_lua.bindClassMemberFunction("getIcon", &Creature::getIcon); - g_lua.bindClassMemberFunction("setOutfit", &Creature::setOutfit); - g_lua.bindClassMemberFunction("getOutfit", &Creature::getOutfit); - g_lua.bindClassMemberFunction("setOutfitColor", &Creature::setOutfitColor); - g_lua.bindClassMemberFunction("getDirection", &Creature::getDirection); - g_lua.bindClassMemberFunction("getWalkDirection", &Creature::getWalkDirection); - g_lua.bindClassMemberFunction("getStepDuration", &Creature::getStepDuration); - g_lua.bindClassMemberFunction("getStepProgress", &Creature::getStepProgress); - g_lua.bindClassMemberFunction("getWalkTicksElapsed", &Creature::getWalkTicksElapsed); - g_lua.bindClassMemberFunction("getStepTicksLeft", &Creature::getStepTicksLeft); - g_lua.bindClassMemberFunction("setDirection", &Creature::setDirection); - g_lua.bindClassMemberFunction("setSkullTexture", &Creature::setSkullTexture); - g_lua.bindClassMemberFunction("setShieldTexture", &Creature::setShieldTexture); - g_lua.bindClassMemberFunction("setEmblemTexture", &Creature::setEmblemTexture); - g_lua.bindClassMemberFunction("setTypeTexture", &Creature::setTypeTexture); - g_lua.bindClassMemberFunction("setIconTexture", &Creature::setIconTexture); - g_lua.bindClassMemberFunction("showStaticSquare", &Creature::showStaticSquare); - g_lua.bindClassMemberFunction("hideStaticSquare", &Creature::hideStaticSquare); - g_lua.bindClassMemberFunction("isWalking", &Creature::isWalking); - g_lua.bindClassMemberFunction("isInvisible", &Creature::isInvisible); - g_lua.bindClassMemberFunction("isDead", &Creature::isDead); - g_lua.bindClassMemberFunction("isRemoved", &Creature::isRemoved); - g_lua.bindClassMemberFunction("canBeSeen", &Creature::canBeSeen); - g_lua.bindClassMemberFunction("canShoot", &Creature::canShoot); - g_lua.bindClassMemberFunction("jump", &Creature::jump); - g_lua.bindClassMemberFunction("getPrewalkingPosition", &Creature::getPrewalkingPosition); - g_lua.bindClassMemberFunction("setInformationColor", &Creature::setInformationColor); - g_lua.bindClassMemberFunction("resetInformationColor", &Creature::resetInformationColor); - g_lua.bindClassMemberFunction("setInformationOffset", &Creature::setInformationOffset); - g_lua.bindClassMemberFunction("getInformationOffset", &Creature::getInformationOffset); - g_lua.bindClassMemberFunction("setText", &Creature::setText); - g_lua.bindClassMemberFunction("getText", &Creature::getText); - g_lua.bindClassMemberFunction("clearText", &Creature::clearText); - - // widgets - g_lua.bindClassMemberFunction("addTopWidget", &Creature::addTopWidget); - g_lua.bindClassMemberFunction("addBottomWidget", &Creature::addBottomWidget); - g_lua.bindClassMemberFunction("addDirectionalWidget", &Creature::addDirectionalWidget); - g_lua.bindClassMemberFunction("removeTopWidget", &Creature::removeTopWidget); - g_lua.bindClassMemberFunction("removeBottomWidget", &Creature::removeBottomWidget); - g_lua.bindClassMemberFunction("removeDirectionalWidget", &Creature::removeDirectionalWidget); - g_lua.bindClassMemberFunction("getTopWidgets", &Creature::getTopWidgets); - g_lua.bindClassMemberFunction("getBottomWidgets", &Creature::getBottomWidgets); - g_lua.bindClassMemberFunction("getDirectionalWdigets", &Creature::getDirectionalWdigets); - g_lua.bindClassMemberFunction("clearWidgets", &Creature::clearWidgets); - g_lua.bindClassMemberFunction("clearTopWidgets", &Creature::clearTopWidgets); - g_lua.bindClassMemberFunction("clearBottomWidgets", &Creature::clearBottomWidgets); - g_lua.bindClassMemberFunction("clearDirectionalWidgets", &Creature::clearDirectionalWidgets); - - // progress bar - g_lua.bindClassMemberFunction("setProgressBar", &Creature::setProgressBar); - g_lua.bindClassMemberFunction("getProgressBarPercent", &Creature::getProgressBarPercent); - - - g_lua.registerClass(); - g_lua.bindClassMemberFunction("getServerId", &ItemType::getServerId); - g_lua.bindClassMemberFunction("getClientId", &ItemType::getClientId); - g_lua.bindClassMemberFunction("isWritable", &ItemType::isWritable); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return ThingTypePtr(new ThingType); }); - g_lua.bindClassMemberFunction("getId", &ThingType::getId); - g_lua.bindClassMemberFunction("getClothSlot", &ThingType::getClothSlot); - g_lua.bindClassMemberFunction("getCategory", &ThingType::getCategory); - g_lua.bindClassMemberFunction("getSize", &ThingType::getSize); - g_lua.bindClassMemberFunction("getWidth", &ThingType::getWidth); - g_lua.bindClassMemberFunction("getHeight", &ThingType::getHeight); - g_lua.bindClassMemberFunction("getDisplacement", &ThingType::getDisplacement); - g_lua.bindClassMemberFunction("getDisplacementX", &ThingType::getDisplacementX); - g_lua.bindClassMemberFunction("getDisplacementY", &ThingType::getDisplacementY); - g_lua.bindClassMemberFunction("getExactSize", &ThingType::getExactSize); - g_lua.bindClassMemberFunction("getRealSize", &ThingType::getRealSize); - g_lua.bindClassMemberFunction("getLayers", &ThingType::getLayers); - g_lua.bindClassMemberFunction("getNumPatternX", &ThingType::getNumPatternX); - g_lua.bindClassMemberFunction("getNumPatternY", &ThingType::getNumPatternY); - g_lua.bindClassMemberFunction("getNumPatternZ", &ThingType::getNumPatternZ); - g_lua.bindClassMemberFunction("getAnimationPhases", &ThingType::getAnimationPhases); - g_lua.bindClassMemberFunction("getGroundSpeed", &ThingType::getGroundSpeed); - g_lua.bindClassMemberFunction("getMaxTextLength", &ThingType::getMaxTextLength); - g_lua.bindClassMemberFunction("getLight", &ThingType::getLight); - g_lua.bindClassMemberFunction("getMinimapColor", &ThingType::getMinimapColor); - g_lua.bindClassMemberFunction("getLensHelp", &ThingType::getLensHelp); - g_lua.bindClassMemberFunction("getClothSlot", &ThingType::getClothSlot); - g_lua.bindClassMemberFunction("getElevation", &ThingType::getElevation); - g_lua.bindClassMemberFunction("isGround", &ThingType::isGround); - g_lua.bindClassMemberFunction("isGroundBorder", &ThingType::isGroundBorder); - g_lua.bindClassMemberFunction("isOnBottom", &ThingType::isOnBottom); - g_lua.bindClassMemberFunction("isOnTop", &ThingType::isOnTop); - g_lua.bindClassMemberFunction("isContainer", &ThingType::isContainer); - g_lua.bindClassMemberFunction("isStackable", &ThingType::isStackable); - g_lua.bindClassMemberFunction("isForceUse", &ThingType::isForceUse); - g_lua.bindClassMemberFunction("isMultiUse", &ThingType::isMultiUse); - g_lua.bindClassMemberFunction("isWritable", &ThingType::isWritable); - g_lua.bindClassMemberFunction("isChargeable", &ThingType::isChargeable); - g_lua.bindClassMemberFunction("isWritableOnce", &ThingType::isWritableOnce); - g_lua.bindClassMemberFunction("isFluidContainer", &ThingType::isFluidContainer); - g_lua.bindClassMemberFunction("isSplash", &ThingType::isSplash); - g_lua.bindClassMemberFunction("isNotWalkable", &ThingType::isNotWalkable); - g_lua.bindClassMemberFunction("isNotMoveable", &ThingType::isNotMoveable); - g_lua.bindClassMemberFunction("blockProjectile", &ThingType::blockProjectile); - g_lua.bindClassMemberFunction("isNotPathable", &ThingType::isNotPathable); - g_lua.bindClassMemberFunction("setPathable", &ThingType::setPathable); - g_lua.bindClassMemberFunction("isPickupable", &ThingType::isPickupable); - g_lua.bindClassMemberFunction("isHangable", &ThingType::isHangable); - g_lua.bindClassMemberFunction("isHookSouth", &ThingType::isHookSouth); - g_lua.bindClassMemberFunction("isHookEast", &ThingType::isHookEast); - g_lua.bindClassMemberFunction("isRotateable", &ThingType::isRotateable); - g_lua.bindClassMemberFunction("hasLight", &ThingType::hasLight); - g_lua.bindClassMemberFunction("isDontHide", &ThingType::isDontHide); - g_lua.bindClassMemberFunction("isTranslucent", &ThingType::isTranslucent); - g_lua.bindClassMemberFunction("hasDisplacement", &ThingType::hasDisplacement); - g_lua.bindClassMemberFunction("hasElevation", &ThingType::hasElevation); - g_lua.bindClassMemberFunction("isLyingCorpse", &ThingType::isLyingCorpse); - g_lua.bindClassMemberFunction("isAnimateAlways", &ThingType::isAnimateAlways); - g_lua.bindClassMemberFunction("hasMiniMapColor", &ThingType::hasMiniMapColor); - g_lua.bindClassMemberFunction("hasLensHelp", &ThingType::hasLensHelp); - g_lua.bindClassMemberFunction("isFullGround", &ThingType::isFullGround); - g_lua.bindClassMemberFunction("isIgnoreLook", &ThingType::isIgnoreLook); - g_lua.bindClassMemberFunction("isCloth", &ThingType::isCloth); - g_lua.bindClassMemberFunction("isMarketable", &ThingType::isMarketable); - g_lua.bindClassMemberFunction("getMarketData", &ThingType::getMarketData); - g_lua.bindClassMemberFunction("isUsable", &ThingType::isUsable); - g_lua.bindClassMemberFunction("isWrapable", &ThingType::isWrapable); - g_lua.bindClassMemberFunction("isUnwrapable", &ThingType::isUnwrapable); - g_lua.bindClassMemberFunction("isTopEffect", &ThingType::isTopEffect); - g_lua.bindClassMemberFunction("getSprites", &ThingType::getSprites); - g_lua.bindClassMemberFunction("hasAttribute", &ThingType::hasAttr); - g_lua.bindClassMemberFunction("exportImage", &ThingType::exportImage); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &Item::create); - g_lua.bindClassStaticFunction("createOtb", &Item::createFromOtb); - g_lua.bindClassMemberFunction("clone", &Item::clone); - g_lua.bindClassMemberFunction("getContainerItems", &Item::getContainerItems); - g_lua.bindClassMemberFunction("getContainerItem", &Item::getContainerItem); - g_lua.bindClassMemberFunction("addContainerItem", &Item::addContainerItem); - g_lua.bindClassMemberFunction("addContainerItemIndexed", &Item::addContainerItemIndexed); - g_lua.bindClassMemberFunction("removeContainerItem", &Item::removeContainerItem); - g_lua.bindClassMemberFunction("clearContainerItems", &Item::clearContainerItems); - g_lua.bindClassMemberFunction("getContainerItem", &Item::getContainerItem); - g_lua.bindClassMemberFunction("setCount", &Item::setCount); - g_lua.bindClassMemberFunction("getCount", &Item::getCount); - g_lua.bindClassMemberFunction("getSubType", &Item::getSubType); - g_lua.bindClassMemberFunction("getCountOrSubType", &Item::getCountOrSubType); - g_lua.bindClassMemberFunction("getId", &Item::getId); - g_lua.bindClassMemberFunction("getServerId", &Item::getServerId); - g_lua.bindClassMemberFunction("getName", &Item::getName); - g_lua.bindClassMemberFunction("getDescription", &Item::getDescription); - g_lua.bindClassMemberFunction("getText", &Item::getText); - g_lua.bindClassMemberFunction("setDescription", &Item::setDescription); - g_lua.bindClassMemberFunction("setText", &Item::setText); - g_lua.bindClassMemberFunction("getUniqueId", &Item::getUniqueId); - g_lua.bindClassMemberFunction("getActionId", &Item::getActionId); - g_lua.bindClassMemberFunction("setUniqueId", &Item::setUniqueId); - g_lua.bindClassMemberFunction("setActionId", &Item::setActionId); - g_lua.bindClassMemberFunction("getTeleportDestination", &Item::getTeleportDestination); - g_lua.bindClassMemberFunction("setTeleportDestination", &Item::setTeleportDestination); - g_lua.bindClassMemberFunction("isStackable", &Item::isStackable); - g_lua.bindClassMemberFunction("isMarketable", &Item::isMarketable); - g_lua.bindClassMemberFunction("isFluidContainer", &Item::isFluidContainer); - g_lua.bindClassMemberFunction("getMarketData", &Item::getMarketData); - g_lua.bindClassMemberFunction("getClothSlot", &Item::getClothSlot); - g_lua.bindClassMemberFunction("getTooltip", &Item::getTooltip); - g_lua.bindClassMemberFunction("setTooltip", &Item::setTooltip); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return EffectPtr(new Effect); }); - g_lua.bindClassMemberFunction("setId", &Effect::setId); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return MissilePtr(new Missile); }); - g_lua.bindClassMemberFunction("setId", &Missile::setId); - g_lua.bindClassMemberFunction("getId", &Missile::getId); - g_lua.bindClassMemberFunction("getSource", &Missile::getSource); - g_lua.bindClassMemberFunction("getDestination", &Missile::getDestination); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return StaticTextPtr(new StaticText); }); - g_lua.bindClassMemberFunction("addMessage", &StaticText::addMessage); - g_lua.bindClassMemberFunction("addColoredMessage", &StaticText::addColoredMessage); - g_lua.bindClassMemberFunction("setText", &StaticText::setText); - g_lua.bindClassMemberFunction("setFont", &StaticText::setFont); - g_lua.bindClassMemberFunction("setColor", &StaticText::setColor); - g_lua.bindClassMemberFunction("getColor", &StaticText::getColor); - g_lua.bindClassMemberFunction("getText", &StaticText::getText); - - g_lua.registerClass(); - g_lua.bindClassMemberFunction("getText", &AnimatedText::getText); - g_lua.bindClassMemberFunction("getOffset", &AnimatedText::getOffset); - g_lua.bindClassMemberFunction("getColor", &AnimatedText::getColor); - - g_lua.registerClass(); - g_lua.registerClass(); - g_lua.registerClass(); - - g_lua.registerClass(); - g_lua.bindClassMemberFunction("unlockWalk", &LocalPlayer::unlockWalk); - g_lua.bindClassMemberFunction("lockWalk", &LocalPlayer::lockWalk); - g_lua.bindClassMemberFunction("isWalkLocked", &LocalPlayer::isWalkLocked); - g_lua.bindClassMemberFunction("canWalk", &LocalPlayer::canWalk); - g_lua.bindClassMemberFunction("setStates", &LocalPlayer::setStates); - g_lua.bindClassMemberFunction("setSkill", &LocalPlayer::setSkill); - g_lua.bindClassMemberFunction("setHealth", &LocalPlayer::setHealth); - g_lua.bindClassMemberFunction("setTotalCapacity", &LocalPlayer::setTotalCapacity); - g_lua.bindClassMemberFunction("setFreeCapacity", &LocalPlayer::setFreeCapacity); - g_lua.bindClassMemberFunction("setExperience", &LocalPlayer::setExperience); - g_lua.bindClassMemberFunction("setLevel", &LocalPlayer::setLevel); - g_lua.bindClassMemberFunction("setMana", &LocalPlayer::setMana); - g_lua.bindClassMemberFunction("setMagicLevel", &LocalPlayer::setMagicLevel); - g_lua.bindClassMemberFunction("setSoul", &LocalPlayer::setSoul); - g_lua.bindClassMemberFunction("setStamina", &LocalPlayer::setStamina); - g_lua.bindClassMemberFunction("setKnown", &LocalPlayer::setKnown); - g_lua.bindClassMemberFunction("setInventoryItem", &LocalPlayer::setInventoryItem); - g_lua.bindClassMemberFunction("getStates", &LocalPlayer::getStates); - g_lua.bindClassMemberFunction("getSkillLevel", &LocalPlayer::getSkillLevel); - g_lua.bindClassMemberFunction("getSkillBaseLevel", &LocalPlayer::getSkillBaseLevel); - g_lua.bindClassMemberFunction("getSkillLevelPercent", &LocalPlayer::getSkillLevelPercent); - g_lua.bindClassMemberFunction("getHealth", &LocalPlayer::getHealth); - g_lua.bindClassMemberFunction("getMaxHealth", &LocalPlayer::getMaxHealth); - g_lua.bindClassMemberFunction("getFreeCapacity", &LocalPlayer::getFreeCapacity); - g_lua.bindClassMemberFunction("getExperience", &LocalPlayer::getExperience); - g_lua.bindClassMemberFunction("getLevel", &LocalPlayer::getLevel); - g_lua.bindClassMemberFunction("getLevelPercent", &LocalPlayer::getLevelPercent); - g_lua.bindClassMemberFunction("getMana", &LocalPlayer::getMana); - g_lua.bindClassMemberFunction("getMaxMana", &LocalPlayer::getMaxMana); - g_lua.bindClassMemberFunction("getMagicLevel", &LocalPlayer::getMagicLevel); - g_lua.bindClassMemberFunction("getMagicLevelPercent", &LocalPlayer::getMagicLevelPercent); - g_lua.bindClassMemberFunction("getSoul", &LocalPlayer::getSoul); - g_lua.bindClassMemberFunction("getStamina", &LocalPlayer::getStamina); - g_lua.bindClassMemberFunction("getOfflineTrainingTime", &LocalPlayer::getOfflineTrainingTime); - g_lua.bindClassMemberFunction("getRegenerationTime", &LocalPlayer::getRegenerationTime); - g_lua.bindClassMemberFunction("getBaseMagicLevel", &LocalPlayer::getBaseMagicLevel); - g_lua.bindClassMemberFunction("getTotalCapacity", &LocalPlayer::getTotalCapacity); - g_lua.bindClassMemberFunction("getInventoryItem", &LocalPlayer::getInventoryItem); - g_lua.bindClassMemberFunction("getVocation", &LocalPlayer::getVocation); - g_lua.bindClassMemberFunction("getBlessings", &LocalPlayer::getBlessings); - g_lua.bindClassMemberFunction("isPremium", &LocalPlayer::isPremium); - g_lua.bindClassMemberFunction("isKnown", &LocalPlayer::isKnown); - g_lua.bindClassMemberFunction("isPreWalking", &LocalPlayer::isPreWalking); - g_lua.bindClassMemberFunction("hasSight", &LocalPlayer::hasSight); - g_lua.bindClassMemberFunction("isAutoWalking", &LocalPlayer::isAutoWalking); - g_lua.bindClassMemberFunction("isServerWalking", &LocalPlayer::isServerWalking); - g_lua.bindClassMemberFunction("stopAutoWalk", &LocalPlayer::stopAutoWalk); - g_lua.bindClassMemberFunction("autoWalk", &LocalPlayer::autoWalk); - g_lua.bindClassMemberFunction("preWalk", &LocalPlayer::preWalk); - g_lua.bindClassMemberFunction("dumpWalkMatrix", &LocalPlayer::dumpWalkMatrix); - g_lua.bindClassMemberFunction("startServerWalking", &LocalPlayer::startServerWalking); - g_lua.bindClassMemberFunction("finishServerWalking", &LocalPlayer::finishServerWalking); - - g_lua.registerClass(); - g_lua.bindClassMemberFunction("clean", &Tile::clean); - g_lua.bindClassMemberFunction("addThing", &Tile::addThing); - g_lua.bindClassMemberFunction("getThing", &Tile::getThing); - g_lua.bindClassMemberFunction("getThings", &Tile::getThings); - g_lua.bindClassMemberFunction("getEffect", &Tile::getEffect); - g_lua.bindClassMemberFunction("getEffects", &Tile::getEffects); - g_lua.bindClassMemberFunction("getItems", &Tile::getItems); - g_lua.bindClassMemberFunction("getThingStackPos", &Tile::getThingStackPos); - g_lua.bindClassMemberFunction("getThingCount", &Tile::getThingCount); - g_lua.bindClassMemberFunction("getTopThing", &Tile::getTopThing); - g_lua.bindClassMemberFunction("removeThing", &Tile::removeThing); - g_lua.bindClassMemberFunction("getTopLookThing", &Tile::getTopLookThing); - g_lua.bindClassMemberFunction("getTopLookThingEx", &Tile::getTopLookThingEx); - g_lua.bindClassMemberFunction("getTopUseThing", &Tile::getTopUseThing); - g_lua.bindClassMemberFunction("getTopCreature", &Tile::getTopCreature); - g_lua.bindClassMemberFunction("getTopCreatureEx", &Tile::getTopCreatureEx); - g_lua.bindClassMemberFunction("getTopMoveThing", &Tile::getTopMoveThing); - g_lua.bindClassMemberFunction("getTopMultiUseThing", &Tile::getTopMultiUseThing); - g_lua.bindClassMemberFunction("getTopMultiUseThingEx", &Tile::getTopMultiUseThingEx); - g_lua.bindClassMemberFunction("getPosition", &Tile::getPosition); - g_lua.bindClassMemberFunction("getDrawElevation", &Tile::getDrawElevation); - g_lua.bindClassMemberFunction("getCreatures", &Tile::getCreatures); - g_lua.bindClassMemberFunction("getGround", &Tile::getGround); - g_lua.bindClassMemberFunction("isWalkable", &Tile::isWalkable); - g_lua.bindClassMemberFunction("isHouseTile", &Tile::isHouseTile); - g_lua.bindClassMemberFunction("isFullGround", &Tile::isFullGround); - g_lua.bindClassMemberFunction("isFullyOpaque", &Tile::isFullyOpaque); - g_lua.bindClassMemberFunction("isLookPossible", &Tile::isLookPossible); - g_lua.bindClassMemberFunction("isBlockingProjectile", &Tile::isBlockingProjectile); - g_lua.bindClassMemberFunction("hasCreature", &Tile::hasCreature); - g_lua.bindClassMemberFunction("hasBlockingCreature", &Tile::hasBlockingCreature); - g_lua.bindClassMemberFunction("isEmpty", &Tile::isEmpty); - g_lua.bindClassMemberFunction("isClickable", &Tile::isClickable); - g_lua.bindClassMemberFunction("isPathable", &Tile::isPathable); - g_lua.bindClassMemberFunction("overwriteMinimapColor", &Tile::overwriteMinimapColor); - g_lua.bindClassMemberFunction("select", &Tile::select); - g_lua.bindClassMemberFunction("unselect", &Tile::unselect); - g_lua.bindClassMemberFunction("isSelected", &Tile::isSelected); - g_lua.bindClassMemberFunction("remFlag", &Tile::remFlag); - g_lua.bindClassMemberFunction("setFlag", &Tile::setFlag); - g_lua.bindClassMemberFunction("setFlags", &Tile::setFlags); - g_lua.bindClassMemberFunction("getFlags", &Tile::getFlags); - g_lua.bindClassMemberFunction("hasFlag", &Tile::hasFlag); - g_lua.bindClassMemberFunction("getElevation", &Tile::getElevation); - g_lua.bindClassMemberFunction("hasElevation", &Tile::hasElevation); - g_lua.bindClassMemberFunction("isBlocking", &Tile::isBlocking); - g_lua.bindClassMemberFunction("canShoot", &Tile::canShoot); - // for bot - g_lua.bindClassMemberFunction("setText", &Tile::setText); - g_lua.bindClassMemberFunction("getText", &Tile::getText); - g_lua.bindClassMemberFunction("setTimer", &Tile::setTimer); - g_lua.bindClassMemberFunction("getTimer", &Tile::getTimer); - g_lua.bindClassMemberFunction("setFill", &Tile::setFill); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIItemPtr(new UIItem); }); - g_lua.bindClassMemberFunction("setItemId", &UIItem::setItemId); - g_lua.bindClassMemberFunction("setItemCount", &UIItem::setItemCount); - g_lua.bindClassMemberFunction("setItemSubType", &UIItem::setItemSubType); - g_lua.bindClassMemberFunction("setItemVisible", &UIItem::setItemVisible); - g_lua.bindClassMemberFunction("setItem", &UIItem::setItem); - g_lua.bindClassMemberFunction("setVirtual", &UIItem::setVirtual); - g_lua.bindClassMemberFunction("setShowCount", &UIItem::setShowCount); - g_lua.bindClassMemberFunction("clearItem", &UIItem::clearItem); - g_lua.bindClassMemberFunction("getItemId", &UIItem::getItemId); - g_lua.bindClassMemberFunction("getItemCount", &UIItem::getItemCount); - g_lua.bindClassMemberFunction("getItemSubType", &UIItem::getItemSubType); - g_lua.bindClassMemberFunction("getItemCountOrSubType", &UIItem::getItemCountOrSubType); - g_lua.bindClassMemberFunction("getItem", &UIItem::getItem); - g_lua.bindClassMemberFunction("isVirtual", &UIItem::isVirtual); - g_lua.bindClassMemberFunction("isItemVisible", &UIItem::isItemVisible); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UISpritePtr(new UISprite); }); - g_lua.bindClassMemberFunction("setSpriteId", &UISprite::setSpriteId); - g_lua.bindClassMemberFunction("clearSprite", &UISprite::clearSprite); - g_lua.bindClassMemberFunction("getSpriteId", &UISprite::getSpriteId); - g_lua.bindClassMemberFunction("setSpriteColor", &UISprite::setSpriteColor); - g_lua.bindClassMemberFunction("hasSprite", &UISprite::hasSprite); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UICreaturePtr(new UICreature); } ); - g_lua.bindClassMemberFunction("setCreature", &UICreature::setCreature); - g_lua.bindClassMemberFunction("setOutfit", &UICreature::setOutfit); - g_lua.bindClassMemberFunction("setFixedCreatureSize", &UICreature::setFixedCreatureSize); - g_lua.bindClassMemberFunction("getCreature", &UICreature::getCreature); - g_lua.bindClassMemberFunction("getOutfit", &UICreature::getOutfit); - g_lua.bindClassMemberFunction("isFixedCreatureSize", &UICreature::isFixedCreatureSize); - g_lua.bindClassMemberFunction("setAutoRotating", &UICreature::setAutoRotating); - g_lua.bindClassMemberFunction("setDirection", &UICreature::setDirection); - g_lua.bindClassMemberFunction("setScale", &UICreature::setScale); - g_lua.bindClassMemberFunction("getScale", &UICreature::getScale); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIMapPtr(new UIMap); }); - g_lua.bindClassMemberFunction("drawSelf", &UIMap::drawSelf); - g_lua.bindClassMemberFunction("movePixels", &UIMap::movePixels); - g_lua.bindClassMemberFunction("setZoom", &UIMap::setZoom); - g_lua.bindClassMemberFunction("zoomIn", &UIMap::zoomIn); - g_lua.bindClassMemberFunction("zoomOut", &UIMap::zoomOut); - g_lua.bindClassMemberFunction("followCreature", &UIMap::followCreature); - g_lua.bindClassMemberFunction("setCameraPosition", &UIMap::setCameraPosition); - g_lua.bindClassMemberFunction("setMaxZoomIn", &UIMap::setMaxZoomIn); - g_lua.bindClassMemberFunction("setMaxZoomOut", &UIMap::setMaxZoomOut); - g_lua.bindClassMemberFunction("setMultifloor", &UIMap::setMultifloor); - g_lua.bindClassMemberFunction("lockVisibleFloor", &UIMap::lockVisibleFloor); - g_lua.bindClassMemberFunction("unlockVisibleFloor", &UIMap::unlockVisibleFloor); - g_lua.bindClassMemberFunction("setVisibleDimension", &UIMap::setVisibleDimension); - g_lua.bindClassMemberFunction("setDrawFlags", &UIMap::setDrawFlags); - g_lua.bindClassMemberFunction("setDrawTexts", &UIMap::setDrawTexts); - g_lua.bindClassMemberFunction("setDrawNames", &UIMap::setDrawNames); - g_lua.bindClassMemberFunction("setDrawHealthBars", &UIMap::setDrawHealthBars); - g_lua.bindClassMemberFunction("setDrawHealthBarsOnTop", &UIMap::setDrawHealthBarsOnTop); - g_lua.bindClassMemberFunction("setDrawLights", &UIMap::setDrawLights); - g_lua.bindClassMemberFunction("setDrawManaBar", &UIMap::setDrawManaBar); - g_lua.bindClassMemberFunction("setDrawPlayerBars", &UIMap::setDrawPlayerBars); - g_lua.bindClassMemberFunction("setAnimated", &UIMap::setAnimated); - g_lua.bindClassMemberFunction("setKeepAspectRatio", &UIMap::setKeepAspectRatio); - g_lua.bindClassMemberFunction("setMinimumAmbientLight", &UIMap::setMinimumAmbientLight); - g_lua.bindClassMemberFunction("setLimitVisibleRange", &UIMap::setLimitVisibleRange); - g_lua.bindClassMemberFunction("setFloorFading", &UIMap::setFloorFading); - g_lua.bindClassMemberFunction("setCrosshair", &UIMap::setCrosshair); - g_lua.bindClassMemberFunction("setShader", &UIMap::setShader); - g_lua.bindClassMemberFunction("isMultifloor", &UIMap::isMultifloor); - g_lua.bindClassMemberFunction("isDrawingTexts", &UIMap::isDrawingTexts); - g_lua.bindClassMemberFunction("isDrawingNames", &UIMap::isDrawingNames); - g_lua.bindClassMemberFunction("isDrawingHealthBars", &UIMap::isDrawingHealthBars); - g_lua.bindClassMemberFunction("isDrawingHealthBarsOnTop", &UIMap::isDrawingHealthBarsOnTop); - g_lua.bindClassMemberFunction("isDrawingLights", &UIMap::isDrawingLights); - g_lua.bindClassMemberFunction("isDrawingManaBar", &UIMap::isDrawingManaBar); - g_lua.bindClassMemberFunction("isLimitVisibleRangeEnabled", &UIMap::isLimitVisibleRangeEnabled); - g_lua.bindClassMemberFunction("isAnimating", &UIMap::isAnimating); - g_lua.bindClassMemberFunction("isKeepAspectRatioEnabled", &UIMap::isKeepAspectRatioEnabled); - g_lua.bindClassMemberFunction("getVisibleDimension", &UIMap::getVisibleDimension); - g_lua.bindClassMemberFunction("getFollowingCreature", &UIMap::getFollowingCreature); - g_lua.bindClassMemberFunction("getDrawFlags", &UIMap::getDrawFlags); - g_lua.bindClassMemberFunction("getCameraPosition", &UIMap::getCameraPosition); - g_lua.bindClassMemberFunction("getPosition", &UIMap::getPosition); - g_lua.bindClassMemberFunction("getPositionOffset", &UIMap::getPositionOffset); - g_lua.bindClassMemberFunction("getTile", &UIMap::getTile); - g_lua.bindClassMemberFunction("getMaxZoomIn", &UIMap::getMaxZoomIn); - g_lua.bindClassMemberFunction("getMaxZoomOut", &UIMap::getMaxZoomOut); - g_lua.bindClassMemberFunction("getZoom", &UIMap::getZoom); - g_lua.bindClassMemberFunction("getMinimumAmbientLight", &UIMap::getMinimumAmbientLight); - g_lua.bindClassMemberFunction("getShader", &UIMap::getShader); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIMinimapPtr(new UIMinimap); }); - g_lua.bindClassMemberFunction("zoomIn", &UIMinimap::zoomIn); - g_lua.bindClassMemberFunction("zoomOut", &UIMinimap::zoomOut); - g_lua.bindClassMemberFunction("setZoom", &UIMinimap::setZoom); - g_lua.bindClassMemberFunction("setMixZoom", &UIMinimap::setMinZoom); - g_lua.bindClassMemberFunction("setMaxZoom", &UIMinimap::setMaxZoom); - g_lua.bindClassMemberFunction("setCameraPosition", &UIMinimap::setCameraPosition); - g_lua.bindClassMemberFunction("floorUp", &UIMinimap::floorUp); - g_lua.bindClassMemberFunction("floorDown", &UIMinimap::floorDown); - g_lua.bindClassMemberFunction("getTilePoint", &UIMinimap::getTilePoint); - g_lua.bindClassMemberFunction("getTilePosition", &UIMinimap::getTilePosition); - g_lua.bindClassMemberFunction("getTileRect", &UIMinimap::getTileRect); - g_lua.bindClassMemberFunction("getCameraPosition", &UIMinimap::getCameraPosition); - g_lua.bindClassMemberFunction("getMinZoom", &UIMinimap::getMinZoom); - g_lua.bindClassMemberFunction("getMaxZoom", &UIMinimap::getMaxZoom); - g_lua.bindClassMemberFunction("getZoom", &UIMinimap::getZoom); - g_lua.bindClassMemberFunction("getScale", &UIMinimap::getScale); - g_lua.bindClassMemberFunction("anchorPosition", &UIMinimap::anchorPosition); - g_lua.bindClassMemberFunction("fillPosition", &UIMinimap::fillPosition); - g_lua.bindClassMemberFunction("centerInPosition", &UIMinimap::centerInPosition); - - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIProgressRectPtr(new UIProgressRect); } ); - g_lua.bindClassMemberFunction("setPercent", &UIProgressRect::setPercent); - g_lua.bindClassMemberFunction("getPercent", &UIProgressRect::getPercent); - - g_lua.registerClass(); -} diff --git a/src/client/luavaluecasts_client.cpp b/src/client/luavaluecasts_client.cpp deleted file mode 100644 index 41c5573..0000000 --- a/src/client/luavaluecasts_client.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "luavaluecasts_client.h" -#include - -int push_luavalue(const Outfit& outfit) -{ - g_lua.createTable(0, 8); - g_lua.pushInteger(outfit.getId()); - g_lua.setField("type"); - g_lua.pushInteger(outfit.getAuxId()); - g_lua.setField("auxType"); - if(g_game.getFeature(Otc::GamePlayerAddons)) { - g_lua.pushInteger(outfit.getAddons()); - g_lua.setField("addons"); - } - g_lua.pushInteger(outfit.getHead()); - g_lua.setField("head"); - g_lua.pushInteger(outfit.getBody()); - g_lua.setField("body"); - g_lua.pushInteger(outfit.getLegs()); - g_lua.setField("legs"); - g_lua.pushInteger(outfit.getFeet()); - g_lua.setField("feet"); - if (g_game.getFeature(Otc::GamePlayerMounts)) { - g_lua.pushInteger(outfit.getMount()); - g_lua.setField("mount"); - } - if (g_game.getFeature(Otc::GameWingsAndAura)) { - g_lua.pushInteger(outfit.getWings()); - g_lua.setField("wings"); - g_lua.pushInteger(outfit.getAura()); - g_lua.setField("aura"); - } - if (g_game.getFeature(Otc::GameOutfitShaders)) { - g_lua.pushString(outfit.getShader()); - g_lua.setField("shader"); - } - return 1; -} - -bool luavalue_cast(int index, Outfit& outfit) -{ - if(g_lua.isTable(index)) { - g_lua.getField("type", index); - outfit.setId(g_lua.popInteger()); - g_lua.getField("auxType", index); - outfit.setAuxId(g_lua.popInteger()); - if(g_game.getFeature(Otc::GamePlayerAddons)) { - g_lua.getField("addons", index); - outfit.setAddons(g_lua.popInteger()); - } - g_lua.getField("head", index); - outfit.setHead(g_lua.popInteger()); - g_lua.getField("body", index); - outfit.setBody(g_lua.popInteger()); - g_lua.getField("legs", index); - outfit.setLegs(g_lua.popInteger()); - g_lua.getField("feet", index); - outfit.setFeet(g_lua.popInteger()); - if (g_game.getFeature(Otc::GamePlayerMounts)) { - g_lua.getField("mount", index); - outfit.setMount(g_lua.popInteger()); - } - if (g_game.getFeature(Otc::GameWingsAndAura)) { - g_lua.getField("wings", index); - outfit.setWings(g_lua.popInteger()); - g_lua.getField("aura", index); - outfit.setAura(g_lua.popInteger()); - } - //if (g_game.getFeature(Otc::GameOutfitShaders)) { - g_lua.getField("shader", index); - outfit.setShader(g_lua.popString()); - //} - return true; - } - return false; -} - -int push_luavalue(const Position& pos) -{ - if(pos.isValid()) { - g_lua.createTable(0, 3); - g_lua.pushInteger(pos.x); - g_lua.setField("x"); - g_lua.pushInteger(pos.y); - g_lua.setField("y"); - g_lua.pushInteger(pos.z); - g_lua.setField("z"); - } else - g_lua.pushNil(); - return 1; -} - -bool luavalue_cast(int index, Position& pos) -{ - if(g_lua.isTable(index)) { - g_lua.getField("x", index); - pos.x = g_lua.popInteger(); - g_lua.getField("y", index); - pos.y = g_lua.popInteger(); - g_lua.getField("z", index); - pos.z = g_lua.popInteger(); - return true; - } - return false; -} - -int push_luavalue(const MarketData& data) -{ - g_lua.createTable(0, 6); - g_lua.pushInteger(data.category); - g_lua.setField("category"); - g_lua.pushString(data.name); - g_lua.setField("name"); - g_lua.pushInteger(data.requiredLevel); - g_lua.setField("requiredLevel"); - g_lua.pushInteger(data.restrictVocation); - g_lua.setField("restrictVocation"); - g_lua.pushInteger(data.showAs); - g_lua.setField("showAs"); - g_lua.pushInteger(data.tradeAs); - g_lua.setField("tradeAs"); - return 1; -} - -bool luavalue_cast(int index, MarketData& data) -{ - if (g_lua.isTable(index)) { - g_lua.getField("category", index); - data.category = g_lua.popInteger(); - g_lua.getField("name", index); - data.name = g_lua.popString(); - g_lua.getField("requiredLevel", index); - data.requiredLevel = g_lua.popInteger(); - g_lua.getField("restrictVocation", index); - data.restrictVocation = g_lua.popInteger(); - g_lua.getField("showAs", index); - data.showAs = g_lua.popInteger(); - g_lua.getField("tradeAs", index); - data.tradeAs = g_lua.popInteger(); - return true; - } - return false; -} - -int push_luavalue(const StoreCategory& category) -{ - g_lua.createTable(0, 5); - g_lua.pushString(category.name); - g_lua.setField("name"); - g_lua.pushString(category.description); - g_lua.setField("description"); - g_lua.pushInteger(category.state); - g_lua.setField("state"); - g_lua.pushString(category.icon); - g_lua.setField("icon"); - g_lua.pushString(category.parent); - g_lua.setField("parent"); - return 1; -} - -bool luavalue_cast(int index, StoreCategory& data) -{ - if (g_lua.isTable(index)) { - g_lua.getField("name", index); - data.name = g_lua.popString(); - g_lua.getField("description", index); - data.description = g_lua.popString(); - g_lua.getField("state", index); - data.state = g_lua.popInteger(); - g_lua.getField("icon", index); - data.icon = g_lua.popString(); - g_lua.getField("parent", index); - data.parent = g_lua.popString(); - return true; - } - return false; -} - -int push_luavalue(const StoreOffer& offer) -{ - g_lua.createTable(0, 6); - g_lua.pushInteger(offer.id); - g_lua.setField("id"); - g_lua.pushString(offer.name); - g_lua.setField("name"); - g_lua.pushString(offer.description); - g_lua.setField("description"); - g_lua.pushInteger(offer.price); - g_lua.setField("price"); - g_lua.pushInteger(offer.state); - g_lua.setField("state"); - g_lua.pushString(offer.icon); - g_lua.setField("icon"); - return 1; -} - -bool luavalue_cast(int index, StoreOffer& data) -{ - if (g_lua.isTable(index)) { - g_lua.getField("id", index); - data.id = g_lua.popInteger(); - g_lua.getField("name", index); - data.name = g_lua.popString(); - g_lua.getField("description", index); - data.description = g_lua.popString(); - g_lua.getField("state", index); - data.state = g_lua.popInteger(); - g_lua.getField("price", index); - data.price = g_lua.popInteger(); - g_lua.getField("icon", index); - data.icon = g_lua.popString(); - return true; - } - return false; -} - -int push_luavalue(const Imbuement& i) -{ - g_lua.createTable(0, 11); - g_lua.pushInteger(i.id); - g_lua.setField("id"); - g_lua.pushString(i.name); - g_lua.setField("name"); - g_lua.pushString(i.description); - g_lua.setField("description"); - g_lua.pushString(i.group); - g_lua.setField("group"); - g_lua.pushInteger(i.imageId); - g_lua.setField("imageId"); - g_lua.pushInteger(i.duration); - g_lua.setField("duration"); - g_lua.pushBoolean(i.premiumOnly); - g_lua.setField("premiumOnly"); - g_lua.createTable(i.sources.size(), 0); - for (size_t j = 0; j < i.sources.size(); ++j) { - g_lua.createTable(0, 2); - g_lua.pushObject(i.sources[j].first); - g_lua.setField("item"); - g_lua.pushString(i.sources[j].second); - g_lua.setField("description"); - g_lua.rawSeti(j + 1); - } - g_lua.setField("sources"); - g_lua.pushInteger(i.cost); - g_lua.setField("cost"); - g_lua.pushInteger(i.successRate); - g_lua.setField("successRate"); - g_lua.pushInteger(i.protectionCost); - g_lua.setField("protectionCost"); - return 1; -} - -int push_luavalue(const Light& light) -{ - g_lua.createTable(0, 2); - g_lua.pushInteger(light.color); - g_lua.setField("color"); - g_lua.pushInteger(light.intensity); - g_lua.setField("intensity"); - return 1; -} - -bool luavalue_cast(int index, Light& light) -{ - if(g_lua.isTable(index)) { - g_lua.getField("color", index); - light.color = g_lua.popInteger(); - g_lua.getField("intensity", index); - light.intensity = g_lua.popInteger(); - return true; - } - return false; -} - -int push_luavalue(const UnjustifiedPoints& unjustifiedPoints) -{ - g_lua.createTable(0, 7); - g_lua.pushInteger(unjustifiedPoints.killsDay); - g_lua.setField("killsDay"); - g_lua.pushInteger(unjustifiedPoints.killsDayRemaining); - g_lua.setField("killsDayRemaining"); - g_lua.pushInteger(unjustifiedPoints.killsWeek); - g_lua.setField("killsWeek"); - g_lua.pushInteger(unjustifiedPoints.killsWeekRemaining); - g_lua.setField("killsWeekRemaining"); - g_lua.pushInteger(unjustifiedPoints.killsMonth); - g_lua.setField("killsMonth"); - g_lua.pushInteger(unjustifiedPoints.killsMonthRemaining); - g_lua.setField("killsMonthRemaining"); - g_lua.pushInteger(unjustifiedPoints.skullTime); - g_lua.setField("skullTime"); - return 1; -} - -bool luavalue_cast(int index, UnjustifiedPoints& unjustifiedPoints) -{ - if(g_lua.isTable(index)) { - g_lua.getField("killsDay", index); - unjustifiedPoints.killsDay = g_lua.popInteger(); - g_lua.getField("killsDayRemaining", index); - unjustifiedPoints.killsDayRemaining = g_lua.popInteger(); - g_lua.getField("killsWeek", index); - unjustifiedPoints.killsWeek = g_lua.popInteger(); - g_lua.getField("killsWeekRemaining", index); - unjustifiedPoints.killsWeekRemaining = g_lua.popInteger(); - g_lua.getField("killsMonth", index); - unjustifiedPoints.killsMonth = g_lua.popInteger(); - g_lua.getField("killsMonthRemaining", index); - unjustifiedPoints.killsMonthRemaining = g_lua.popInteger(); - g_lua.getField("skullTime", index); - unjustifiedPoints.skullTime = g_lua.popInteger(); - return true; - } - return false; -} diff --git a/src/client/luavaluecasts_client.h b/src/client/luavaluecasts_client.h deleted file mode 100644 index 467b5a1..0000000 --- a/src/client/luavaluecasts_client.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CLIENT_LUAVALUECASTS_H -#define CLIENT_LUAVALUECASTS_H - -#include "global.h" -#include -#include "game.h" -#include "outfit.h" - -// outfit -int push_luavalue(const Outfit& outfit); -bool luavalue_cast(int index, Outfit& outfit); - -// position -int push_luavalue(const Position& pos); -bool luavalue_cast(int index, Position& pos); - -// market -int push_luavalue(const MarketData& data); -bool luavalue_cast(int index, MarketData& data); - -// store category -int push_luavalue(const StoreCategory& category); -bool luavalue_cast(int index, StoreCategory& data); - -// store offer -int push_luavalue(const StoreOffer& offer); -bool luavalue_cast(int index, StoreOffer& offer); - -// imbuement -int push_luavalue(const Imbuement& offer); - -// light -int push_luavalue(const Light& light); -bool luavalue_cast(int index, Light& light); - -// unjustified points -int push_luavalue(const UnjustifiedPoints& unjustifiedPoints); -bool luavalue_cast(int index, UnjustifiedPoints& unjustifiedPoints); - -#endif diff --git a/src/client/map.cpp b/src/client/map.cpp deleted file mode 100644 index 13c67de..0000000 --- a/src/client/map.cpp +++ /dev/null @@ -1,1084 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "map.h" -#include "game.h" -#include "localplayer.h" -#include "tile.h" -#include "item.h" -#include "missile.h" -#include "statictext.h" -#include "mapview.h" -#include "minimap.h" - -#include -#include -#include -#include -#include - -Map g_map; -TilePtr Map::m_nulltile = nullptr; - -void Map::init() -{ - resetAwareRange(); - m_animationFlags |= Animation_Show; -} - -void Map::terminate() -{ - clean(); -} - -void Map::addMapView(const MapViewPtr& mapView) -{ - m_mapViews.push_back(mapView); -} - -void Map::removeMapView(const MapViewPtr& mapView) -{ - auto it = std::find(m_mapViews.begin(), m_mapViews.end(), mapView); - if(it != m_mapViews.end()) - m_mapViews.erase(it); -} - -void Map::notificateTileUpdate(const Position& pos, bool updateMinimap) -{ - if(!pos.isMapPosition()) - return; - - for(const MapViewPtr& mapView : m_mapViews) - mapView->onTileUpdate(pos); - - if (!updateMinimap) - return; - - if (!g_game.getFeature(Otc::GameMinimapLimitedToSingleFloor) || (m_centralPosition.z == pos.z)) { - g_minimap.updateTile(pos, getTile(pos)); - } -} - -void Map::requestVisibleTilesCacheUpdate() { - for (const MapViewPtr& mapView : m_mapViews) - mapView->requestVisibleTilesCacheUpdate(); -} - -void Map::clean() -{ - cleanDynamicThings(); - - for(int i=0;i<=Otc::MAX_Z;++i) - m_tileBlocks[i].clear(); - - m_waypoints.clear(); - - g_towns.clear(); - g_houses.clear(); - g_creatures.clearSpawns(); - m_tilesRect = Rect(65534, 65534, 0, 0); -} - -void Map::cleanDynamicThings() -{ - for(const auto& pair : m_knownCreatures) { - const CreaturePtr& creature = pair.second; - removeThing(creature); - } - m_knownCreatures.clear(); - - for(int i=0;i<=Otc::MAX_Z;++i) - m_floorMissiles[i].clear(); - - cleanTexts(); -} - -void Map::cleanTexts() -{ - m_animatedTexts.clear(); - m_staticTexts.clear(); -} - -void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos) -{ - if(!thing) - return; - - if(thing->isItem() || thing->isCreature() || thing->isEffect()) { - const TilePtr& tile = getOrCreateTile(pos); - if(tile) - tile->addThing(thing, stackPos); - } else { - if(thing->isMissile()) { - m_floorMissiles[pos.z].push_back(thing->static_self_cast()); - } else if(thing->isAnimatedText()) { - // this code will stack animated texts of the same color - AnimatedTextPtr animatedText = thing->static_self_cast(); - - AnimatedTextPtr prevAnimatedText; - bool merged = false; - for(auto other : m_animatedTexts) { - if(other->getPosition() == pos) { - prevAnimatedText = other; - if(other->merge(animatedText)) { - merged = true; - break; - } - } - } - if(!merged) { - m_animatedTexts.push_back(animatedText); - } - } else if(thing->isStaticText()) { - StaticTextPtr staticText = thing->static_self_cast(); - - bool mustAdd = true; - for(auto other : m_staticTexts) { - // try to combine messages - if(other->getPosition() == pos && other->addColoredMessage(staticText->getName(), staticText->getMessageMode(), staticText->getFirstMessage())) { - mustAdd = false; - break; - } - } - - if(mustAdd) - m_staticTexts.push_back(staticText); - else - return; - } - - thing->setPosition(pos); - thing->onAppear(); - - if (thing->isMissile()) { - g_lua.callGlobalField("g_map", "onMissle", thing); - } else if (thing->isAnimatedText()) { - AnimatedTextPtr animatedText = thing->static_self_cast(); - g_lua.callGlobalField("g_map", "onAnimatedText", thing, animatedText->getText()); - } else if (thing->isStaticText()) { - StaticTextPtr staticText = thing->static_self_cast(); - g_lua.callGlobalField("g_map", "onStaticText", thing, staticText->getText()); - } - } - - notificateTileUpdate(pos, thing->isItem()); -} - -void Map::setTileSpeed(const Position& pos, uint16_t speed, uint8_t blocking) { - const TilePtr& tile = getOrCreateTile(pos); - if (tile) - tile->setSpeed(speed, blocking); -} - -ThingPtr Map::getThing(const Position& pos, int stackPos) -{ - if(TilePtr tile = getTile(pos)) - return tile->getThing(stackPos); - return nullptr; -} - -bool Map::removeThing(const ThingPtr& thing) -{ - if(!thing) - return false; - - bool ret = false; - if(thing->isMissile()) { - MissilePtr missile = thing->static_self_cast(); - int z = missile->getPosition().z; - auto it = std::find(m_floorMissiles[z].begin(), m_floorMissiles[z].end(), missile); - if(it != m_floorMissiles[z].end()) { - m_floorMissiles[z].erase(it); - ret = true; - } - } else if(thing->isAnimatedText()) { - AnimatedTextPtr animatedText = thing->static_self_cast(); - auto it = std::find(m_animatedTexts.begin(), m_animatedTexts.end(), animatedText); - if(it != m_animatedTexts.end()) { - m_animatedTexts.erase(it); - ret = true; - } - } else if(thing->isStaticText()) { - StaticTextPtr staticText = thing->static_self_cast(); - auto it = std::find(m_staticTexts.begin(), m_staticTexts.end(), staticText); - if(it != m_staticTexts.end()) { - m_staticTexts.erase(it); - ret = true; - } - } else if(const TilePtr& tile = thing->getTile()) - ret = tile->removeThing(thing); - - notificateTileUpdate(thing->getPosition(), thing->isItem()); - return ret; -} - -bool Map::removeThingByPos(const Position& pos, int stackPos) -{ - if(TilePtr tile = getTile(pos)) - return removeThing(tile->getThing(stackPos)); - return false; -} - -void Map::colorizeThing(const ThingPtr& thing, const Color& color) -{ - if(!thing) - return; - - if(thing->isItem()) - thing->static_self_cast()->setColor(color); - else if(thing->isCreature()) { - const TilePtr& tile = thing->getTile(); - VALIDATE(tile); - - const ThingPtr& topThing = tile->getTopThing(); - VALIDATE(topThing); - - topThing->static_self_cast()->setColor(color); - } -} - -void Map::removeThingColor(const ThingPtr& thing) -{ - if(!thing) - return; - - if(thing->isItem()) - thing->static_self_cast()->setColor(Color::alpha); - else if(thing->isCreature()) { - const TilePtr& tile = thing->getTile(); - VALIDATE(tile); - - const ThingPtr& topThing = tile->getTopThing(); - VALIDATE(topThing); - - topThing->static_self_cast()->setColor(Color::alpha); - } -} - -StaticTextPtr Map::getStaticText(const Position& pos) -{ - for(auto staticText : m_staticTexts) { - // try to combine messages - if(staticText->getPosition() == pos) - return staticText; - } - return nullptr; -} - -const TilePtr& Map::createTile(const Position& pos) -{ - if(!pos.isMapPosition()) - return m_nulltile; - if(pos.x < m_tilesRect.left()) - m_tilesRect.setLeft(pos.x); - if(pos.y < m_tilesRect.top()) - m_tilesRect.setTop(pos.y); - if(pos.x > m_tilesRect.right()) - m_tilesRect.setRight(pos.x); - if(pos.y > m_tilesRect.bottom()) - m_tilesRect.setBottom(pos.y); - TileBlock& block = m_tileBlocks[pos.z][getBlockIndex(pos)]; - return block.create(pos); -} - -template -const TilePtr& Map::createTileEx(const Position& pos, const Items&... items) -{ - if(!pos.isValid()) - return m_nulltile; - const TilePtr& tile = getOrCreateTile(pos); - auto vec = {items...}; - for(auto it : vec) - addThing(it, pos); - - return tile; -} - -const TilePtr& Map::getOrCreateTile(const Position& pos) -{ - if(!pos.isMapPosition()) - return m_nulltile; - if(pos.x < m_tilesRect.left()) - m_tilesRect.setLeft(pos.x); - if(pos.y < m_tilesRect.top()) - m_tilesRect.setTop(pos.y); - if(pos.x > m_tilesRect.right()) - m_tilesRect.setRight(pos.x); - if(pos.y > m_tilesRect.bottom()) - m_tilesRect.setBottom(pos.y); - TileBlock& block = m_tileBlocks[pos.z][getBlockIndex(pos)]; - return block.getOrCreate(pos); -} - -const TilePtr& Map::getTile(const Position& pos) -{ - if(!pos.isMapPosition()) - return m_nulltile; - auto it = m_tileBlocks[pos.z].find(getBlockIndex(pos)); - if(it != m_tileBlocks[pos.z].end()) - return it->second.get(pos); - return m_nulltile; -} - -const TileList Map::getTiles(int floor/* = -1*/) -{ - TileList tiles; - if(floor > Otc::MAX_Z) { - return tiles; - } - else if(floor < 0) { - // Search all floors - for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) { - for(const auto& pair : m_tileBlocks[z]) { - const TileBlock& block = pair.second; - for(const TilePtr& tile : block.getTiles()) { - if(tile != nullptr) - tiles.push_back(tile); - } - } - } - } - else { - for(const auto& pair : m_tileBlocks[floor]) { - const TileBlock& block = pair.second; - for(const TilePtr& tile : block.getTiles()) { - if(tile != nullptr) - tiles.push_back(tile); - } - } - } - return tiles; -} - -void Map::cleanTile(const Position& pos) -{ - if(!pos.isMapPosition()) - return; - auto it = m_tileBlocks[pos.z].find(getBlockIndex(pos)); - if(it != m_tileBlocks[pos.z].end()) { - TileBlock& block = it->second; - if(const TilePtr& tile = block.get(pos)) { - tile->clean(); - if(tile->canErase()) - block.remove(pos); - - notificateTileUpdate(pos, false); - } - } - for(auto it = m_staticTexts.begin();it != m_staticTexts.end();) { - const StaticTextPtr& staticText = *it; - if(staticText->getPosition() == pos && staticText->getMessageMode() == Otc::MessageNone) - it = m_staticTexts.erase(it); - else - ++it; - } - - if (!g_game.getFeature(Otc::GameMinimapLimitedToSingleFloor) || (m_centralPosition.z == pos.z)) { - g_minimap.updateTile(pos, getTile(pos)); - } -} - -void Map::setShowZone(tileflags_t zone, bool show) -{ - if(show) - m_zoneFlags |= (uint32)zone; - else - m_zoneFlags &= ~(uint32)zone; -} - -void Map::setShowZones(bool show) -{ - if(!show) - m_zoneFlags = 0; - else if(m_zoneFlags == 0) - m_zoneFlags = TILESTATE_HOUSE | TILESTATE_PROTECTIONZONE; -} - -void Map::setZoneColor(tileflags_t zone, const Color& color) -{ - if((m_zoneFlags & zone) == zone) - m_zoneColors[zone] = color; -} - -Color Map::getZoneColor(tileflags_t flag) -{ - auto it = m_zoneColors.find(flag); - if(it == m_zoneColors.end()) - return Color::alpha; - return it->second; -} - -void Map::setForceShowAnimations(bool force) -{ - if(force) { - if(!(m_animationFlags & Animation_Force)) - m_animationFlags |= Animation_Force; - } else - m_animationFlags &= ~Animation_Force; -} - -bool Map::isForcingAnimations() -{ - return (m_animationFlags & Animation_Force) == Animation_Force; -} - -bool Map::isShowingAnimations() -{ - return (m_animationFlags & Animation_Show) == Animation_Show; -} - -void Map::setShowAnimations(bool show) -{ - if(show) { - if(!(m_animationFlags & Animation_Show)) - m_animationFlags |= Animation_Show; - } else - m_animationFlags &= ~Animation_Show; -} - -std::map Map::findItemsById(uint16 clientId, uint32 max) -{ - std::map ret; - uint32 count = 0; - for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) { - for(const auto& pair : m_tileBlocks[z]) { - const TileBlock& block = pair.second; - for(const TilePtr& tile : block.getTiles()) { - if(unlikely(!tile || tile->isEmpty())) - continue; - for(const ItemPtr& item : tile->getItems()) { - if(item->getId() == clientId) { - ret.insert(std::make_pair(tile->getPosition(), item)); - if(++count >= max) - break; - } - } - } - } - } - - return ret; -} - -void Map::addCreature(const CreaturePtr& creature) -{ - m_knownCreatures[creature->getId()] = creature; -} - -CreaturePtr Map::getCreatureById(uint32 id) -{ - auto it = m_knownCreatures.find(id); - if(it == m_knownCreatures.end()) - return nullptr; - return it->second; -} - -void Map::removeCreatureById(uint32 id) -{ - if(id == 0) - return; - - auto it = m_knownCreatures.find(id); - if(it != m_knownCreatures.end()) - m_knownCreatures.erase(it); -} - -void Map::removeUnawareThings() -{ - // remove creatures from tiles that we are not aware of anymore - for(const auto& pair : m_knownCreatures) { - const CreaturePtr& creature = pair.second; - if(!isAwareOfPosition(creature->getPosition())) - removeThing(creature); - } - - // remove static texts from tiles that we are not aware anymore - for(auto it = m_staticTexts.begin(); it != m_staticTexts.end();) { - const StaticTextPtr& staticText = *it; - if(staticText->getMessageMode() == Otc::MessageNone && !isAwareOfPosition(staticText->getPosition())) - it = m_staticTexts.erase(it); - else - ++it; - } - - bool extended = g_game.getFeature(Otc::GameBiggerMapCache); - if(!g_game.getFeature(Otc::GameKeepUnawareTiles)) { - // remove tiles that we are not aware anymore - for(int z = 0; z <= Otc::MAX_Z; ++z) { - auto& tileBlocks = m_tileBlocks[z]; - for(auto it = tileBlocks.begin(); it != tileBlocks.end();) { - TileBlock& block = (*it).second; - bool blockEmpty = true; - for(const TilePtr& tile : block.getTiles()) { - if(!tile) - continue; - - const Position& pos = tile->getPosition(); - - if(!isAwareOfPositionForClean(pos, extended)) - block.remove(pos); - else - blockEmpty = false; - } - - if(blockEmpty) - it = tileBlocks.erase(it); - else - ++it; - } - } - } -} - -void Map::setCentralPosition(const Position& centralPosition) -{ - if(m_centralPosition == centralPosition) - return; - - m_centralPosition = centralPosition; - - removeUnawareThings(); - - // this fixes local player position when the local player is removed from the map, - // the local player is removed from the map when there are too many creatures on his tile, - // so there is no enough stackpos to the server send him - g_dispatcher.addEvent([this] { - LocalPlayerPtr localPlayer = g_game.getLocalPlayer(); - if(!localPlayer || localPlayer->getPosition() == m_centralPosition) - return; - TilePtr tile = localPlayer->getTile(); - if(tile && tile->hasThing(localPlayer)) - return; - - Position oldPos = localPlayer->getPosition(); - Position pos = m_centralPosition; - if(oldPos != pos) { - if(!localPlayer->isRemoved()) - localPlayer->onDisappear(); - localPlayer->setPosition(pos); - localPlayer->onAppear(); - g_logger.debug("forced player position update"); - } - }); - - for(const MapViewPtr& mapView : m_mapViews) - mapView->onMapCenterChange(centralPosition); -} - -std::vector Map::getSightSpectators(const Position& centerPos, bool multiFloor) -{ - return getSpectatorsInRangeEx(centerPos, multiFloor, m_awareRange.left - 1, m_awareRange.right - 2, m_awareRange.top - 1, m_awareRange.bottom - 2); -} - -std::vector Map::getSpectators(const Position& centerPos, bool multiFloor) -{ - return getSpectatorsInRangeEx(centerPos, multiFloor, m_awareRange.left, m_awareRange.right, m_awareRange.top, m_awareRange.bottom); -} - -std::vector Map::getSpectatorsInRange(const Position& centerPos, bool multiFloor, int xRange, int yRange) -{ - return getSpectatorsInRangeEx(centerPos, multiFloor, xRange, xRange, yRange, yRange); -} - -std::vector Map::getSpectatorsInRangeEx(const Position& centerPos, bool multiFloor, int minXRange, int maxXRange, int minYRange, int maxYRange) -{ - int minZRange = 0; - int maxZRange = 0; - std::vector creatures; - - if(multiFloor) { - minZRange = 0; - maxZRange = Otc::MAX_Z; - } - - //TODO: optimize - //TODO: get creatures from other floors corretly - //TODO: delivery creatures in distance order - - for(int iz=-minZRange; iz<=maxZRange; ++iz) { - for(int iy=-minYRange; iy<=maxYRange; ++iy) { - for(int ix=-minXRange; ix<=maxXRange; ++ix) { - TilePtr tile = getTile(centerPos.translated(ix,iy,iz)); - if(!tile) - continue; - - auto tileCreatures = tile->getCreatures(); - creatures.insert(creatures.end(), tileCreatures.rbegin(), tileCreatures.rend()); - } - } - } - - return creatures; -} - -bool Map::isLookPossible(const Position& pos) -{ - TilePtr tile = getTile(pos); - return tile && tile->isLookPossible(); -} - -bool Map::isCovered(const Position& pos, int firstFloor) -{ - // check for tiles on top of the postion - Position tilePos = pos; - while(tilePos.coveredUp() && tilePos.z >= firstFloor) { - TilePtr tile = getTile(tilePos); - // the below tile is covered when the above tile has a full ground - if(tile && tile->isFullGround()) - return true; - } - return false; -} - -bool Map::isCompletelyCovered(const Position& pos, int firstFloor) -{ - const TilePtr& checkTile = getTile(pos); - Position tilePos = pos; - while(tilePos.coveredUp() && tilePos.z >= firstFloor) { - bool covered = true; - bool done = false; - // check in 2x2 range tiles that has no transparent pixels - for(int x=0;x<2 && !done;++x) { - for(int y=0;y<2 && !done;++y) { - const TilePtr& tile = getTile(tilePos.translated(-x, -y)); - if(!tile || !tile->isFullyOpaque()) { - covered = false; - done = true; - } else if(x==0 && y==0 && (!checkTile || checkTile->isSingleDimension())) { - done = true; - } - } - } - if(covered) - return true; - } - return false; -} - -bool Map::isAwareOfPosition(const Position& pos, bool extended) -{ - if ((pos.z < getFirstAwareFloor() || pos.z > getLastAwareFloor()) && !extended) - return false; - - Position groundedPos = pos; - while (groundedPos.z != m_centralPosition.z) { - if (groundedPos.z > m_centralPosition.z) { - if (groundedPos.x == 65535 || groundedPos.y == 65535) // When pos == 65535,65535,15 we cant go up to 65536,65536,14 - break; - groundedPos.coveredUp(); - } else { - if (groundedPos.x == 0 || groundedPos.y == 0) // When pos == 0,0,0 we cant go down to -1,-1,1 - break; - groundedPos.coveredDown(); - } - } - - if (extended) { - return m_centralPosition.isInRange(groundedPos, m_awareRange.left * 2, - m_awareRange.right * 2, - m_awareRange.top * 2, - m_awareRange.bottom * 2); - } - return m_centralPosition.isInRange(groundedPos, m_awareRange.left, - m_awareRange.right, - m_awareRange.top, - m_awareRange.bottom); -} - -bool Map::isAwareOfPositionForClean(const Position& pos, bool extended) -{ - if ((pos.z < getFirstAwareFloor() || pos.z > getLastAwareFloor()) && !extended) - return false; - - Position groundedPos = pos; - while (groundedPos.z != m_centralPosition.z) { - if (groundedPos.z > m_centralPosition.z) { - if (groundedPos.x == 65535 || groundedPos.y == 65535) // When pos == 65535,65535,15 we cant go up to 65536,65536,14 - break; - groundedPos.coveredUp(); - } else { - if (groundedPos.x == 0 || groundedPos.y == 0) // When pos == 0,0,0 we cant go down to -1,-1,1 - break; - groundedPos.coveredDown(); - } - } - - if (extended) { - return m_centralPosition.isInRange(groundedPos, m_awareRange.left * 4, - m_awareRange.right * 4, - m_awareRange.top * 4, - m_awareRange.bottom * 4); - } - return m_centralPosition.isInRange(groundedPos, m_awareRange.left + 1, - m_awareRange.right + 1, - m_awareRange.top + 1, - m_awareRange.bottom + 1); -} - -void Map::setAwareRange(const AwareRange& range) -{ - m_awareRange = range; - removeUnawareThings(); -} - -void Map::resetAwareRange() -{ - AwareRange range; - range.left = 8; - range.top = 6; - range.bottom = 7; - range.right = 9; - setAwareRange(range); -} - -int Map::getFirstAwareFloor() -{ - if(m_centralPosition.z > Otc::SEA_FLOOR) - return m_centralPosition.z-Otc::AWARE_UNDEGROUND_FLOOR_RANGE; - else - return 0; -} - -int Map::getLastAwareFloor() -{ - if(m_centralPosition.z > Otc::SEA_FLOOR) - return std::min(m_centralPosition.z+Otc::AWARE_UNDEGROUND_FLOOR_RANGE, (int)Otc::MAX_Z); - else - return Otc::SEA_FLOOR; -} - -std::tuple, Otc::PathFindResult> Map::findPath(const Position& startPos, const Position& goalPos, int maxComplexity, int flags) -{ - // pathfinding using A* search algorithm (otclientv8 note: it's dijkstra algorithm) - // as described in http://en.wikipedia.org/wiki/A*_search_algorithm - - struct SNode { - SNode(const Position& pos) : cost(0), totalCost(0), pos(pos), prev(nullptr), dir(Otc::InvalidDirection) { } - float cost; - float totalCost; - Position pos; - SNode *prev; - Otc::Direction dir; - }; - - struct LessNode { - bool operator()(std::pair a, std::pair b) const { - return b.second < a.second; - } - }; - - std::tuple, Otc::PathFindResult> ret; - std::vector& dirs = std::get<0>(ret); - Otc::PathFindResult& result = std::get<1>(ret); - - result = Otc::PathFindResultNoWay; - - if(startPos == goalPos) { - result = Otc::PathFindResultSamePosition; - return ret; - } - - if(startPos.z != goalPos.z) { - result = Otc::PathFindResultImpossible; - return ret; - } - - // check the goal pos is walkable - if(g_map.isAwareOfPosition(goalPos)) { - const TilePtr goalTile = getTile(goalPos); - if(!goalTile || (!goalTile->isWalkable(flags & Otc::PathFindIgnoreCreatures))) { - return ret; - } - } - else { - const MinimapTile& goalTile = g_minimap.getTile(goalPos); - if(goalTile.hasFlag(MinimapTileNotWalkable)) { - return ret; - } - } - - std::unordered_map nodes; - std::priority_queue, std::vector>, LessNode> searchList; - - // hidden code - - for(auto it : nodes) - delete it.second; - - return ret; -} - -PathFindResult_ptr Map::newFindPath(const Position& start, const Position& goal, std::shared_ptr> visibleNodes) { - auto ret = std::make_shared(); - ret->start = start; - ret->destination = goal; - - if (start == goal) { - ret->status = Otc::PathFindResultSamePosition; - return ret; - } - if (goal.z != start.z) { - return ret; - } - - struct LessNode { - bool operator()(Node* a, Node* b) const { - return b->totalCost < a->totalCost; - } - }; - - std::unordered_map nodes; - std::priority_queue, LessNode> searchList; - - if (visibleNodes) { - for (auto& node : *visibleNodes) - nodes.emplace(node->pos, node); - } - - Node* initNode = new Node{ 1, 0, start, nullptr, 0, 0 }; - nodes[start] = initNode; - searchList.push(initNode); - - int limit = 50000; - float distance = start.distance(goal); - - // hidden code - - return ret; -} - -void Map::findPathAsync(const Position& start, const Position& goal, std::function callback) { - -} - -std::map> Map::findEveryPath(const Position& start, int maxDistance, const std::map& params) -{ - // using Dijkstra's algorithm - struct LessNode { - bool operator()(Node* a, Node* b) const - { - return b->totalCost < a->totalCost; - } - }; - - if (g_extras.debugPathfinding) { - g_logger.info(stdext::format("findEveryPath: %i %i %i - %i", start.x, start.y, start.z, maxDistance)); - for (auto& param : params) { - g_logger.info(stdext::format("%s - %s", param.first, param.second)); - } - } - - std::map::const_iterator it; - it = params.find("ignoreLastCreature"); - bool ignoreLastCreature = it != params.end() && it->second != "0" && it->second != ""; - it = params.find("ignoreCreatures"); - bool ignoreCreatures = it != params.end() && it->second != "0" && it->second != ""; - it = params.find("ignoreNonPathable"); - bool ignoreNonPathable = it != params.end() && it->second != "0" && it->second != ""; - it = params.find("ignoreNonWalkable"); - bool ignoreNonWalkable = it != params.end() && it->second != "0" && it->second != ""; - it = params.find("ignoreStairs"); - bool ignoreStairs = it != params.end() && it->second != "0" && it->second != ""; - it = params.find("ignoreCost"); - bool ignoreCost = it != params.end() && it->second != "0" && it->second != ""; - it = params.find("allowUnseen"); - bool allowUnseen = it != params.end() && it->second != "0" && it->second != ""; - it = params.find("allowOnlyVisibleTiles"); - bool allowOnlyVisibleTiles = it != params.end() && it->second != "0" && it->second != ""; - it = params.find("marginMin"); - bool hasMargin = it != params.end(); - it = params.find("marginMax"); - hasMargin = hasMargin || (it != params.end()); - - - Position destPos; - it = params.find("destination"); - if (it != params.end()) { - std::vector pos = stdext::split(it->second, ","); - if (pos.size() == 3) { - destPos = Position(pos[0], pos[1], pos[2]); - } - } - - std::map> ret; - std::unordered_map nodes; - std::priority_queue, LessNode> searchList; - - Node* initNode = new Node{ 1, 0, start, nullptr, 0, 0 }; - nodes[start] = initNode; - searchList.push(initNode); - - // hidden code - - for (auto& node : nodes) { - if (node.second) - delete node.second; - } - - return ret; -} - -int Map::getMinimapColor(const Position& pos) -{ - int color = 0; - if (const TilePtr& tile = getTile(pos)) { - color = tile->getMinimapColorByte(); - } - if (color == 0) { - const MinimapTile& mtile = g_minimap.getTile(pos); - color = mtile.color; - } - return color; -} - -bool Map::isPatchable(const Position& pos) -{ - if (const TilePtr& tile = getTile(pos)) { - return tile->isPathable(); - } - const MinimapTile& mtile = g_minimap.getTile(pos); - return !mtile.hasFlag(MinimapTileNotPathable); -} - -bool Map::isWalkable(const Position& pos, bool ignoreCreatures) -{ - if (const TilePtr& tile = getTile(pos)) { - return tile->isWalkable(ignoreCreatures); - } - const MinimapTile& mtile = g_minimap.getTile(pos); - return !mtile.hasFlag(MinimapTileNotPathable); -} - -std::vector Map::getSpectatorsByPattern(const Position& centerPos, const std::string& pattern, Otc::Direction direction) -{ - std::vector finalPattern(pattern.size(), false); - std::vector creatures; - int width = 0, height = 0, lineLength = 0, p = 0; - for (auto& c : pattern) { - lineLength += 1; - if (c == '0' || c == '-') { - p += 1; - } else if (c == '1' || c == '+') { - finalPattern[p++] = true; - } else if (c == 'N' || c == 'n') { - finalPattern[p++] = direction == Otc::North; - } else if (c == 'E' || c == 'e') { - finalPattern[p++] = direction == Otc::East; - } else if (c == 'W' || c == 'w') { - finalPattern[p++] = direction == Otc::West; - } else if (c == 'S' || c == 's') { - finalPattern[p++] = direction == Otc::South; - } else { - lineLength -= 1; - if (lineLength > 1) { - if (width == 0) - width = lineLength; - if (width != lineLength) { - g_logger.error(stdext::format("Invalid pattern for getSpectatorsByPattern: %s", pattern)); - return creatures; - } - height += 1; - lineLength = 0; - } - } - } - if (lineLength > 0) { - if (width == 0) - width = lineLength; - if (width != lineLength) { - g_logger.error(stdext::format("Invalid pattern for getSpectatorsByPattern: %s", pattern)); - return creatures; - } - height += 1; - } - if (width % 2 != 1 || height % 2 != 1) { - g_logger.error(stdext::format("Invalid pattern for getSpectatorsByPattern, width and height should be odd (height: %i width: %i)", height, width)); - return creatures; - } - - p = 0; - for (int y = centerPos.y - height / 2, endy = centerPos.y + height / 2; y <= endy; ++y) { - for (int x = centerPos.x - width / 2, endx = centerPos.x + width / 2; x <= endx; ++x) { - if (!finalPattern[p++]) - continue; - TilePtr tile = getTile(Position(x, y, centerPos.z)); - if (!tile) - continue; - auto tileCreatures = tile->getCreatures(); - creatures.insert(creatures.end(), tileCreatures.rbegin(), tileCreatures.rend()); - } - } - return creatures; -} - -bool Map::isSightClear(const Position& fromPos, const Position& toPos) -{ - if (fromPos == toPos) { - return true; - } - - Position start(fromPos.z > toPos.z ? toPos : fromPos); - Position destination(fromPos.z > toPos.z ? fromPos : toPos); - - const int8_t mx = start.x < destination.x ? 1 : start.x == destination.x ? 0 : -1; - const int8_t my = start.y < destination.y ? 1 : start.y == destination.y ? 0 : -1; - - int32_t A = destination.y - start.y; - int32_t B = start.x - destination.x; - int32_t C = -(A * destination.x + B * destination.y); - - while (start.x != destination.x || start.y != destination.y) { - int32_t move_hor = std::abs(A * (start.x + mx) + B * (start.y) + C); - int32_t move_ver = std::abs(A * (start.x) + B * (start.y + my) + C); - int32_t move_cross = std::abs(A * (start.x + mx) + B * (start.y + my) + C); - - if (start.y != destination.y && (start.x == destination.x || move_hor > move_ver || move_hor > move_cross)) { - start.y += my; - } - - if (start.x != destination.x && (start.y == destination.y || move_ver > move_hor || move_ver > move_cross)) { - start.x += mx; - } - - auto tile = getTile(Position(start.x, start.y, start.z)); - if (tile && tile->isBlockingProjectile()) { - return false; - } - } - - while (start.z != destination.z) { - auto tile = getTile(Position(start.x, start.y, start.z)); - if (tile && tile->getThingCount() > 0) { - return false; - } - start.z++; - } - - return true; -} - -bool Map::checkSightLine(const Position& fromPos, const Position& toPos) -{ - if (fromPos.z != toPos.z) - return false; - return checkSightLine(fromPos, toPos) || checkSightLine(toPos, fromPos); -} \ No newline at end of file diff --git a/src/client/map.h b/src/client/map.h deleted file mode 100644 index e4e275c..0000000 --- a/src/client/map.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MAP_H -#define MAP_H - -#include "creature.h" -#include "houses.h" -#include "towns.h" -#include "creatures.h" -#include "animatedtext.h" -#include "statictext.h" -#include "tile.h" - -#include - -enum OTBM_ItemAttr -{ - OTBM_ATTR_DESCRIPTION = 1, - OTBM_ATTR_EXT_FILE = 2, - OTBM_ATTR_TILE_FLAGS = 3, - OTBM_ATTR_ACTION_ID = 4, - OTBM_ATTR_UNIQUE_ID = 5, - OTBM_ATTR_TEXT = 6, - OTBM_ATTR_DESC = 7, - OTBM_ATTR_TELE_DEST = 8, - OTBM_ATTR_ITEM = 9, - OTBM_ATTR_DEPOT_ID = 10, - OTBM_ATTR_SPAWN_FILE = 11, - OTBM_ATTR_RUNE_CHARGES = 12, - OTBM_ATTR_HOUSE_FILE = 13, - OTBM_ATTR_HOUSEDOORID = 14, - OTBM_ATTR_COUNT = 15, - OTBM_ATTR_DURATION = 16, - OTBM_ATTR_DECAYING_STATE = 17, - OTBM_ATTR_WRITTENDATE = 18, - OTBM_ATTR_WRITTENBY = 19, - OTBM_ATTR_SLEEPERGUID = 20, - OTBM_ATTR_SLEEPSTART = 21, - OTBM_ATTR_CHARGES = 22, - OTBM_ATTR_CONTAINER_ITEMS = 23, - OTBM_ATTR_ATTRIBUTE_MAP = 128, - /// just random numbers, they're not actually used by the binary reader... - OTBM_ATTR_WIDTH = 129, - OTBM_ATTR_HEIGHT = 130 -}; - -enum OTBM_NodeTypes_t -{ - OTBM_ROOTV2 = 1, - OTBM_MAP_DATA = 2, - OTBM_ITEM_DEF = 3, - OTBM_TILE_AREA = 4, - OTBM_TILE = 5, - OTBM_ITEM = 6, - OTBM_TILE_SQUARE = 7, - OTBM_TILE_REF = 8, - OTBM_SPAWNS = 9, - OTBM_SPAWN_AREA = 10, - OTBM_MONSTER = 11, - OTBM_TOWNS = 12, - OTBM_TOWN = 13, - OTBM_HOUSETILE = 14, - OTBM_WAYPOINTS = 15, - OTBM_WAYPOINT = 16 -}; - -enum { - OTCM_SIGNATURE = 0x4D43544F, - OTCM_VERSION = 1 -}; - -enum { - BLOCK_SIZE = 32 -}; - -enum : uint8 { - Animation_Force, - Animation_Show -}; - -class TileBlock { -public: - TileBlock() { m_tiles.fill(nullptr); } - - const TilePtr& create(const Position& pos) { - TilePtr& tile = m_tiles[getTileIndex(pos)]; - tile = TilePtr(new Tile(pos)); - return tile; - } - const TilePtr& getOrCreate(const Position& pos) { - TilePtr& tile = m_tiles[getTileIndex(pos)]; - if(!tile) - tile = TilePtr(new Tile(pos)); - return tile; - } - const TilePtr& get(const Position& pos) { return m_tiles[getTileIndex(pos)]; } - void remove(const Position& pos) { m_tiles[getTileIndex(pos)] = nullptr; } - - uint getTileIndex(const Position& pos) { return ((pos.y % BLOCK_SIZE) * BLOCK_SIZE) + (pos.x % BLOCK_SIZE); } - - const std::array& getTiles() const { return m_tiles; } - -private: - std::array m_tiles; -}; - -struct AwareRange -{ - int top; - int right; - int bottom; - int left; - - int horizontal() { return left + right + 1; } - int vertical() { return top + bottom + 1; } -}; - -struct PathFindResult -{ - Otc::PathFindResult status = Otc::PathFindResultNoWay; - std::vector path; - int complexity = 0; - Position start; - Position destination; -}; -using PathFindResult_ptr = std::shared_ptr; - -struct Node { - float cost; - float totalCost; - Position pos; - Node *prev; - int distance; - int unseen; -}; - -//@bindsingleton g_map -class Map -{ -public: - void init(); - void terminate(); - - void addMapView(const MapViewPtr& mapView); - void removeMapView(const MapViewPtr& mapView); - void notificateTileUpdate(const Position& pos, bool updateMinimap = false); - - void requestVisibleTilesCacheUpdate(); - - bool loadOtcm(const std::string& fileName); - void saveOtcm(const std::string& fileName); - - void loadOtbm(const std::string& fileName); - void saveOtbm(const std::string& fileName); - - // otbm attributes (description, size, etc.) - void setHouseFile(const std::string& file) { m_attribs.set(OTBM_ATTR_HOUSE_FILE, file); } - void setSpawnFile(const std::string& file) { m_attribs.set(OTBM_ATTR_SPAWN_FILE, file); } - void setDescription(const std::string& desc) { m_attribs.set(OTBM_ATTR_DESCRIPTION, desc); } - - void clearDescriptions() { m_attribs.remove(OTBM_ATTR_DESCRIPTION); } - void setWidth(uint16 w) { m_attribs.set(OTBM_ATTR_WIDTH, w); } - void setHeight(uint16 h) { m_attribs.set(OTBM_ATTR_HEIGHT, h); } - - std::string getHouseFile() { return m_attribs.get(OTBM_ATTR_HOUSE_FILE); } - std::string getSpawnFile() { return m_attribs.get(OTBM_ATTR_SPAWN_FILE); } - Size getSize() { return Size(m_attribs.get(OTBM_ATTR_WIDTH), m_attribs.get(OTBM_ATTR_HEIGHT)); } - std::vector getDescriptions() { return stdext::split(m_attribs.get(OTBM_ATTR_DESCRIPTION), "\n"); } - - void clean(); - void cleanDynamicThings(); - void cleanTexts(); - - // thing related - void addThing(const ThingPtr& thing, const Position& pos, int stackPos = -1); - void setTileSpeed(const Position & pos, uint16_t speed, uint8_t blocking); - ThingPtr getThing(const Position& pos, int stackPos); - bool removeThing(const ThingPtr& thing); - bool removeThingByPos(const Position& pos, int stackPos); - void colorizeThing(const ThingPtr& thing, const Color& color); - void removeThingColor(const ThingPtr& thing); - - StaticTextPtr getStaticText(const Position& pos); - - // tile related - const TilePtr& createTile(const Position& pos); - template - const TilePtr& createTileEx(const Position& pos, const Items&... items); - const TilePtr& getOrCreateTile(const Position& pos); - const TilePtr& getTile(const Position& pos); - const TileList getTiles(int floor = -1); - void cleanTile(const Position& pos); - - // tile zone related - void setShowZone(tileflags_t zone, bool show); - void setShowZones(bool show); - void setZoneColor(tileflags_t flag, const Color& color); - void setZoneOpacity(float opacity) { m_zoneOpacity = opacity; } - - float getZoneOpacity() { return m_zoneOpacity; } - Color getZoneColor(tileflags_t flag); - tileflags_t getZoneFlags() { return (tileflags_t)m_zoneFlags; } - bool showZones() { return m_zoneFlags != 0; } - bool showZone(tileflags_t zone) { return (m_zoneFlags & zone) == zone; } - - void setForceShowAnimations(bool force); - bool isForcingAnimations(); - bool isShowingAnimations(); - void setShowAnimations(bool show); - - std::map findItemsById(uint16 clientId, uint32 max); - - // known creature related - void addCreature(const CreaturePtr& creature); - CreaturePtr getCreatureById(uint32 id); - void removeCreatureById(uint32 id); - std::vector getSightSpectators(const Position& centerPos, bool multiFloor); - std::vector getSpectators(const Position& centerPos, bool multiFloor); - std::vector getSpectatorsInRange(const Position& centerPos, bool multiFloor, int xRange, int yRange); - std::vector getSpectatorsInRangeEx(const Position& centerPos, bool multiFloor, int minXRange, int maxXRange, int minYRange, int maxYRange); - - void setLight(const Light& light) { m_light = light; } - void setCentralPosition(const Position& centralPosition); - - bool isLookPossible(const Position& pos); - bool isCovered(const Position& pos, int firstFloor = 0); - bool isCompletelyCovered(const Position& pos, int firstFloor = 0); - bool isAwareOfPosition(const Position& pos, bool extended = false); - bool isAwareOfPositionForClean(const Position& pos, bool extended = false); - - void setAwareRange(const AwareRange& range); - void resetAwareRange(); - AwareRange getAwareRange() { return m_awareRange; } - Size getAwareRangeAsSize() { return Size(m_awareRange.horizontal(), m_awareRange.vertical()); } - - Light getLight() { return m_light; } - Position getCentralPosition() { return m_centralPosition; } - int getFirstAwareFloor(); - int getLastAwareFloor(); - const std::vector& getFloorMissiles(int z) { return m_floorMissiles[z]; } - - std::vector getAnimatedTexts() { return m_animatedTexts; } - std::vector getStaticTexts() { return m_staticTexts; } - - std::tuple, Otc::PathFindResult> findPath(const Position& start, const Position& goal, int maxComplexity, int flags = 0); - PathFindResult_ptr newFindPath(const Position& start, const Position& goal, std::shared_ptr> visibleNodes); - void findPathAsync(const Position & start, const Position & goal, std::function callback); - - // tuple = - std::map> findEveryPath(const Position& start, int maxDistance, const std::map& params); - - int getMinimapColor(const Position& pos); - bool isPatchable(const Position& pos); - bool isWalkable(const Position& pos, bool ignoreCreatures); - -private: - void removeUnawareThings(); - uint getBlockIndex(const Position& pos) { return ((pos.y / BLOCK_SIZE) * (65536 / BLOCK_SIZE)) + (pos.x / BLOCK_SIZE); } - - std::map m_tileBlocks[Otc::MAX_Z+1]; - std::map m_knownCreatures; - std::array, Otc::MAX_Z+1> m_floorMissiles; - std::vector m_animatedTexts; - std::vector m_staticTexts; - std::vector m_mapViews; - std::unordered_map m_waypoints; - - uint8 m_animationFlags; - uint32 m_zoneFlags; - std::map m_zoneColors; - float m_zoneOpacity; - - Light m_light; - Position m_centralPosition; - Rect m_tilesRect; - - stdext::packed_storage m_attribs; - AwareRange m_awareRange; - static TilePtr m_nulltile; -}; - -extern Map g_map; - -#endif diff --git a/src/client/mapio.cpp b/src/client/mapio.cpp deleted file mode 100644 index ca029c2..0000000 --- a/src/client/mapio.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "map.h" -#include "tile.h" -#include "game.h" - -#include -#include -#include -#include -#include -#include -#include - -void Map::loadOtbm(const std::string& fileName) -{ - try { - if(!g_things.isOtbLoaded()) - stdext::throw_exception("OTB isn't loaded yet to load a map."); - - FileStreamPtr fin = g_resources.openFile(fileName); - if(!fin) - stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName)); - - char identifier[4]; - if(fin->read(identifier, 1, 4) < 4) - stdext::throw_exception("Could not read file identifier"); - - if(memcmp(identifier, "OTBM", 4) != 0 && memcmp(identifier, "\0\0\0\0", 4) != 0) - stdext::throw_exception(stdext::format("Invalid file identifier detected: %s", identifier)); - - BinaryTreePtr root = fin->getBinaryTree(); - if(root->getU8()) - stdext::throw_exception("could not read root property!"); - - uint32 headerVersion = root->getU32(); - if(headerVersion > 3) - stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion)); - - setWidth(root->getU16()); - setHeight(root->getU16()); - - uint32 headerMajorItems = root->getU8(); - if(headerMajorItems > g_things.getOtbMajorVersion()) { - stdext::throw_exception(stdext::format("This map was saved with different OTB version. read %d what it's supposed to be: %d", - headerMajorItems, g_things.getOtbMajorVersion())); - } - - root->skip(3); - uint32 headerMinorItems = root->getU32(); - if(headerMinorItems > g_things.getOtbMinorVersion()) { - g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d or less", - headerMinorItems, g_things.getOtbMinorVersion())); - } - - BinaryTreePtr node = root->getChildren()[0]; - if(node->getU8() != OTBM_MAP_DATA) - stdext::throw_exception("Could not read root data node"); - - while(node->canRead()) { - uint8 attribute = node->getU8(); - std::string tmp = node->getString(); - switch (attribute) { - case OTBM_ATTR_DESCRIPTION: - setDescription(tmp); - break; - case OTBM_ATTR_SPAWN_FILE: - setSpawnFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp); - break; - case OTBM_ATTR_HOUSE_FILE: - setHouseFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp); - break; - default: - stdext::throw_exception(stdext::format("Invalid attribute '%d'", (int)attribute)); - } - } - - for(const BinaryTreePtr& nodeMapData : node->getChildren()) { - uint8 mapDataType = nodeMapData->getU8(); - if(mapDataType == OTBM_TILE_AREA) { - Position basePos; - basePos.x = nodeMapData->getU16(); - basePos.y = nodeMapData->getU16(); - basePos.z = nodeMapData->getU8(); - - for(const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) { - uint8 type = nodeTile->getU8(); - if(unlikely(type != OTBM_TILE && type != OTBM_HOUSETILE)) - stdext::throw_exception(stdext::format("invalid node tile type %d", (int)type)); - - HousePtr house = nullptr; - uint32 flags = TILESTATE_NONE; - Position pos = basePos + nodeTile->getPoint(); - - if(type == OTBM_HOUSETILE) { - uint32 hId = nodeTile->getU32(); - TilePtr tile = getOrCreateTile(pos); - if(!(house = g_houses.getHouse(hId))) { - house = HousePtr(new House(hId)); - g_houses.addHouse(house); - } - house->setTile(tile); - } - - while(nodeTile->canRead()) { - uint8 tileAttr = nodeTile->getU8(); - switch(tileAttr) { - case OTBM_ATTR_TILE_FLAGS: { - uint32 _flags = nodeTile->getU32(); - if((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE) - flags |= TILESTATE_PROTECTIONZONE; - else if((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE) - flags |= TILESTATE_OPTIONALZONE; - else if((_flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE) - flags |= TILESTATE_HARDCOREZONE; - - if((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT) - flags |= TILESTATE_NOLOGOUT; - - if((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH) - flags |= TILESTATE_REFRESH; - break; - } - case OTBM_ATTR_ITEM: { - addThing(Item::createFromOtb(nodeTile->getU16()), pos); - break; - } - default: { - stdext::throw_exception(stdext::format("invalid tile attribute %d at pos %s", - (int)tileAttr, stdext::to_string(pos))); - } - } - } - - for(const BinaryTreePtr& nodeItem : nodeTile->getChildren()) { - if(unlikely(nodeItem->getU8() != OTBM_ITEM)) - stdext::throw_exception("invalid item node"); - - ItemPtr item = Item::createFromOtb(nodeItem->getU16()); - item->unserializeItem(nodeItem); - - if(item->isContainer()) { - for(const BinaryTreePtr& containerItem : nodeItem->getChildren()) { - if(containerItem->getU8() != OTBM_ITEM) - stdext::throw_exception("invalid container item node"); - - ItemPtr cItem = Item::createFromOtb(containerItem->getU16()); - cItem->unserializeItem(containerItem); - item->addContainerItem(cItem); - } - } - - if(house && item->isMoveable()) { - g_logger.warning(stdext::format("Moveable item found in house: %d at pos %s - escaping...", item->getId(), stdext::to_string(pos))); - item.reset(); - } - - addThing(item, pos); - } - - if(const TilePtr& tile = getTile(pos)) { - if(house) - tile->setFlag(TILESTATE_HOUSE); - tile->setFlag(flags); - } - } - } else if(mapDataType == OTBM_TOWNS) { - TownPtr town = nullptr; - for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) { - if(nodeTown->getU8() != OTBM_TOWN) - stdext::throw_exception("invalid town node."); - - uint32 townId = nodeTown->getU32(); - std::string townName = nodeTown->getString(); - - Position townCoords; - townCoords.x = nodeTown->getU16(); - townCoords.y = nodeTown->getU16(); - townCoords.z = nodeTown->getU8(); - - if(!(town = g_towns.getTown(townId))) - g_towns.addTown(TownPtr(new Town(townId, townName, townCoords))); - } - g_towns.sort(); - } else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) { - for(const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) { - if(nodeWaypoint->getU8() != OTBM_WAYPOINT) - stdext::throw_exception("invalid waypoint node."); - - std::string name = nodeWaypoint->getString(); - - Position waypointPos; - waypointPos.x = nodeWaypoint->getU16(); - waypointPos.y = nodeWaypoint->getU16(); - waypointPos.z = nodeWaypoint->getU8(); - - if(waypointPos.isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end()) - m_waypoints.insert(std::make_pair(waypointPos, name)); - } - } else - stdext::throw_exception(stdext::format("Unknown map data node %d", (int)mapDataType)); - } - - fin->close(); - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what())); - } -} - -void Map::saveOtbm(const std::string& fileName) -{ - try { - FileStreamPtr fin = g_resources.createFile(fileName); - if(!fin) - stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName)); - - std::string dir; - if(fileName.find_last_of('/') == std::string::npos) - dir = g_resources.getWorkDir(); - else - dir = fileName.substr(0, fileName.find_last_of('/')); - - uint32 version = 0; - if(g_things.getOtbMajorVersion() < ClientVersion820) - version = 1; - else - version = 2; - - /// Usually when a map has empty house/spawn file it means the map is new. - /// TODO: Ask the user for a map name instead of those ugly uses of substr - std::string::size_type sep_pos; - std::string houseFile = getHouseFile(); - std::string spawnFile = getSpawnFile(); - std::string cpyf; - - if((sep_pos = fileName.rfind('.')) != std::string::npos && stdext::ends_with(fileName, ".otbm")) - cpyf = fileName.substr(0, sep_pos); - - if(houseFile.empty()) - houseFile = cpyf + "-houses.xml"; - - if(spawnFile.empty()) - spawnFile = cpyf + "-spawns.xml"; - - /// we only need the filename to save to, the directory should be resolved by the OTBM loader not here - if((sep_pos = spawnFile.rfind('/')) != std::string::npos) - spawnFile = spawnFile.substr(sep_pos + 1); - - if((sep_pos = houseFile.rfind('/')) != std::string::npos) - houseFile = houseFile.substr(sep_pos + 1); - - fin->addU32(0); // file version - OutputBinaryTreePtr root(new OutputBinaryTree(fin)); - { - root->addU32(version); - - Size mapSize = getSize(); - root->addU16(mapSize.width()); - root->addU16(mapSize.height()); - - root->addU32(g_things.getOtbMajorVersion()); - root->addU32(g_things.getOtbMinorVersion()); - - root->startNode(OTBM_MAP_DATA); - { - root->addU8(OTBM_ATTR_DESCRIPTION); - root->addString(m_attribs.get(OTBM_ATTR_DESCRIPTION)); - - root->addU8(OTBM_ATTR_SPAWN_FILE); - root->addString(spawnFile); - - root->addU8(OTBM_ATTR_HOUSE_FILE); - root->addString(houseFile); - - int px = -1, py = -1, pz =-1; - bool firstNode = true; - - for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) { - for(const auto& it : m_tileBlocks[z]) { - const TileBlock& block = it.second; - for(const TilePtr& tile : block.getTiles()) { - if(unlikely(!tile || tile->isEmpty())) - continue; - - const Position& pos = tile->getPosition(); - if(unlikely(!pos.isValid())) - continue; - - if(pos.x < px || pos.x >= px + 256 - || pos.y < py || pos.y >= py + 256 - || pos.z != pz) { - if(!firstNode) - root->endNode(); /// OTBM_TILE_AREA - - firstNode = false; - root->startNode(OTBM_TILE_AREA); - - px = pos.x & 0xFF00; - py = pos.y & 0xFF00; - pz = pos.z; - root->addPos(px, py, pz); - } - - root->startNode(tile->isHouseTile() ? OTBM_HOUSETILE : OTBM_TILE); - root->addPoint(Point(pos.x, pos.y) & 0xFF); - if(tile->isHouseTile()) - root->addU32(tile->getHouseId()); - - if(tile->getFlags()) { - root->addU8(OTBM_ATTR_TILE_FLAGS); - root->addU32(tile->getFlags()); - } - - const auto& itemList = tile->getItems(); - const ItemPtr& ground = tile->getGround(); - if(ground) { - // Those types are called "complex" needs other stuff to be written. - // For containers, there is container items, for depot, depot it and so on. - if(!ground->isContainer() && !ground->isDepot() - && !ground->isDoor() && !ground->isTeleport()) { - root->addU8(OTBM_ATTR_ITEM); - root->addU16(ground->getServerId()); - } else - ground->serializeItem(root); - } - for(const ItemPtr& item : itemList) - if(!item->isGround()) - item->serializeItem(root); - - root->endNode(); // OTBM_TILE - } - } - } - - if(!firstNode) - root->endNode(); // OTBM_TILE_AREA - - root->startNode(OTBM_TOWNS); - for(const TownPtr& town : g_towns.getTowns()) { - root->startNode(OTBM_TOWN); - - root->addU32(town->getId()); - root->addString(town->getName()); - - Position townPos = town->getPos(); - root->addPos(townPos.x, townPos.y, townPos.z); - root->endNode(); - } - root->endNode(); - - if(version > 1) { - root->startNode(OTBM_WAYPOINTS); - for(const auto& it : m_waypoints) { - root->startNode(OTBM_WAYPOINT); - root->addString(it.second); - - Position pos = it.first; - root->addPos(pos.x, pos.y, pos.z); - root->endNode(); - } - root->endNode(); - } - } - root->endNode(); // OTBM_MAP_DATA - } - root->endNode(); - - fin->flush(); - fin->close(); - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what())); - } -} - -bool Map::loadOtcm(const std::string& fileName) -{ - try { - FileStreamPtr fin = g_resources.openFile(fileName); - if(!fin) - stdext::throw_exception("unable to open file"); - - uint32 signature = fin->getU32(); - if(signature != OTCM_SIGNATURE) - stdext::throw_exception("invalid otcm file"); - - uint16 start = fin->getU16(); - uint16 version = fin->getU16(); - fin->getU32(); // flags - - switch(version) { - case 1: { - fin->getString(); // description - uint32 datSignature = fin->getU32(); - fin->getU16(); // protocol version - fin->getString(); // world name - - if(datSignature != g_things.getDatSignature()) - g_logger.warning("otcm map loaded was created with a different dat signature"); - - break; - } - default: - stdext::throw_exception("otcm version not supported"); - } - - fin->seek(start); - - while(true) { - Position pos; - - pos.x = fin->getU16(); - pos.y = fin->getU16(); - pos.z = fin->getU8(); - - // end of file - if(!pos.isValid()) - break; - - const TilePtr& tile = g_map.createTile(pos); - - int stackPos = 0; - while(true) { - int id = fin->getU16(); - - // end of tile - if(id == 0xFFFF) - break; - - int countOrSubType = fin->getU8(); - - ItemPtr item = Item::create(id); - item->setCountOrSubType(countOrSubType); - - if(item->isValid()) - tile->addThing(item, stackPos++); - } - - g_map.notificateTileUpdate(pos); - } - - fin->close(); - - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("failed to load OTCM map: %s", e.what())); - return false; - } -} - -void Map::saveOtcm(const std::string& fileName) -{ - try { - stdext::timer saveTimer; - - FileStreamPtr fin = g_resources.createFile(fileName); - - //TODO: compression flag with zlib - uint32 flags = 0; - - // header - fin->addU32(OTCM_SIGNATURE); - fin->addU16(0); // data start, will be overwritten later - fin->addU16(OTCM_VERSION); - fin->addU32(flags); - - // version 1 header - fin->addString("OTCM 1.0"); // map description - fin->addU32(g_things.getDatSignature()); - fin->addU16(g_game.getClientVersion()); - fin->addString(g_game.getWorldName()); - - // go back and rewrite where the map data starts - uint32 start = fin->tell(); - fin->seek(4); - fin->addU16(start); - fin->seek(start); - - for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) { - for(const auto& it : m_tileBlocks[z]) { - const TileBlock& block = it.second; - for(const TilePtr& tile : block.getTiles()) { - if(!tile || tile->isEmpty()) - continue; - - Position pos = tile->getPosition(); - fin->addU16(pos.x); - fin->addU16(pos.y); - fin->addU8(pos.z); - - for(const ThingPtr& thing : tile->getThings()) { - if(thing->isItem()) { - ItemPtr item = thing->static_self_cast(); - fin->addU16(item->getId()); - fin->addU8(item->getCountOrSubType()); - } - } - - // end of tile - fin->addU16(0xFFFF); - } - } - } - - // end of file - Position invalidPos; - fin->addU16(invalidPos.x); - fin->addU16(invalidPos.y); - fin->addU8(invalidPos.z); - - fin->flush(); - - fin->close(); - } catch(stdext::exception& e) { - g_logger.error(stdext::format("failed to save OTCM map: %s", e.what())); - } -} - -/* vim: set ts=4 sw=4 et: */ diff --git a/src/client/mapview.cpp b/src/client/mapview.cpp deleted file mode 100644 index fc90117..0000000 --- a/src/client/mapview.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "mapview.h" - -#include "creature.h" -#include "map.h" -#include "tile.h" -#include "statictext.h" -#include "animatedtext.h" -#include "missile.h" -#include "shadermanager.h" -#include "lightview.h" -#include "localplayer.h" -#include "game.h" -#include "spritemanager.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -MapView::MapView() -{ - m_lockedFirstVisibleFloor = -1; - m_cachedFirstVisibleFloor = 7; - m_cachedLastVisibleFloor = 7; - m_fadeOutTime = 0; - m_fadeInTime = 0; - m_minimumAmbientLight = 0; - m_optimizedSize = Size(g_map.getAwareRange().horizontal(), g_map.getAwareRange().vertical()) * g_sprites.spriteSize(); - - setVisibleDimension(Size(15, 11)); -} - -MapView::~MapView() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); -#endif -} - -void MapView::drawTileTexts(const Rect& rect, const Rect& srcRect) -{ - Position cameraPosition = getCameraPosition(); - Point drawOffset = srcRect.topLeft(); - float horizontalStretchFactor = rect.width() / (float)srcRect.width(); - float verticalStretchFactor = rect.height() / (float)srcRect.height(); - - auto player = g_game.getLocalPlayer(); - for (auto& tile : m_cachedVisibleTiles) { - Position tilePos = tile.first->getPosition(); - if (tilePos.z != player->getPosition().z) continue; - - Point p = transformPositionTo2D(tilePos, cameraPosition) - drawOffset; - p.x *= horizontalStretchFactor; - p.y *= verticalStretchFactor; - p += rect.topLeft(); - p.y += 5; - - tile.first->drawTexts(p); - } -} - - -void MapView::drawBackground(const Rect& rect, const TilePtr& crosshairTile) { - Position cameraPosition = getCameraPosition(); - if (m_mustUpdateVisibleTilesCache) { - updateVisibleTilesCache(); - } - - if (g_game.getFeature(Otc::GameForceLight)) { - m_drawLight = true; - m_minimumAmbientLight = 0.05f; - } - - Rect srcRect = calcFramebufferSource(rect.size()); - g_drawQueue->setFrameBuffer(rect, m_optimizedSize, srcRect); - - if (m_drawLight) { - Light ambientLight; - if (cameraPosition.z <= Otc::SEA_FLOOR) - ambientLight = g_map.getLight(); - if (!m_lightTexture || m_lightTexture->getSize() != m_drawDimension) - m_lightTexture = TexturePtr(new Texture(m_drawDimension, false, true)); - m_lightView = std::make_unique(m_lightTexture, m_drawDimension, rect, srcRect, ambientLight.color, - std::max(m_minimumAmbientLight * 255, ambientLight.intensity)); - } - - auto itm = m_cachedVisibleTiles.begin(); - auto end = m_cachedVisibleTiles.end(); - for (int z = m_cachedLastVisibleFloor; z >= m_cachedFirstFadingFloor; --z) { - float fading = 1.0; - if (m_floorFading > 0) { - fading = 0.; - if (m_floorFading > 0) { - fading = stdext::clamp((float)m_fadingFloorTimers[z].elapsed_millis() / (float)m_floorFading, 0.f, 1.f); - if (z < m_cachedFirstVisibleFloor) - fading = 1.0 - fading; - } - if (fading == 0) break; - } - - size_t floorStart = g_drawQueue->size(); - size_t lightFloorStart = m_lightView ? m_lightView->size() : 0; - for (; itm != end; ++itm) { - Position tilePos = itm->first->getPosition(); - if (tilePos.z != z) - break; - - - Point tileDrawPos = transformPositionTo2D(tilePos, cameraPosition); - - if (m_lightView) { - ItemPtr ground = itm->first->getGround(); - if (ground && ground->isGround() && !ground->isTranslucent()) { - m_lightView->setFieldBrightness(tileDrawPos, lightFloorStart, 0); - } - } - - itm->first->drawBottom(tileDrawPos, m_lightView.get()); - if (m_crosshair && itm->first == crosshairTile) - { - g_drawQueue->addTexturedRect(Rect(tileDrawPos, tileDrawPos + Otc::TILE_PIXELS - 1), - m_crosshair, Rect(0, 0, m_crosshair->getSize())); - } - itm->first->drawTop(tileDrawPos, m_lightView.get()); - } - for (const MissilePtr& missile : g_map.getFloorMissiles(z)) { - missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), true, m_lightView.get()); - } - if (fading < 0.99) - g_drawQueue->setOpacity(floorStart, fading); - } - -} - -void MapView::drawForeground(const Rect& rect) -{ - // this could happen if the player position is not known yet - Position cameraPosition = getCameraPosition(); - if (!cameraPosition.isValid()) - return; - - Rect srcRect = calcFramebufferSource(rect.size()); - Point drawOffset = srcRect.topLeft(); - float horizontalStretchFactor = rect.width() / (float)srcRect.width(); - float verticalStretchFactor = rect.height() / (float)srcRect.height(); - - // creatures - std::vector> creatures; - for (const CreaturePtr& creature : g_map.getSpectatorsInRangeEx(cameraPosition, false, m_visibleDimension.width() / 2, m_visibleDimension.width() / 2 + 1, m_visibleDimension.height() / 2, m_visibleDimension.height() / 2 + 1)) { - if (!creature->canBeSeen()) - continue; - - PointF jumpOffset = creature->getJumpOffset(); - Point creatureOffset = Point(16 - creature->getDisplacementX(), -creature->getDisplacementY() - 2); - Position pos = creature->getPrewalkingPosition(); - Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset; - p += (creature->getDrawOffset() + creatureOffset) - Point(stdext::round(jumpOffset.x), stdext::round(jumpOffset.y)); - p.x = p.x * horizontalStretchFactor; - p.y = p.y * verticalStretchFactor; - p += rect.topLeft(); - creatures.push_back(std::make_pair(creature, p)); - } - - for (auto& c : creatures) { - int flags = Otc::DrawIcons; - if (m_drawNames) { flags |= Otc::DrawNames; } - if ((!c.first->isLocalPlayer() || m_drawPlayerBars) && !m_drawHealthBarsOnTop) { - if (m_drawHealthBars) { flags |= Otc::DrawBars; } - if (m_drawManaBar) { flags |= Otc::DrawManaBar; } - } - c.first->drawInformation(c.second, g_map.isCovered(c.first->getPrewalkingPosition(), m_cachedFirstVisibleFloor), rect, flags); - } - - if (m_lightView) { - g_drawQueue->add(m_lightView.release()); - } - - // texts - int limit = g_adaptiveRenderer.textsLimit(); - for (int i = 0; i < 2; ++i) { - for (const StaticTextPtr& staticText : g_map.getStaticTexts()) { - Position pos = staticText->getPosition(); - - if (pos.z != cameraPosition.z && staticText->getMessageMode() == Otc::MessageNone) - continue; - if ((staticText->getMessageMode() != Otc::MessageSay && staticText->getMessageMode() != Otc::MessageYell)) { - if (i == 0) - continue; - } else if (i == 1) - continue; - - Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset + Point(8, 0); - p.x *= horizontalStretchFactor; - p.y *= verticalStretchFactor; - p += rect.topLeft(); - staticText->drawText(p, rect); - if (--limit == 0) - break; - } - } - - limit = g_adaptiveRenderer.textsLimit(); - for (const AnimatedTextPtr& animatedText : g_map.getAnimatedTexts()) { - Position pos = animatedText->getPosition(); - - if (pos.z != cameraPosition.z) - continue; - - Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset + Point(16, 8); - p.x *= horizontalStretchFactor; - p.y *= verticalStretchFactor; - p += rect.topLeft(); - animatedText->drawText(p, rect); - if (--limit == 0) - break; - } - - // tile texts - drawTileTexts(rect, srcRect); - - // bars on top - if (m_drawHealthBarsOnTop) { - for (auto& c : creatures) { - int flags = 0; - if ((!c.first->isLocalPlayer() || m_drawPlayerBars)) { - if (m_drawHealthBars) { flags |= Otc::DrawBars; } - if (m_drawManaBar) { flags |= Otc::DrawManaBar; } - } - c.first->drawInformation(c.second, g_map.isCovered(c.first->getPrewalkingPosition(), m_cachedFirstVisibleFloor), rect, flags); - } - } -} - - -void MapView::updateVisibleTilesCache() -{ - // hidden -} - -void MapView::updateGeometry(const Size& visibleDimension, const Size& optimizedSize) -{ - m_multifloor = true; - m_visibleDimension = visibleDimension; - m_drawDimension = visibleDimension + Size(3, 3); - m_virtualCenterOffset = (m_drawDimension / 2 - Size(1, 1)).toPoint(); - m_visibleCenterOffset = m_virtualCenterOffset; - m_optimizedSize = m_drawDimension * g_sprites.spriteSize(); - requestVisibleTilesCacheUpdate(); -} - -void MapView::onTileUpdate(const Position& pos) -{ - requestVisibleTilesCacheUpdate(); -} - -void MapView::onMapCenterChange(const Position& pos) -{ - requestVisibleTilesCacheUpdate(); -} - -void MapView::lockFirstVisibleFloor(int firstVisibleFloor) -{ - m_lockedFirstVisibleFloor = firstVisibleFloor; - requestVisibleTilesCacheUpdate(); -} - -void MapView::unlockFirstVisibleFloor() -{ - m_lockedFirstVisibleFloor = -1; - requestVisibleTilesCacheUpdate(); -} - -void MapView::setVisibleDimension(const Size& visibleDimension) -{ - //if(visibleDimension == m_visibleDimension) - // return; - - if(visibleDimension.width() % 2 != 1 || visibleDimension.height() % 2 != 1) { - g_logger.traceError("visible dimension must be odd"); - return; - } - - if(visibleDimension < Size(3,3)) { - g_logger.traceError("reach max zoom in"); - return; - } - - updateGeometry(visibleDimension, m_optimizedSize); -} - -void MapView::optimizeForSize(const Size& visibleSize) -{ - updateGeometry(m_visibleDimension, visibleSize); -} - -void MapView::followCreature(const CreaturePtr& creature) -{ - m_follow = true; - m_followingCreature = creature; - requestVisibleTilesCacheUpdate(); -} - -void MapView::setCameraPosition(const Position& pos) -{ - m_follow = false; - m_customCameraPosition = pos; - requestVisibleTilesCacheUpdate(); -} - -Position MapView::getPosition(const Point& point, const Size& mapSize) -{ - Position cameraPosition = getCameraPosition(); - - // if we have no camera, its impossible to get the tile - if(!cameraPosition.isValid()) - return Position(); - - Rect srcRect = calcFramebufferSource(mapSize); - float sh = srcRect.width() / (float)mapSize.width(); - float sv = srcRect.height() / (float)mapSize.height(); - - Point framebufferPos = Point(point.x * sh, point.y * sv); - Point realPos = (framebufferPos + srcRect.topLeft()); - Point centerOffset = realPos / Otc::TILE_PIXELS; - - Point tilePos2D = getVisibleCenterOffset() - m_drawDimension.toPoint() + centerOffset + Point(2,2); - if(tilePos2D.x + cameraPosition.x < 0 && tilePos2D.y + cameraPosition.y < 0) - return Position(); - - Position position = Position(tilePos2D.x, tilePos2D.y, 0) + cameraPosition; - - if(!position.isValid()) - return Position(); - - return position; -} - -Point MapView::getPositionOffset(const Point& point, const Size& mapSize) -{ - Position cameraPosition = getCameraPosition(); - - // if we have no camera, its impossible to get the tile - if (!cameraPosition.isValid()) - return Point(0, 0); - - Rect srcRect = calcFramebufferSource(mapSize); - float sh = srcRect.width() / (float)mapSize.width(); - float sv = srcRect.height() / (float)mapSize.height(); - - Point framebufferPos = Point(point.x * sh, point.y * sv); - Point realPos = (framebufferPos + srcRect.topLeft()); - return Point(realPos.x % Otc::TILE_PIXELS, realPos.y % Otc::TILE_PIXELS); -} - -void MapView::move(int x, int y) -{ - m_moveOffset.x += x; - m_moveOffset.y += y; - - int32_t tmp = m_moveOffset.x / g_sprites.spriteSize(); - bool requestTilesUpdate = false; - if(tmp != 0) { - m_customCameraPosition.x += tmp; - m_moveOffset.x %= g_sprites.spriteSize(); - requestTilesUpdate = true; - } - - tmp = m_moveOffset.y / g_sprites.spriteSize(); - if(tmp != 0) { - m_customCameraPosition.y += tmp; - m_moveOffset.y %= g_sprites.spriteSize(); - requestTilesUpdate = true; - } - - if(requestTilesUpdate) - requestVisibleTilesCacheUpdate(); -} - -Rect MapView::calcFramebufferSource(const Size& destSize, bool inNextFrame) -{ - float scaleFactor = g_sprites.spriteSize()/(float)Otc::TILE_PIXELS; - Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * g_sprites.spriteSize(); - if(isFollowingCreature()) - drawOffset += m_followingCreature->getWalkOffset(inNextFrame) * scaleFactor; - - Size srcSize = destSize; - Size srcVisible = m_visibleDimension * g_sprites.spriteSize(); - srcSize.scale(srcVisible, Fw::KeepAspectRatio); - drawOffset.x += (srcVisible.width() - srcSize.width()) / 2; - drawOffset.y += (srcVisible.height() - srcSize.height()) / 2; - - return Rect(drawOffset, srcSize); -} - -int MapView::calcFirstVisibleFloor(bool forFading) -{ - int z = 7; - // return forced first visible floor - if(m_lockedFirstVisibleFloor != -1) { - z = m_lockedFirstVisibleFloor; - } else { - Position cameraPosition = getCameraPosition(); - - // this could happens if the player is not known yet - if(cameraPosition.isValid()) { - // avoid rendering multifloors in far views - if(!m_multifloor) { - z = cameraPosition.z; - } else { - // if nothing is limiting the view, the first visible floor is 0 - int firstFloor = 0; - - // limits to underground floors while under sea level - if(cameraPosition.z > Otc::SEA_FLOOR) - firstFloor = std::max(cameraPosition.z - Otc::AWARE_UNDEGROUND_FLOOR_RANGE, (int)Otc::UNDERGROUND_FLOOR); - - // loop in 3x3 tiles around the camera - for(int ix = -1; ix <= 1 && firstFloor < cameraPosition.z && !forFading; ++ix) { - for(int iy = -1; iy <= 1 && firstFloor < cameraPosition.z; ++iy) { - Position pos = cameraPosition.translated(ix, iy); - - // process tiles that we can look through, e.g. windows, doors - if((ix == 0 && iy == 0) || ((std::abs(ix) != std::abs(iy)) && g_map.isLookPossible(pos))) { - Position upperPos = pos; - Position coveredPos = pos; - - while(coveredPos.coveredUp() && upperPos.up() && upperPos.z >= firstFloor) { - // check tiles physically above - TilePtr tile = g_map.getTile(upperPos); - if(tile && tile->limitsFloorsView(!g_map.isLookPossible(pos))) { - firstFloor = upperPos.z + 1; - break; - } - - // check tiles geometrically above - tile = g_map.getTile(coveredPos); - if(tile && tile->limitsFloorsView(g_map.isLookPossible(pos))) { - firstFloor = coveredPos.z + 1; - break; - } - } - } - } - } - z = firstFloor; - } - } - } - - // just ensure the that the floor is in the valid range - z = stdext::clamp(z, 0, (int)Otc::MAX_Z); - return z; -} - -int MapView::calcLastVisibleFloor() -{ - if(!m_multifloor) - return calcFirstVisibleFloor(); - - int z = 7; - - Position cameraPosition = getCameraPosition(); - // this could happens if the player is not known yet - if(cameraPosition.isValid()) { - // view only underground floors when below sea level - if(cameraPosition.z > Otc::SEA_FLOOR) - z = cameraPosition.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE; - else - z = Otc::SEA_FLOOR; - } - - if(m_lockedFirstVisibleFloor != -1) - z = std::max(m_lockedFirstVisibleFloor, z); - - // just ensure the that the floor is in the valid range - z = stdext::clamp(z, 0, (int)Otc::MAX_Z); - return z; -} - -Point MapView::transformPositionTo2D(const Position& position, const Position& relativePosition) { - return Point((m_virtualCenterOffset.x + (position.x - relativePosition.x) - (relativePosition.z - position.z)) * g_sprites.spriteSize(), - (m_virtualCenterOffset.y + (position.y - relativePosition.y) - (relativePosition.z - position.z)) * g_sprites.spriteSize()); -} - - -Position MapView::getCameraPosition() -{ - if (isFollowingCreature()) { - return m_followingCreature->getPrewalkingPosition(); - } - - return m_customCameraPosition; -} - -void MapView::setDrawLights(bool enable) -{ - m_drawLight = enable; -} - -void MapView::setCrosshair(const std::string& file) -{ - if (file == "") - m_crosshair = nullptr; - else - m_crosshair = g_textures.getTexture(file); -} - -/* vim: set ts=4 sw=4 et: */ diff --git a/src/client/mapview.h b/src/client/mapview.h deleted file mode 100644 index f9a1e8e..0000000 --- a/src/client/mapview.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MAPVIEW_H -#define MAPVIEW_H - -#include "declarations.h" -#include -#include -#include -#include -#include "lightview.h" - -// @bindclass -class MapView : public LuaObject -{ -public: - MapView(); - ~MapView(); - void drawBackground(const Rect& rect, const TilePtr& crosshairTile = nullptr); - void drawForeground(const Rect& rect); - void drawTexts(const Rect& rect, const Rect& srcRect); - -private: - void drawTileTexts(const Rect& rect, const Rect& srcRect); - void updateGeometry(const Size& visibleDimension, const Size& optimizedSize); - void updateVisibleTilesCache(); - void requestVisibleTilesCacheUpdate() { m_mustUpdateVisibleTilesCache = true; } - -protected: - void onTileUpdate(const Position& pos); - void onMapCenterChange(const Position& pos); - - friend class Map; - -public: - // floor visibility related - void lockFirstVisibleFloor(int firstVisibleFloor); - void unlockFirstVisibleFloor(); - int getLockedFirstVisibleFloor() { return m_lockedFirstVisibleFloor; } - - void setMultifloor(bool enable) { m_multifloor = enable; requestVisibleTilesCacheUpdate(); } - bool isMultifloor() { return m_multifloor; } - - // map dimension related - void setVisibleDimension(const Size& visibleDimension); - void optimizeForSize(const Size & visibleSize); - Size getVisibleDimension() { return m_visibleDimension; } - Point getVisibleCenterOffset() { return m_visibleCenterOffset; } - int getCachedFirstVisibleFloor() { return m_cachedFirstVisibleFloor; } - int getCachedLastVisibleFloor() { return m_cachedLastVisibleFloor; } - - // camera related - void followCreature(const CreaturePtr& creature); - CreaturePtr getFollowingCreature() { return m_followingCreature; } - bool isFollowingCreature() { return m_followingCreature && m_follow; } - - void setCameraPosition(const Position& pos); - Position getCameraPosition(); - - void setMinimumAmbientLight(float intensity) { m_minimumAmbientLight = intensity; } - float getMinimumAmbientLight() { return m_minimumAmbientLight; } - - // drawing related - void setDrawFlags(Otc::DrawFlags drawFlags) { m_drawFlags = drawFlags; requestVisibleTilesCacheUpdate(); } - Otc::DrawFlags getDrawFlags() { return m_drawFlags; } - - void setDrawTexts(bool enable) { m_drawTexts = enable; } - bool isDrawingTexts() { return m_drawTexts; } - - void setDrawNames(bool enable) { m_drawNames = enable; } - bool isDrawingNames() { return m_drawNames; } - - void setDrawHealthBars(bool enable) { m_drawHealthBars = enable; } - bool isDrawingHealthBars() { return m_drawHealthBars; } - - void setDrawHealthBarsOnTop(bool enable) { m_drawHealthBarsOnTop = enable; } - bool isDrawingHealthBarsOnTop() { return m_drawHealthBarsOnTop; } - - void setDrawLights(bool enable); - bool isDrawingLights() { return m_drawLight; } - - void setDrawManaBar(bool enable) { m_drawManaBar = enable; } - bool isDrawingManaBar() { return m_drawManaBar; } - - void setDrawPlayerBars(bool enable) { m_drawPlayerBars = enable; } - - void move(int x, int y); - - void setAnimated(bool animated) { m_animated = animated; requestVisibleTilesCacheUpdate(); } - bool isAnimating() { return m_animated; } - - void setFloorFading(int value) { m_floorFading = value; } - void setCrosshair(const std::string& file); - - //void setShader(const PainterShaderProgramPtr& shader, float fadein, float fadeout); - //PainterShaderProgramPtr getShader() { return m_shader; } - - Position getPosition(const Point& point, const Size& mapSize); - - Point getPositionOffset(const Point& point, const Size& mapSize); - - MapViewPtr asMapView() { return static_self_cast(); } - -private: - Rect calcFramebufferSource(const Size& destSize, bool inNextFrame = false); - int calcFirstVisibleFloor(bool forFading = false); - int calcLastVisibleFloor(); - Point transformPositionTo2D(const Position& position, const Position& relativePosition); - - stdext::timer m_mapRenderTimer; - - int m_lockedFirstVisibleFloor; - int m_cachedFirstVisibleFloor; - int m_cachedFirstFadingFloor; - int m_cachedLastVisibleFloor; - int m_updateTilesPos; - int m_floorFading = 500; - TexturePtr m_crosshair = nullptr; - Size m_drawDimension; - Size m_visibleDimension; - Size m_optimizedSize; - Point m_virtualCenterOffset; - Point m_visibleCenterOffset; - Point m_moveOffset; - Position m_customCameraPosition; - Position m_lastCameraPosition; - stdext::boolean m_mustUpdateVisibleTilesCache; - stdext::boolean m_mustDrawVisibleTilesCache; - stdext::boolean m_multifloor; - stdext::boolean m_animated; - stdext::boolean m_drawTexts; - stdext::boolean m_drawNames; - stdext::boolean m_drawHealthBars; - stdext::boolean m_drawHealthBarsOnTop; - stdext::boolean m_drawManaBar; - bool m_drawPlayerBars = true; - stdext::boolean m_smooth; - - stdext::timer m_fadingFloorTimers[Otc::MAX_Z + 1]; - - stdext::boolean m_follow; - std::vector> m_cachedVisibleTiles; - CreaturePtr m_followingCreature; - //PainterShaderProgramPtr m_shader; - Otc::DrawFlags m_drawFlags; - bool m_drawLight = false; - float m_minimumAmbientLight; - std::unique_ptr m_lightView; - TexturePtr m_lightTexture; - Timer m_fadeTimer; - //PainterShaderProgramPtr m_nextShader; - float m_fadeInTime; - float m_fadeOutTime; - //stdext::boolean m_shaderSwitchDone; -}; - -#endif diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp deleted file mode 100644 index d02434a..0000000 --- a/src/client/minimap.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#include "minimap.h" -#include "tile.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -Minimap g_minimap; - -void MinimapBlock::clean() -{ - m_tiles.fill(MinimapTile()); - m_texture.reset(); - m_mustUpdate = false; -} - -void MinimapBlock::update() -{ - if(!m_mustUpdate) - return; - - ImagePtr image(new Image(Size(MMBLOCK_SIZE, MMBLOCK_SIZE))); - - bool shouldDraw = false; - for(int x=0;xsetPixel(x, y, col); - } - } - - if(shouldDraw) { - m_texture = TexturePtr(new Texture(image)); - } else - m_texture.reset(); - - m_mustUpdate = false; -} - -void MinimapBlock::updateTile(int x, int y, const MinimapTile& tile) -{ - if(m_tiles[getTileIndex(x,y)].color != tile.color) - m_mustUpdate = true; - - m_tiles[getTileIndex(x,y)] = tile; -} - -void Minimap::init() -{ -} - -void Minimap::terminate() -{ - clean(); -} - -void Minimap::clean() -{ - std::lock_guard lock(m_lock); - for(int i=0;i<=Otc::MAX_Z;++i) - m_tileBlocks[i].clear(); -} - -void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scale, const Color& color) -{ - if(screenRect.isEmpty()) - return; - - Rect mapRect = calcMapRect(screenRect, mapCenter, scale); - g_drawQueue->addFilledRect(screenRect, color); - - if(MMBLOCK_SIZE*scale <= 1 || !mapCenter.isMapPosition()) { - return; - } - - size_t drawQueueStart = g_drawQueue->size(); - Point blockOff = getBlockOffset(mapRect.topLeft()); - Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2; - Point start = screenRect.topLeft() -(mapRect.topLeft() - blockOff)*scale - off; - - for(int y = blockOff.y, ys = start.y;ys= 65536) - continue; - - for(int x = blockOff.x, xs = start.x;xs= 65536) - continue; - - Position blockPos(x, y, mapCenter.z); - if(!hasBlock(blockPos)) - continue; - - MinimapBlock& block = getBlock(Position(x, y, mapCenter.z)); - block.update(); - - const TexturePtr& tex = block.getTexture(); - if(tex) { - Rect src(0, 0, MMBLOCK_SIZE, MMBLOCK_SIZE); - Rect dest(xs, ys, MMBLOCK_SIZE * scale, MMBLOCK_SIZE * scale); - - g_drawQueue->addTexturedRect(dest, tex, src); - } - } - } - - g_drawQueue->setClip(drawQueueStart, screenRect); -} - -Point Minimap::getTilePoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale) -{ - if(screenRect.isEmpty() || pos.z != mapCenter.z) - return Point(-1,-1); - - Rect mapRect = calcMapRect(screenRect, mapCenter, scale); - Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2; - Point posoff = (Point(pos.x,pos.y) - mapRect.topLeft())*scale; - return posoff + screenRect.topLeft() - off + (Point(1,1)*scale)/2; -} - -Position Minimap::getTilePosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale) -{ - if(screenRect.isEmpty()) - return Position(); - - Rect mapRect = calcMapRect(screenRect, mapCenter, scale); - Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2; - Point pos2d = (point - screenRect.topLeft() + off)/scale + mapRect.topLeft(); - return Position(pos2d.x, pos2d.y, mapCenter.z); -} - -Rect Minimap::getTileRect(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale) -{ - if(screenRect.isEmpty() || pos.z != mapCenter.z) - return Rect(); - - int tileSize = 32 * scale; - Rect tileRect(0,0,tileSize, tileSize); - tileRect.moveCenter(getTilePoint(pos, screenRect, mapCenter, scale)); - return tileRect; -} - -Rect Minimap::calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale) -{ - int w = screenRect.width() / scale, h = std::ceil(screenRect.height() / scale); - Rect mapRect(0,0,w,h); - mapRect.moveCenter(Point(mapCenter.x, mapCenter.y)); - return mapRect; -} - -void Minimap::updateTile(const Position& pos, const TilePtr& tile) -{ - MinimapTile minimapTile; - if(tile) { - minimapTile.color = tile->getMinimapColorByte(); - minimapTile.flags |= MinimapTileWasSeen; - if(!tile->isWalkable(true)) - minimapTile.flags |= MinimapTileNotWalkable; - if(!tile->isPathable()) - minimapTile.flags |= MinimapTileNotPathable; - minimapTile.speed = std::min((int)std::ceil(tile->getGroundSpeed() / 10.0f), 255); - } else { - minimapTile.color = 255; - minimapTile.flags |= MinimapTileEmpty; - minimapTile.speed = 1; - } - - if(minimapTile != MinimapTile()) { - MinimapBlock& block = getBlock(pos); - Point offsetPos = getBlockOffset(Point(pos.x, pos.y)); - block.updateTile(pos.x - offsetPos.x, pos.y - offsetPos.y, minimapTile); - block.justSaw(); - } -} - -const MinimapTile& Minimap::getTile(const Position& pos) -{ - static MinimapTile nulltile; - if(pos.z <= Otc::MAX_Z && hasBlock(pos)) { - MinimapBlock& block = getBlock(pos); - Point offsetPos = getBlockOffset(Point(pos.x, pos.y)); - return block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y); - } - return nulltile; -} - -std::pair Minimap::threadGetTile(const Position& pos) { - std::lock_guard lock(m_lock); - static MinimapTile nulltile; - - if (pos.z <= Otc::MAX_Z && hasBlock(pos)) { - MinimapBlock_ptr block = m_tileBlocks[pos.z][getBlockIndex(pos)]; - if (block) { - Point offsetPos = getBlockOffset(Point(pos.x, pos.y)); - return std::make_pair(block, block->getTile(pos.x - offsetPos.x, pos.y - offsetPos.y)); - } - } - return std::make_pair(nullptr, nulltile); -} - -bool Minimap::loadImage(const std::string& fileName, const Position& topLeft, float colorFactor) -{ - if(colorFactor <= 0.01f) - colorFactor = 1.0f; - - try { - ImagePtr image = Image::load(fileName); - - uint8 waterc = Color::to8bit(std::string("#3300cc")); - - // non pathable colors - Color nonPathableColors[] = { - std::string("#ffff00"), // yellow - }; - - // non walkable colors - Color nonWalkableColors[] = { - std::string("#000000"), // oil, black - std::string("#006600"), // trees, dark green - std::string("#ff3300"), // walls, red - std::string("#666666"), // mountain, grey - std::string("#ff6600"), // lava, orange - std::string("#00ff00"), // positon - std::string("#ccffff"), // ice, very light blue - }; - - for(int y=0;ygetHeight();++y) { - for(int x=0;xgetWidth();++x) { - Color color = *(uint32*)image->getPixel(x,y); - uint8 c = Color::to8bit(color * colorFactor); - int flags = 0; - - if(c == waterc || color.a() == 0) { - flags |= MinimapTileNotWalkable; - c = 255; // alpha - } - - if(flags != 0) { - for(Color &col : nonWalkableColors) { - if(col == color) { - flags |= MinimapTileNotWalkable; - break; - } - } - } - - if(flags != 0) { - for(Color &col : nonPathableColors) { - if(col == color) { - flags |= MinimapTileNotPathable; - break; - } - } - } - - if(c == 255) - continue; - - Position pos(topLeft.x + x, topLeft.y + y, topLeft.z); - MinimapBlock& block = getBlock(pos); - Point offsetPos = getBlockOffset(Point(pos.x, pos.y)); - MinimapTile& tile = block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y); - if(!(tile.flags & MinimapTileWasSeen)) { - tile.color = c; - tile.flags = flags; - block.mustUpdate(); - } - } - } - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("failed to load OTMM minimap: %s", e.what())); - return false; - } -} - -void Minimap::saveImage(const std::string& fileName, const Rect& mapRect) -{ - //TODO -} - -bool Minimap::loadOtmm(const std::string& fileName) -{ - try { - FileStreamPtr fin = g_resources.openFile(fileName); - if(!fin) - stdext::throw_exception("unable to open file"); - - uint32 signature = fin->getU32(); - if(signature != OTMM_SIGNATURE) - stdext::throw_exception("invalid OTMM file"); - - uint16 start = fin->getU16(); - uint16 version = fin->getU16(); - fin->getU32(); // flags - - switch(version) { - case 1: { - fin->getString(); // description - break; - } - default: - stdext::throw_exception("OTMM version not supported"); - } - - fin->seek(start); - - uint blockSize = MMBLOCK_SIZE * MMBLOCK_SIZE * sizeof(MinimapTile); - std::vector compressBuffer(compressBound(blockSize)); - std::vector decompressBuffer(blockSize); - - while(true) { - Position pos; - pos.x = fin->getU16(); - pos.y = fin->getU16(); - pos.z = fin->getU8(); - - // end of file or file is corrupted - if(!pos.isValid() || pos.z >= Otc::MAX_Z+1) - break; - - MinimapBlock& block = getBlock(pos); - ulong len = fin->getU16(); - ulong destLen = blockSize; - fin->read(compressBuffer.data(), len); - int ret = uncompress(decompressBuffer.data(), &destLen, compressBuffer.data(), len); - if(ret != Z_OK || destLen != blockSize) - break; - - memcpy((uchar*)&block.getTiles(), decompressBuffer.data(), blockSize); - block.mustUpdate(); - block.justSaw(); - } - - fin->close(); - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("failed to load OTMM minimap: %s", e.what())); - return false; - } -} - -void Minimap::saveOtmm(const std::string& fileName) -{ - try { - stdext::timer saveTimer; - - FileStreamPtr fin = g_resources.createFile(fileName); - - //TODO: compression flag with zlib - uint32 flags = 0; - - // header - fin->addU32(OTMM_SIGNATURE); - fin->addU16(0); // data start, will be overwritten later - fin->addU16(OTMM_VERSION); - fin->addU32(flags); - - // version 1 header - fin->addString("OTMM 1.0"); // description - - // go back and rewrite where the map data starts - uint32 start = fin->tell(); - fin->seek(4); - fin->addU16(start); - fin->seek(start); - - uint blockSize = MMBLOCK_SIZE * MMBLOCK_SIZE * sizeof(MinimapTile); - std::vector compressBuffer(compressBound(blockSize)); - const int COMPRESS_LEVEL = 3; - - for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) { - for(auto& it : m_tileBlocks[z]) { - int index = it.first; - MinimapBlock& block = *it.second; - if(!block.wasSeen()) - continue; - - Position pos = getIndexPosition(index, z); - fin->addU16(pos.x); - fin->addU16(pos.y); - fin->addU8(pos.z); - - ulong len = blockSize; - int ret = compress2(compressBuffer.data(), &len, (uchar*)&block.getTiles(), blockSize, COMPRESS_LEVEL); - VALIDATE(ret == Z_OK); - fin->addU16(len); - fin->write(compressBuffer.data(), len); - } - } - - // end of file - Position invalidPos; - fin->addU16(invalidPos.x); - fin->addU16(invalidPos.y); - fin->addU8(invalidPos.z); - - fin->flush(); - - fin->close(); - } catch(stdext::exception& e) { - g_logger.error(stdext::format("failed to save OTMM minimap: %s", e.what())); - } -} diff --git a/src/client/minimap.h b/src/client/minimap.h deleted file mode 100644 index fbffc50..0000000 --- a/src/client/minimap.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef MINIMAP_H -#define MINIMAP_H - -#include "declarations.h" -#include - -enum { - MMBLOCK_SIZE = 64, - OTMM_SIGNATURE = 0x4D4d544F, - OTMM_VERSION = 1 -}; - -enum MinimapTileFlags { - MinimapTileWasSeen = 1, - MinimapTileNotPathable = 2, - MinimapTileNotWalkable = 4, - MinimapTileEmpty = 8 -}; - -#pragma pack(push,1) // disable memory alignment -struct MinimapTile -{ - MinimapTile() : flags(0), color(255), speed(10) { } - uint8 flags; - uint8 color; - uint8 speed; - bool hasFlag(MinimapTileFlags flag) const { return flags & flag; } - int getSpeed() const { return speed * 10; } - bool operator==(const MinimapTile& other) const { return color == other.color && flags == other.flags && speed == other.speed; } - bool operator!=(const MinimapTile& other) const { return !(*this == other); } -}; - -class MinimapBlock -{ -public: - void clean(); - void update(); - void updateTile(int x, int y, const MinimapTile& tile); - MinimapTile& getTile(int x, int y) { return m_tiles[getTileIndex(x,y)]; } - void resetTile(int x, int y) { m_tiles[getTileIndex(x,y)] = MinimapTile(); } - uint getTileIndex(int x, int y) { return ((y % MMBLOCK_SIZE) * MMBLOCK_SIZE) + (x % MMBLOCK_SIZE); } - const TexturePtr& getTexture() { return m_texture; } - std::array& getTiles() { return m_tiles; } - void mustUpdate() { m_mustUpdate = true; } - void justSaw() { m_wasSeen = true; } - bool wasSeen() { return m_wasSeen; } -private: - TexturePtr m_texture; - std::array m_tiles; - stdext::boolean m_mustUpdate; - stdext::boolean m_wasSeen; -}; - -#pragma pack(pop) - -using MinimapBlock_ptr = std::shared_ptr; - -class Minimap -{ - -public: - void init(); - void terminate(); - - void clean(); - - void draw(const Rect& screenRect, const Position& mapCenter, float scale, const Color& color); - Point getTilePoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale); - Position getTilePosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale); - Rect getTileRect(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale); - - void updateTile(const Position& pos, const TilePtr& tile); - const MinimapTile& getTile(const Position& pos); - std::pair threadGetTile(const Position& pos); - - bool loadImage(const std::string& fileName, const Position& topLeft, float colorFactor); - void saveImage(const std::string& fileName, const Rect& mapRect); - bool loadOtmm(const std::string& fileName); - void saveOtmm(const std::string& fileName); - -private: - Rect calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale); - bool hasBlock(const Position& pos) { return m_tileBlocks[pos.z].find(getBlockIndex(pos)) != m_tileBlocks[pos.z].end(); } - MinimapBlock& getBlock(const Position& pos) { - std::lock_guard lock(m_lock); - auto& ptr = m_tileBlocks[pos.z][getBlockIndex(pos)]; - if (!ptr) - ptr = std::make_shared(); - return *ptr; - } - Point getBlockOffset(const Point& pos) { return Point(pos.x - pos.x % MMBLOCK_SIZE, - pos.y - pos.y % MMBLOCK_SIZE); } - Position getIndexPosition(int index, int z) { return Position((index % (65536 / MMBLOCK_SIZE))*MMBLOCK_SIZE, - (index / (65536 / MMBLOCK_SIZE))*MMBLOCK_SIZE, z); } - uint getBlockIndex(const Position& pos) { return ((pos.y / MMBLOCK_SIZE) * (65536 / MMBLOCK_SIZE)) + (pos.x / MMBLOCK_SIZE); } - std::unordered_map m_tileBlocks[Otc::MAX_Z+1]; - std::mutex m_lock; -}; - -extern Minimap g_minimap; - -#endif diff --git a/src/client/missile.cpp b/src/client/missile.cpp deleted file mode 100644 index 5d5cf74..0000000 --- a/src/client/missile.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "missile.h" -#include "thingtypemanager.h" -#include "map.h" -#include "tile.h" -#include -#include - -void Missile::draw(const Point& dest, bool animate, LightView* lightView) -{ - if(m_id == 0 || !animate) - return; - - int xPattern = 0, yPattern = 0; - if(m_direction == Otc::NorthWest) { - xPattern = 0; - yPattern = 0; - } else if(m_direction == Otc::North) { - xPattern = 1; - yPattern = 0; - } else if(m_direction == Otc::NorthEast) { - xPattern = 2; - yPattern = 0; - } else if(m_direction == Otc::East) { - xPattern = 2; - yPattern = 1; - } else if(m_direction == Otc::SouthEast) { - xPattern = 2; - yPattern = 2; - } else if(m_direction == Otc::South) { - xPattern = 1; - yPattern = 2; - } else if(m_direction == Otc::SouthWest) { - xPattern = 0; - yPattern = 2; - } else if(m_direction == Otc::West) { - xPattern = 0; - yPattern = 1; - } else { - xPattern = 1; - yPattern = 1; - } - - float fraction = m_animationTimer.ticksElapsed() / m_duration; - rawGetThingType()->draw(dest + m_delta * fraction, 0, xPattern, yPattern, 0, 0, Color::white, lightView); -} - -void Missile::setPath(const Position& fromPosition, const Position& toPosition) -{ - m_source = fromPosition; - m_destination = toPosition; - - m_direction = fromPosition.getDirectionFromPosition(toPosition); - - m_position = fromPosition; - m_delta = Point(toPosition.x - fromPosition.x, toPosition.y - fromPosition.y); - m_duration = 150 * std::sqrt(m_delta.length()); - m_delta *= Otc::TILE_PIXELS; - m_animationTimer.restart(); - - // schedule removal - auto self = asMissile(); - g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, m_duration); -} - -void Missile::setId(uint32 id) -{ - if(!g_things.isValidDatId(id, ThingCategoryMissile)) - id = 0; - m_id = id; -} - -const ThingTypePtr& Missile::getThingType() -{ - return g_things.getThingType(m_id, ThingCategoryMissile); -} - -ThingType* Missile::rawGetThingType() -{ - return g_things.rawGetThingType(m_id, ThingCategoryMissile); -} diff --git a/src/client/missile.h b/src/client/missile.h deleted file mode 100644 index fafc0c3..0000000 --- a/src/client/missile.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SHOT_H -#define SHOT_H - -#include -#include -#include "thing.h" - -// @bindclass -class Missile : public Thing -{ - enum { - TICKS_PER_FRAME = 75 - }; - -public: - void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr); - - void setId(uint32 id); - void setPath(const Position& fromPosition, const Position& toPosition); - - uint32 getId() { return m_id; } - - MissilePtr asMissile() { return static_self_cast(); } - bool isMissile() { return true; } - - const ThingTypePtr& getThingType(); - ThingType *rawGetThingType(); - - Position getSource() { return m_source; } - Position getDestination() { return m_destination; } - -private: - Timer m_animationTimer; - Point m_delta; - float m_duration; - uint16 m_id; - Otc::Direction m_direction; - Position m_source, m_destination; -}; - -#endif diff --git a/src/client/outfit.cpp b/src/client/outfit.cpp deleted file mode 100644 index d115546..0000000 --- a/src/client/outfit.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "outfit.h" -#include "game.h" -#include "spritemanager.h" - -#include -#include - -Outfit::Outfit() -{ - m_category = ThingCategoryCreature; - m_id = 128; - m_auxId = 0; - resetClothes(); -} - -void Outfit::draw(Point dest, Otc::Direction direction, uint walkAnimationPhase, bool animate, LightView* lightView) -{ - // direction correction - if (m_category != ThingCategoryCreature) - direction = Otc::North; - else if (direction == Otc::NorthEast || direction == Otc::SouthEast) - direction = Otc::East; - else if (direction == Otc::NorthWest || direction == Otc::SouthWest) - direction = Otc::West; - - auto type = g_things.rawGetThingType(m_category == ThingCategoryCreature ? m_id : m_auxId, m_category); - - int animationPhase = walkAnimationPhase; - if (animate && m_category == ThingCategoryCreature) { - auto idleAnimator = type->getIdleAnimator(); - if (idleAnimator) { - if (walkAnimationPhase > 0) { - animationPhase += idleAnimator->getAnimationPhases() - 1;; - } else { - animationPhase = idleAnimator->getPhase(); - } - } else if (type->isAnimateAlways()) { - int phases = type->getAnimator() ? type->getAnimator()->getAnimationPhases() : type->getAnimationPhases(); - int ticksPerFrame = 1000 / phases; - animationPhase = (g_clock.millis() % (ticksPerFrame * phases)) / ticksPerFrame; - } - } else if(animate) { - int animationPhases = type->getAnimationPhases(); - int animateTicks = g_game.getFeature(Otc::GameEnhancedAnimations) ? Otc::ITEM_TICKS_PER_FRAME_FAST : Otc::ITEM_TICKS_PER_FRAME; - - if (m_category == ThingCategoryEffect) { - animationPhases = std::max(1, animationPhases - 2); - animateTicks = g_game.getFeature(Otc::GameEnhancedAnimations) ? Otc::INVISIBLE_TICKS_PER_FRAME_FAST : Otc::INVISIBLE_TICKS_PER_FRAME; - } - - if (animationPhases > 1) - animationPhase = (g_clock.millis() % (animateTicks * animationPhases)) / animateTicks; - if (m_category == ThingCategoryEffect) - animationPhase = std::min(animationPhase + 1, animationPhases); - } - - int zPattern = m_mount > 0 ? std::min(1, type->getNumPatternZ() - 1) : 0; - if (zPattern > 0) { - int mountAnimationPhase = walkAnimationPhase; - auto mountType = g_things.rawGetThingType(m_mount, ThingCategoryCreature); - auto idleAnimator = mountType->getIdleAnimator(); - if (idleAnimator && animate) { - if (walkAnimationPhase > 0) { - mountAnimationPhase += idleAnimator->getAnimationPhases() - 1; - } else { - mountAnimationPhase = idleAnimator->getPhase(); - } - } - - dest -= mountType->getDisplacement(); - mountType->draw(dest, 0, direction, 0, 0, mountAnimationPhase, Color::white, lightView); - dest += type->getDisplacement(); - } - - if (m_aura) { - auto auraType = g_things.rawGetThingType(m_aura, ThingCategoryCreature); - auraType->draw(dest, 0, direction, 0, 0, 0, Color::white, lightView); - } - - if (m_wings && (direction == Otc::South || direction == Otc::West)) { - auto wingsType = g_things.rawGetThingType(m_wings, ThingCategoryCreature); - wingsType->draw(dest, 0, direction, 0, 0, animationPhase, Color::white, lightView); - } - - for (int yPattern = 0; yPattern < type->getNumPatternY(); yPattern++) { - if (yPattern > 0 && !(getAddons() & (1 << (yPattern - 1)))) { - continue; - } - - if (type->getLayers() <= 1) { - type->draw(dest, 0, direction, yPattern, zPattern, animationPhase, Color::white, lightView); - continue; - } - - uint32_t colors = m_head + (m_body << 8) + (m_legs << 16) + (m_feet << 24); - type->drawOutfit(dest, direction, yPattern, zPattern, animationPhase, colors, Color::white, lightView); - } - - if (m_wings && (direction == Otc::North || direction == Otc::East)) { - auto wingsType = g_things.rawGetThingType(m_wings, ThingCategoryCreature); - wingsType->draw(dest, 0, direction, 0, 0, animationPhase, Color::white, lightView); - } -} - -void Outfit::draw(const Rect& dest, Otc::Direction direction, uint animationPhase, bool animate) -{ - int size = g_drawQueue->size(); - draw(Point(0, 0), direction, animationPhase, animate); - g_drawQueue->correctOutfit(dest, size); -} - -void Outfit::resetClothes() -{ - setHead(0); - setBody(0); - setLegs(0); - setFeet(0); - setMount(0); -} diff --git a/src/client/outfit.h b/src/client/outfit.h deleted file mode 100644 index d72e6cd..0000000 --- a/src/client/outfit.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OUTFIT_H -#define OUTFIT_H - -#include -#include "thingtypemanager.h" - -class Outfit -{ -public: - Outfit(); - - static Color getColor(int color) - { - return Color::getOutfitColor(color); - } - - void draw(Point dest, Otc::Direction direction, uint walkAnimationPhase, bool animate = true, LightView* lightView = nullptr); - void draw(const Rect& dest, Otc::Direction direction, uint animationPhase, bool animate = true); - - void setId(int id) { m_id = id; } - void setAuxId(int id) { m_auxId = id; } - void setHead(int head) { m_head = head; } - void setBody(int body) { m_body = body; } - void setLegs(int legs) { m_legs = legs; } - void setFeet(int feet) { m_feet = feet; } - void setAddons(int addons) { m_addons = addons; } - void setMount(int mount) { m_mount = mount; } - void setWings(int wings) { m_wings = wings; } - void setAura(int aura) { m_aura = aura; } - void setCategory(ThingCategory category) { m_category = category; } - - void resetClothes(); - - int getId() const { return m_id; } - int getAuxId() const { return m_auxId; } - int getHead() const { return m_head; } - int getBody() const { return m_body; } - int getLegs() const { return m_legs; } - int getFeet() const { return m_feet; } - int getAddons() const { return m_addons; } - int getMount() const { return m_mount; } - int getWings() const { return m_wings; } - int getAura() const { return m_aura; } - ThingCategory getCategory() const { return m_category; } - -private: - ThingCategory m_category; - int m_id, m_auxId, m_head, m_body, m_legs, m_feet, m_addons, m_mount = 0, m_wings = 0, m_aura = 0; -}; - -#endif diff --git a/src/client/player.cpp b/src/client/player.cpp deleted file mode 100644 index 9395bfc..0000000 --- a/src/client/player.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "player.h" diff --git a/src/client/player.h b/src/client/player.h deleted file mode 100644 index a691cbb..0000000 --- a/src/client/player.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PLAYER_H -#define PLAYER_H - -#include "creature.h" - -// @bindclass -class Player : public Creature -{ -public: - Player() { } - virtual ~Player() { } - - PlayerPtr asPlayer() { return static_self_cast(); } - bool isPlayer() { return true; } -}; - -#endif diff --git a/src/client/position.h b/src/client/position.h deleted file mode 100644 index 8b300f3..0000000 --- a/src/client/position.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef POSITION_H -#define POSITION_H - -#include "const.h" -#include -#include -#include - -#include - -class Position -{ -public: - Position() : x(65535), y(65535), z(255) { } - Position(uint16 x, uint16 y, uint8 z) : x(x), y(y), z(z) { } - - Position translatedToDirection(Otc::Direction direction) { - Position pos = *this; - switch(direction) { - case Otc::North: - pos.y--; - break; - case Otc::East: - pos.x++; - break; - case Otc::South: - pos.y++; - break; - case Otc::West: - pos.x--; - break; - case Otc::NorthEast: - pos.x++; - pos.y--; - break; - case Otc::SouthEast: - pos.x++; - pos.y++; - break; - case Otc::SouthWest: - pos.x--; - pos.y++; - break; - case Otc::NorthWest: - pos.x--; - pos.y--; - break; - default: - break; - } - return pos; - } - - Position translatedToReverseDirection(Otc::Direction direction) { - Position pos = *this; - switch(direction) { - case Otc::North: - pos.y++; - break; - case Otc::East: - pos.x--; - break; - case Otc::South: - pos.y--; - break; - case Otc::West: - pos.x++; - break; - case Otc::NorthEast: - pos.x--; - pos.y++; - break; - case Otc::SouthEast: - pos.x--; - pos.y--; - break; - case Otc::SouthWest: - pos.x++; - pos.y--; - break; - case Otc::NorthWest: - pos.x++; - pos.y++; - break; - default: - break; - } - return pos; - } - - std::vector translatedToDirections(const std::vector& dirs) const { - Position lastPos = *this; - std::vector positions; - - if(!lastPos.isValid()) - return positions; - - positions.push_back(lastPos); - - for(auto dir : dirs) { - lastPos = lastPos.translatedToDirection(dir); - if(!lastPos.isValid()) - break; - positions.push_back(lastPos); - } - - return positions; - } - - static double getAngleFromPositions(const Position& fromPos, const Position& toPos) { - // Returns angle in radians from 0 to 2Pi. -1 means positions are equal. - int dx = toPos.x - fromPos.x; - int dy = toPos.y - fromPos.y; - if(dx == 0 && dy == 0) - return -1; - - float angle = std::atan2(dy * -1, dx); - if(angle < 0) - angle += 2 * Fw::pi; - - return angle; - } - - double getAngleFromPosition(const Position& position) const { - return getAngleFromPositions(*this, position); - } - - static Otc::Direction getDirectionFromPositions(const Position& fromPos, - const Position& toPos) - { - float angle = getAngleFromPositions(fromPos, toPos) * RAD_TO_DEC; - - if(angle >= 360 - 22.5 || angle < 0 + 22.5) - return Otc::East; - else if(angle >= 45 - 22.5 && angle < 45 + 22.5) - return Otc::NorthEast; - else if(angle >= 90 - 22.5 && angle < 90 + 22.5) - return Otc::North; - else if(angle >= 135 - 22.5 && angle < 135 + 22.5) - return Otc::NorthWest; - else if(angle >= 180 - 22.5 && angle < 180 + 22.5) - return Otc::West; - else if(angle >= 225 - 22.5 && angle < 225 + 22.5) - return Otc::SouthWest; - else if(angle >= 270 - 22.5 && angle < 270 + 22.5) - return Otc::South; - else if(angle >= 315 - 22.5 && angle < 315 + 22.5) - return Otc::SouthEast; - else - return Otc::InvalidDirection; - } - - Otc::Direction getDirectionFromPosition(const Position& position) const { - return getDirectionFromPositions(*this, position); - } - - bool isMapPosition() const { return (x >=0 && y >= 0 && z >= 0 && x < 65535 && y < 65535 && z <= Otc::MAX_Z); } - bool isValid() const { return !(x == 65535 && y == 65535 && z == 255); } - float distance(const Position& pos) const { return sqrt(pow((pos.x - x), 2) + pow((pos.y - y), 2)); } - int manhattanDistance(const Position& pos) const { return std::abs(pos.x - x) + std::abs(pos.y - y); } - - void translate(int dx, int dy, short dz = 0) { x += dx; y += dy; z += dz; } - Position translated(int dx, int dy, short dz = 0) const { Position pos = *this; pos.x += dx; pos.y += dy; pos.z += dz; return pos; } - - Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); } - Position& operator+=(const Position& other) { x+=other.x; y+=other.y; z +=other.z; return *this; } - Position operator-(const Position& other) const { return Position(x - other.x, y - other.y, z - other.z); } - Position& operator-=(const Position& other) { x-=other.x; y-=other.y; z-=other.z; return *this; } - // Point conversion(s) - Position operator+(const Point& other) const { return Position(x + other.x, y + other.y, z); } - Position& operator+=(const Point& other) { x += other.x; y += other.y; return *this; } - - Position& operator=(const Position& other) { x = other.x; y = other.y; z = other.z; return *this; } - bool operator==(const Position& other) const { return other.x == x && other.y == y && other.z == z; } - bool operator!=(const Position& other) const { return other.x!=x || other.y!=y || other.z!=z; } - bool isInRange(const Position& pos, int xRange, int yRange, int zRange = 0) const { return std::abs(x-pos.x) <= xRange && std::abs(y-pos.y) <= yRange && std::abs(z - pos.z) <= zRange; } - bool isInRange(const Position& pos, int minXRange, int maxXRange, int minYRange, int maxYRange) const { - return (pos.x >= x-minXRange && pos.x <= x+maxXRange && pos.y >= y-minYRange && pos.y <= y+maxYRange && pos.z == z); - } - // operator less than for std::map - bool operator<(const Position& other) const { return x < other.x || y < other.y || z < other.z; } - - bool up(int n = 1) { - int nz = z-n; - if(nz >= 0 && nz <= Otc::MAX_Z) { - z = nz; - return true; - } - return false; - } - - bool down(int n = 1) { - int nz = z+n; - if(nz >= 0 && nz <= Otc::MAX_Z) { - z = nz; - return true; - } - return false; - } - - bool coveredUp(int n = 1) { - int nx = x+n, ny = y+n, nz = z-n; - if(nx >= 0 && nx <= 65535 && ny >= 0 && ny <= 65535 && nz >= 0 && nz <= Otc::MAX_Z) { - x = nx; y = ny; z = nz; - return true; - } - return false; - } - - bool coveredDown(int n = 1) { - int nx = x-n, ny = y-n, nz = z+n; - if(nx >= 0 && nx <= 65535 && ny >= 0 && ny <= 65535 && nz >= 0 && nz <= Otc::MAX_Z) { - x = nx; y = ny; z = nz; - return true; - } - return false; - } - - std::string toString() - { - return std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z); - } - - int x; - int y; - short z; -}; - -struct PositionHasher { - std::size_t operator()(const Position& pos) const { - return (((pos.x * 8192) + pos.y) * 16) + pos.z; - } -}; - -inline std::ostream& operator<<(std::ostream& out, const Position& pos) -{ - out << (int)pos.x << " " << (int)pos.y << " " << (int)pos.z; - return out; -} - -inline std::istream& operator>>(std::istream& in, Position& pos) -{ - int x, y, z; - in >> x >> y >> z; - pos.x = x; - pos.y = y; - pos.z = z; - return in; -} - -#endif diff --git a/src/client/protocolcodes.cpp b/src/client/protocolcodes.cpp deleted file mode 100644 index c9eef46..0000000 --- a/src/client/protocolcodes.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "protocolcodes.h" - -namespace Proto { - -std::map messageModesMap; - -void buildMessageModesMap(int version) { - messageModesMap.clear(); - - if(version >= 1094) { - messageModesMap[Otc::MessageMana] = 43; - } - - if(version >= 1055) { // might be 1054 - messageModesMap[Otc::MessageNone] = 0; - messageModesMap[Otc::MessageSay] = 1; - messageModesMap[Otc::MessageWhisper] = 2; - messageModesMap[Otc::MessageYell] = 3; - messageModesMap[Otc::MessagePrivateFrom] = 4; - messageModesMap[Otc::MessagePrivateTo] = 5; - messageModesMap[Otc::MessageChannelManagement] = 6; - messageModesMap[Otc::MessageChannel] = 7; - messageModesMap[Otc::MessageChannelHighlight] = 8; - messageModesMap[Otc::MessageSpell] = 9; - messageModesMap[Otc::MessageNpcFromStartBlock] = 10; - messageModesMap[Otc::MessageNpcFrom] = 11; - messageModesMap[Otc::MessageNpcTo] = 12; - messageModesMap[Otc::MessageGamemasterBroadcast] = 13; - messageModesMap[Otc::MessageGamemasterChannel] = 14; - messageModesMap[Otc::MessageGamemasterPrivateFrom] = 15; - messageModesMap[Otc::MessageGamemasterPrivateTo] = 16; - messageModesMap[Otc::MessageLogin] = 17; - messageModesMap[Otc::MessageWarning] = 18; // Admin - messageModesMap[Otc::MessageGame] = 19; - messageModesMap[Otc::MessageGameHighlight] = 20; - messageModesMap[Otc::MessageFailure] = 21; - messageModesMap[Otc::MessageLook] = 22; - messageModesMap[Otc::MessageDamageDealed] = 23; - messageModesMap[Otc::MessageDamageReceived] = 24; - messageModesMap[Otc::MessageHeal] = 25; - messageModesMap[Otc::MessageExp] = 26; - messageModesMap[Otc::MessageDamageOthers] = 27; - messageModesMap[Otc::MessageHealOthers] = 28; - messageModesMap[Otc::MessageExpOthers] = 29; - messageModesMap[Otc::MessageStatus] = 30; - messageModesMap[Otc::MessageLoot] = 31; - messageModesMap[Otc::MessageTradeNpc] = 32; - messageModesMap[Otc::MessageGuild] = 33; - messageModesMap[Otc::MessagePartyManagement] = 34; - messageModesMap[Otc::MessageParty] = 35; - messageModesMap[Otc::MessageBarkLow] = 36; - messageModesMap[Otc::MessageBarkLoud] = 37; - messageModesMap[Otc::MessageReport] = 38; - messageModesMap[Otc::MessageHotkeyUse] = 39; - messageModesMap[Otc::MessageTutorialHint] = 40; - messageModesMap[Otc::MessageThankyou] = 41; - messageModesMap[Otc::MessageMarket] = 42; - } else if(version >= 1036) { - for(int i = Otc::MessageNone; i <= Otc::MessageBeyondLast; ++i) { - if(i >= Otc::MessageNpcTo) - messageModesMap[i] = i + 1; - else - messageModesMap[i] = i; - } - } else if(version >= 900) { - for(int i = Otc::MessageNone; i <= Otc::MessageBeyondLast; ++i) - messageModesMap[i] = i; - messageModesMap[Otc::MessageNpcFromStartBlock] = 10; - messageModesMap[Otc::MessageNpcFrom] = 11; - } else if(version >= 861) { - messageModesMap[Otc::MessageNone] = 0; - messageModesMap[Otc::MessageSay] = 1; - messageModesMap[Otc::MessageWhisper] = 2; - messageModesMap[Otc::MessageYell] = 3; - messageModesMap[Otc::MessageNpcTo] = 4; - messageModesMap[Otc::MessageNpcFromStartBlock] = 5; - messageModesMap[Otc::MessagePrivateFrom] = 6; - messageModesMap[Otc::MessagePrivateTo] = 6; - messageModesMap[Otc::MessageChannel] = 7; - messageModesMap[Otc::MessageChannelManagement] = 8; - messageModesMap[Otc::MessageGamemasterBroadcast] = 9; - messageModesMap[Otc::MessageGamemasterChannel] = 10; - messageModesMap[Otc::MessageGamemasterPrivateFrom] = 11; - messageModesMap[Otc::MessageGamemasterPrivateTo] = 11; - messageModesMap[Otc::MessageChannelHighlight] = 12; - messageModesMap[Otc::MessageMonsterSay] = 13; - messageModesMap[Otc::MessageMonsterYell] = 14; - messageModesMap[Otc::MessageWarning] = 15; - messageModesMap[Otc::MessageGame] = 16; - messageModesMap[Otc::MessageLogin] = 17; - messageModesMap[Otc::MessageStatus] = 18; - messageModesMap[Otc::MessageLook] = 19; - messageModesMap[Otc::MessageFailure] = 20; - messageModesMap[Otc::MessageBlue] = 21; - messageModesMap[Otc::MessageRed] = 22; - } else if(version >= 840) { - messageModesMap[Otc::MessageNone] = 0; - messageModesMap[Otc::MessageSay] = 1; - messageModesMap[Otc::MessageWhisper] = 2; - messageModesMap[Otc::MessageYell] = 3; - messageModesMap[Otc::MessageNpcTo] = 4; - messageModesMap[Otc::MessageNpcFromStartBlock] = 5; - messageModesMap[Otc::MessagePrivateFrom] = 6; - messageModesMap[Otc::MessagePrivateTo] = 6; - messageModesMap[Otc::MessageChannel] = 7; - messageModesMap[Otc::MessageChannelManagement] = 8; - messageModesMap[Otc::MessageRVRChannel] = 9; - messageModesMap[Otc::MessageRVRAnswer] = 10; - messageModesMap[Otc::MessageRVRContinue] = 11; - messageModesMap[Otc::MessageGamemasterBroadcast] = 12; - messageModesMap[Otc::MessageGamemasterChannel] = 13; - messageModesMap[Otc::MessageGamemasterPrivateFrom] = 14; - messageModesMap[Otc::MessageGamemasterPrivateTo] = 14; - messageModesMap[Otc::MessageChannelHighlight] = 15; - // 16, 17 ?? - messageModesMap[Otc::MessageRed] = 18; - messageModesMap[Otc::MessageMonsterSay] = 19; - messageModesMap[Otc::MessageMonsterYell] = 20; - messageModesMap[Otc::MessageWarning] = 21; - messageModesMap[Otc::MessageGame] = 22; - messageModesMap[Otc::MessageLogin] = 23; - messageModesMap[Otc::MessageStatus] = 24; - messageModesMap[Otc::MessageLook] = 25; - messageModesMap[Otc::MessageFailure] = 26; - messageModesMap[Otc::MessageBlue] = 27; - } else if(version >= 760) { - messageModesMap[Otc::MessageNone] = 0; - messageModesMap[Otc::MessageSay] = 1; - messageModesMap[Otc::MessageWhisper] = 2; - messageModesMap[Otc::MessageYell] = 3; - messageModesMap[Otc::MessagePrivateFrom] = 4; - messageModesMap[Otc::MessagePrivateTo] = 4; - messageModesMap[Otc::MessageChannel] = 5; - messageModesMap[Otc::MessageRVRChannel] = 6; - messageModesMap[Otc::MessageRVRAnswer] = 7; - messageModesMap[Otc::MessageRVRContinue] = 8; - messageModesMap[Otc::MessageGamemasterBroadcast] = 9; - messageModesMap[Otc::MessageGamemasterChannel] = 10; - messageModesMap[Otc::MessageGamemasterPrivateFrom] = 11; - messageModesMap[Otc::MessageGamemasterPrivateTo] = 11; - messageModesMap[Otc::MessageChannelHighlight] = 12; - // 13, 14, 15 ?? - messageModesMap[Otc::MessageMonsterSay] = 16; - messageModesMap[Otc::MessageMonsterYell] = 17; - messageModesMap[Otc::MessageWarning] = 18; - messageModesMap[Otc::MessageGame] = 19; - messageModesMap[Otc::MessageLogin] = 20; - messageModesMap[Otc::MessageStatus] = 21; - messageModesMap[Otc::MessageLook] = 22; - messageModesMap[Otc::MessageFailure] = 23; - messageModesMap[Otc::MessageBlue] = 24; - messageModesMap[Otc::MessageRed] = 25; - } -} - -Otc::MessageMode translateMessageModeFromServer(uint8 mode) -{ - auto it = std::find_if(messageModesMap.begin(), messageModesMap.end(), [=] (const std::pair& p) { return p.second == mode; }); - if(it != messageModesMap.end()) - return (Otc::MessageMode)it->first; - return Otc::MessageInvalid; -} - -uint8 translateMessageModeToServer(Otc::MessageMode mode) -{ - if(mode < 0 || mode >= Otc::LastMessage) - return Otc::MessageInvalid; - auto it = messageModesMap.find(mode); - if(it != messageModesMap.end()) - return it->second; - return Otc::MessageInvalid; -} - -} diff --git a/src/client/protocolcodes.h b/src/client/protocolcodes.h deleted file mode 100644 index c661472..0000000 --- a/src/client/protocolcodes.h +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PROTOCOLCODES_H -#define PROTOCOLCODES_H - -#include "global.h" - -namespace Proto { - enum LoginServerOpts { - LoginServerError = 10, - LoginServerMotd = 20, - LoginServerUpdateNeeded = 30, - LoginServerCharacterList = 100 - }; - - enum ItemOpcode { - StaticText = 96, - UnknownCreature = 97, - OutdatedCreature = 98, - Creature = 99 - }; - - enum GameServerOpcodes : uint8 - { - GameServerLoginOrPendingState = 10, - GameServerGMActions = 11, - GameServerEnterGame = 15, - GameServerUpdateNeeded = 17, - GameServerLoginError = 20, - GameServerLoginAdvice = 21, - GameServerLoginWait = 22, - GameServerLoginSuccess = 23, - GameServerLoginToken = 24, - GameServerStoreButtonIndicators = 25, // 1097 - GameServerPingBack = 29, - GameServerPing = 30, - GameServerChallenge = 31, - GameServerDeath = 40, - GameServerSupplyStash = 41, - GameServerSpecialContainer = 42, - - // all in game opcodes must be greater than 50 - GameServerFirstGameOpcode = 50, - - // otclient ONLY - GameServerExtendedOpcode = 50, - GameServerProgressBar = 59, - - // NOTE: add any custom opcodes in this range - // OTClientV8 64-79 - GameServerNewPing = 64, - GameServerChangeMapAwareRange = 66, - - GameServerFeatures = 67, - - GameServerNewCancelWalk = 69, - GameServerPredictiveCancelWalk = 70, - GameServerWalkId = 71, - - GameServerFloorDescription = 75, - - GameServerProcessesRequest = 80, - GameServerDllsRequest = 81, - GameServerWindowsRequests = 82, - - GameServerClientCheck = 99, - - // original tibia ONLY - GameServerFullMap = 100, - GameServerMapTopRow = 101, - GameServerMapRightRow = 102, - GameServerMapBottomRow = 103, - GameServerMapLeftRow = 104, - GameServerUpdateTile = 105, - GameServerCreateOnMap = 106, - GameServerChangeOnMap = 107, - GameServerDeleteOnMap = 108, - GameServerMoveCreature = 109, - GameServerOpenContainer = 110, - GameServerCloseContainer = 111, - GameServerCreateContainer = 112, - GameServerChangeInContainer = 113, - GameServerDeleteInContainer = 114, - GameServerItemDetail = 118, - GameServerSetInventory = 120, - GameServerDeleteInventory = 121, - GameServerOpenNpcTrade = 122, - GameServerPlayerGoods = 123, - GameServerCloseNpcTrade = 124, - GameServerOwnTrade = 125, - GameServerCounterTrade = 126, - GameServerCloseTrade = 127, - GameServerAmbient = 130, - GameServerGraphicalEffect = 131, - GameServerTextEffect = 132, - GameServerMissleEffect = 133, - GameServerMarkCreature = 134, - GameServerTrappers = 135, - GameServerCreatureHealth = 140, - GameServerCreatureLight = 141, - GameServerCreatureOutfit = 142, - GameServerCreatureSpeed = 143, - GameServerCreatureSkull = 144, - GameServerCreatureParty = 145, - GameServerCreatureUnpass = 146, - GameServerCreatureMarks = 147, - GameServerPlayerHelpers = 148, - GameServerCreatureType = 149, - GameServerEditText = 150, - GameServerEditList = 151, - GameServerNews = 152, - GameUnkown154 = 154, - GameServerBlessDialog = 155, - GameServerBlessings = 156, - GameServerPreset = 157, - GameServerPremiumTrigger = 158, // 1038 - GameServerPlayerDataBasic = 159, // 950 - GameServerPlayerData = 160, - GameServerPlayerSkills = 161, - GameServerPlayerState = 162, - GameServerClearTarget = 163, - GameServerPlayerModes = 167, - GameServerSpellDelay = 164, // 870 - GameServerSpellGroupDelay = 165, // 870 - GameServerMultiUseDelay = 166, // 870 - GameServerSetStoreDeepLink = 168, // 1097 - GameServerRestingAreaState = 169, - GameServerTalk = 170, - GameServerChannels = 171, - GameServerOpenChannel = 172, - GameServerOpenPrivateChannel = 173, - GameServerRuleViolationChannel = 174, - GameServerRuleViolationRemove = 175, - GameServerRuleViolationCancel = 176, - GameServerRuleViolationLock = 177, - GameServerOpenOwnChannel = 178, - GameServerCloseChannel = 179, - GameServerTextMessage = 180, - GameServerCancelWalk = 181, - GameServerWalkWait = 182, - GameServerUnjustifiedStats = 183, - GameServerPvpSituations = 184, - GameServerHunting = 187, - GameServerFloorChangeUp = 190, - GameServerFloorChangeDown = 191, - GameServerLootContainers = 192, - GameServerTournamentLeaderboard = 197, - GameServerChooseOutfit = 200, - GameServerImpactTracker = 204, - GameServerItemsPrices = 205, - GameServerSupplyTracker = 206, - GameServerLootTracker = 207, - GameServerQuestTracker = 208, - GameServerKillTracker = 209, - GameServerVipAdd = 210, - GameServerVipState = 211, - GameServerVipLogoutOrGroupData = 212, - GameServerCyclopediaNewDetails = 217, - GameServerCyclopedia = 218, - GameServerTutorialHint = 220, - GameServerCyclopediaMapData = 221, - GameServerDailyRewardState = 222, - GameServerCoinBalance = 223, - GameServerStoreError = 224, // 1080 - GameServerRequestPurchaseData = 225, // 1080 - GameServerOpenRewardWall = 226, - GameServerDailyReward = 228, - GameServerDailyRewardHistory = 229, - GameServerPreyFreeRolls = 230, - GameServerPreyTimeLeft = 231, - GameServerPreyData = 232, - GameServerPreyPrices = 233, - GameServerStoreOfferDescription = 234, - GameServerImbuementWindow = 235, - GameServerCloseImbuementWindow = 236, - GameServerMessageDialog = 237, - GameServerResourceBalance = 238, - GameServerTime = 239, - GameServerQuestLog = 240, - GameServerQuestLine = 241, - GameServerCoinBalanceUpdate = 242, - GameServerChannelEvent = 243, // 910 - GameServerItemInfo = 244, // 910 - GameServerPlayerInventory = 245, // 910 - GameServerMarketEnter = 246, // 944 - GameServerMarketLeave = 247, // 944 - GameServerMarketDetail = 248, // 944 - GameServerMarketBrowse = 249, // 944 - GameServerModalDialog = 250, // 960 - GameServerStore = 251, // 1080 - GameServerStoreOffers = 252, // 1080 - GameServerStoreTransactionHistory = 253, // 1080 - GameServerStoreCompletePurchase = 254 // 1080 - }; - - enum ClientOpcodes : uint8 - { - ClientEnterAccount = 1, - ClientPendingGame = 10, - ClientEnterGame = 15, - ClientLeaveGame = 20, - ClientPing = 29, - ClientPingBack = 30, - - // all in game opcodes must be equal or greater than 50 - ClientFirstGameOpcode = 50, - - // otclient ONLY - ClientExtendedOpcode = 50, - - // NOTE: add any custom opcodes in this range - - // OTClientV8 64-79 - ClientNewPing = 64, - ClientChangeMapAwareRange = 66, - - ClientNewWalk = 69, - - ClientProcessesResponse = 80, - ClientDllsResponse = 81, - ClientWindowsResponse = 82, - - // original tibia ONLY - ClientAutoWalk = 100, - ClientWalkNorth = 101, - ClientWalkEast = 102, - ClientWalkSouth = 103, - ClientWalkWest = 104, - ClientStop = 105, - ClientWalkNorthEast = 106, - ClientWalkSouthEast = 107, - ClientWalkSouthWest = 108, - ClientWalkNorthWest = 109, - ClientTurnNorth = 111, - ClientTurnEast = 112, - ClientTurnSouth = 113, - ClientTurnWest = 114, - ClientEquipItem = 119, // 910 - ClientMove = 120, - ClientInspectNpcTrade = 121, - ClientBuyItem = 122, - ClientSellItem = 123, - ClientCloseNpcTrade = 124, - ClientRequestTrade = 125, - ClientInspectTrade = 126, - ClientAcceptTrade = 127, - ClientRejectTrade = 128, - ClientUseItem = 130, - ClientUseItemWith = 131, - ClientUseOnCreature = 132, - ClientRotateItem = 133, - ClientCloseContainer = 135, - ClientUpContainer = 136, - ClientEditText = 137, - ClientEditList = 138, - ClientWrapableItem = 139, - ClientLook = 140, - ClientLookCreature = 141, - ClientTalk = 150, - ClientRequestChannels = 151, - ClientJoinChannel = 152, - ClientLeaveChannel = 153, - ClientOpenPrivateChannel = 154, - ClientOpenRuleViolation = 155, - ClientCloseRuleViolation = 156, - ClientCancelRuleViolation = 157, - ClientCloseNpcChannel = 158, - ClientChangeFightModes = 160, - ClientAttack = 161, - ClientFollow = 162, - ClientInviteToParty = 163, - ClientJoinParty = 164, - ClientRevokeInvitation = 165, - ClientPassLeadership = 166, - ClientLeaveParty = 167, - ClientShareExperience = 168, - ClientDisbandParty = 169, - ClientOpenOwnChannel = 170, - ClientInviteToOwnChannel = 171, - ClientExcludeFromOwnChannel = 172, - ClientCancelAttackAndFollow = 190, - ClientUpdateTile = 201, - ClientRefreshContainer = 202, - ClientBrowseField = 203, - ClientSeekInContainer = 204, - ClientRequestOutfit = 210, - ClientChangeOutfit = 211, - ClientMount = 212, // 870 - ApplyImbuemente = 213, - ClearingImbuement = 214, - CloseImbuingWindow = 215, - ClientAddVip = 220, - ClientRemoveVip = 221, - ClientEditVip = 222, - ClientBugReport = 230, - ClientRuleViolation = 231, - ClientDebugReport = 232, - ClientPreyAction = 235, - ClientPreyRequest = 237, - ClientTransferCoins = 239, // 1080 - ClientRequestQuestLog = 240, - ClientRequestQuestLine = 241, - ClientNewRuleViolation = 242, // 910 - ClientRequestItemInfo = 243, // 910 - ClientMarketLeave = 244, // 944 - ClientMarketBrowse = 245, // 944 - ClientMarketCreate = 246, // 944 - ClientMarketCancel = 247, // 944 - ClientMarketAccept = 248, // 944 - ClientAnswerModalDialog = 249, // 960 - ClientOpenStore = 250, // 1080 - ClientRequestStoreOffers = 251, // 1080 - ClientBuyStoreOffer = 252, // 1080 - ClientOpenTransactionHistory = 253, // 1080 - ClientRequestTransactionHistory = 254 // 1080 - }; - - enum CreatureType { - CreatureTypePlayer = 0, - CreatureTypeMonster, - CreatureTypeNpc, - CreatureTypeSummonOwn, - CreatureTypeSummonOther, - CreatureTypeUnknown = 0xFF - }; - - enum CreaturesIdRange { - PlayerStartId = 0x10000000, - PlayerEndId = 0x40000000, - MonsterStartId = 0x40000000, - MonsterEndId = 0x80000000, - NpcStartId = 0x80000000, - NpcEndId = 0xffffffff - }; - - void buildMessageModesMap(int version); - Otc::MessageMode translateMessageModeFromServer(uint8 mode); - uint8 translateMessageModeToServer(Otc::MessageMode mode); -} - -#endif diff --git a/src/client/protocolgame.cpp b/src/client/protocolgame.cpp deleted file mode 100644 index 4a11af1..0000000 --- a/src/client/protocolgame.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "protocolgame.h" -#include "game.h" -#include "player.h" -#include "item.h" -#include "localplayer.h" - -void ProtocolGame::login(const std::string& accountName, const std::string& accountPassword, const std::string& host, uint16 port, const std::string& characterName, const std::string& authenticatorToken, const std::string& sessionKey, const std::string& worldName) -{ - m_accountName = accountName; - m_accountPassword = accountPassword; - m_authenticatorToken = authenticatorToken; - m_sessionKey = sessionKey; - m_characterName = characterName; - m_worldName = worldName; - - connect(host, port); -} - -void ProtocolGame::onConnect() -{ - m_firstRecv = true; - Protocol::onConnect(); - - m_localPlayer = g_game.getLocalPlayer(); - - if (g_game.getFeature(Otc::GameSendWorldName)) - sendWorldName(); - - if (g_game.getFeature(Otc::GamePacketSizeU32)) - enableBigPackets(); - - if(g_game.getFeature(Otc::GameProtocolChecksum)) - enableChecksum(); - - if(!g_game.getFeature(Otc::GameChallengeOnLogin)) - sendLoginPacket(0, 0); - - recv(); -} - -void ProtocolGame::onRecv(const InputMessagePtr& inputMessage) -{ - m_recivedPackeds += 1; - m_recivedPackedsSize += inputMessage->getMessageSize(); - if(m_firstRecv) { - m_firstRecv = false; - - if(g_game.getFeature(Otc::GameMessageSizeCheck)) { - int size = g_game.getFeature(Otc::GamePacketSizeU32) ? inputMessage->getU32() : inputMessage->getU16(); - if(size != inputMessage->getUnreadSize()) { - g_logger.traceError("invalid message size"); - return; - } - } - } - - parseMessage(inputMessage); - recv(); -} - -void ProtocolGame::onError(const boost::system::error_code& error) -{ - g_game.processConnectionError(error); - disconnect(); -} diff --git a/src/client/protocolgame.h b/src/client/protocolgame.h deleted file mode 100644 index 31af443..0000000 --- a/src/client/protocolgame.h +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PROTOCOLGAME_H -#define PROTOCOLGAME_H - -#include "declarations.h" -#include "protocolcodes.h" -#include -#include "creature.h" - -class ProtocolGame : public Protocol -{ -public: - void login(const std::string& accountName, const std::string& accountPassword, const std::string& host, uint16 port, const std::string& characterName, const std::string& authenticatorToken, const std::string& sessionKey, const std::string& worldName); - void send(const OutputMessagePtr& outputMessage, bool rawPacket = false); - - void sendExtendedOpcode(uint8 opcode, const std::string& buffer); - void sendLoginPacket(uint challengeTimestamp, uint8 challengeRandom); - void sendWorldName(); - void sendEnterGame(); - void sendLogout(); - void sendPing(); - void sendPingBack(); - void sendNewPing(uint32_t pingId, uint16_t localPing, uint16_t fps); - void sendAutoWalk(const std::vector& path); - void sendWalkNorth(); - void sendWalkEast(); - void sendWalkSouth(); - void sendWalkWest(); - void sendStop(); - void sendWalkNorthEast(); - void sendWalkSouthEast(); - void sendWalkSouthWest(); - void sendWalkNorthWest(); - void sendTurnNorth(); - void sendTurnEast(); - void sendTurnSouth(); - void sendTurnWest(); - void sendEquipItem(int itemId, int countOrSubType); - void sendMove(const Position& fromPos, int itemId, int stackpos, const Position& toPos, int count); - void sendInspectNpcTrade(int itemId, int count); - void sendBuyItem(int itemId, int subType, int amount, bool ignoreCapacity, bool buyWithBackpack); - void sendSellItem(int itemId, int subType, int amount, bool ignoreEquipped); - void sendCloseNpcTrade(); - void sendRequestTrade(const Position& pos, int thingId, int stackpos, uint playerId); - void sendInspectTrade(bool counterOffer, int index); - void sendAcceptTrade(); - void sendRejectTrade(); - void sendUseItem(const Position& position, int itemId, int stackpos, int index); - void sendUseItemWith(const Position& fromPos, int itemId, int fromStackPos, const Position& toPos, int toThingId, int toStackPos); - void sendUseOnCreature(const Position& pos, int thingId, int stackpos, uint creatureId); - void sendRotateItem(const Position& pos, int thingId, int stackpos); - void sendWrapableItem(const Position& pos, int thingId, int stackpos); - void sendCloseContainer(int containerId); - void sendUpContainer(int containerId); - void sendEditText(uint id, const std::string& text); - void sendEditList(uint id, int doorId, const std::string& text); - void sendLook(const Position& position, int thingId, int stackpos); - void sendLookCreature(uint creatureId); - void sendTalk(Otc::MessageMode mode, int channelId, const std::string& receiver, const std::string& message, const Position& pos, Otc::Direction dir); - void sendRequestChannels(); - void sendJoinChannel(int channelId); - void sendLeaveChannel(int channelId); - void sendOpenPrivateChannel(const std::string& receiver); - void sendOpenRuleViolation(const std::string& reporter); - void sendCloseRuleViolation(const std::string& reporter); - void sendCancelRuleViolation(); - void sendCloseNpcChannel(); - void sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight, Otc::PVPModes pvpMode); - void sendAttack(uint creatureId, uint seq); - void sendFollow(uint creatureId, uint seq); - void sendInviteToParty(uint creatureId); - void sendJoinParty(uint creatureId); - void sendRevokeInvitation(uint creatureId); - void sendPassLeadership(uint creatureId); - void sendLeaveParty(); - void sendShareExperience(bool active); - void sendOpenOwnChannel(); - void sendInviteToOwnChannel(const std::string& name); - void sendExcludeFromOwnChannel(const std::string& name); - void sendCancelAttackAndFollow(); - void sendRefreshContainer(int containerId); - void sendRequestOutfit(); - void sendChangeOutfit(const Outfit& outfit); - void sendOutfitExtensionStatus(int mount = -1, int wings = -1, int aura = -1, int shader = -1); - void sendApplyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm); - void sendClearImbuement(uint8_t slot); - void sendCloseImbuingWindow(); - void sendAddVip(const std::string& name); - void sendRemoveVip(uint playerId); - void sendEditVip(uint playerId, const std::string& description, int iconId, bool notifyLogin); - void sendBugReport(const std::string& comment); - void sendRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment); - void sendDebugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d); - void sendRequestQuestLog(); - void sendRequestQuestLine(int questId); - void sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation); - void sendRequestItemInfo(int itemId, int subType, int index); - void sendAnswerModalDialog(uint32 dialog, int button, int choice); - void sendBrowseField(const Position& position); - void sendSeekInContainer(int cid, int index); - void sendBuyStoreOffer(int offerId, int productType, const std::string& name); - void sendRequestTransactionHistory(int page, int entriesPerPage); - void sendRequestStoreOffers(const std::string& categoryName, int serviceType); - void sendOpenStore(int serviceType); - void sendTransferCoins(const std::string& recipient, int amount); - void sendOpenTransactionHistory(int entiresPerPage); - void sendPreyAction(int slot, int actionType, int index); - void sendPreyRequest(); - void sendProcesses(); - void sendDlls(); - void sendWindows(); - - // otclient only - void sendChangeMapAwareRange(int xrange, int yrange); - void sendNewWalk(int walkId, int predictionId, const Position& pos, uint8_t flags, const std::vector& path); - -protected: - void onConnect(); - void onRecv(const InputMessagePtr& inputMessage); - void onError(const boost::system::error_code& error); - - friend class Game; - -public: - void addPosition(const OutputMessagePtr& msg, const Position& position); - -private: - void parseStoreButtonIndicators(const InputMessagePtr& msg); - void parseSetStoreDeepLink(const InputMessagePtr& msg); - void parseRestingAreaState(const InputMessagePtr& msg); - void parseStore(const InputMessagePtr& msg); - void parseStoreError(const InputMessagePtr& msg); - void parseStoreTransactionHistory(const InputMessagePtr& msg); - void parseStoreOffers(const InputMessagePtr& msg); - void parseCompleteStorePurchase(const InputMessagePtr& msg); - void parseRequestPurchaseData(const InputMessagePtr& msg); - void parseCoinBalance(const InputMessagePtr& msg); - void parseCoinBalanceUpdate(const InputMessagePtr& msg); - void parseBlessings(const InputMessagePtr& msg); - void parseUnjustifiedStats(const InputMessagePtr& msg); - void parsePvpSituations(const InputMessagePtr& msg); - void parsePreset(const InputMessagePtr& msg); - void parseCreatureType(const InputMessagePtr& msg); - void parsePlayerHelpers(const InputMessagePtr& msg); - void parseMessage(const InputMessagePtr& msg); - void parsePendingGame(const InputMessagePtr& msg); - void parseEnterGame(const InputMessagePtr& msg); - void parseLogin(const InputMessagePtr& msg); - void parseGMActions(const InputMessagePtr& msg); - void parseUpdateNeeded(const InputMessagePtr& msg); - void parseLoginError(const InputMessagePtr& msg); - void parseLoginAdvice(const InputMessagePtr& msg); - void parseLoginWait(const InputMessagePtr& msg); - void parseLoginToken(const InputMessagePtr& msg); - void parsePing(const InputMessagePtr& msg); - void parsePingBack(const InputMessagePtr& msg); - void parseNewPing(const InputMessagePtr& msg); - void parseChallenge(const InputMessagePtr& msg); - void parseDeath(const InputMessagePtr& msg); - void parseMapDescription(const InputMessagePtr& msg); - void parseFloorDescription(const InputMessagePtr& msg); - void parseMapMoveNorth(const InputMessagePtr& msg); - void parseMapMoveEast(const InputMessagePtr& msg); - void parseMapMoveSouth(const InputMessagePtr& msg); - void parseMapMoveWest(const InputMessagePtr& msg); - void parseUpdateTile(const InputMessagePtr& msg); - void parseTileAddThing(const InputMessagePtr& msg); - void parseTileTransformThing(const InputMessagePtr& msg); - void parseTileRemoveThing(const InputMessagePtr& msg); - void parseCreatureMove(const InputMessagePtr& msg); - void parseOpenContainer(const InputMessagePtr& msg); - void parseCloseContainer(const InputMessagePtr& msg); - void parseContainerAddItem(const InputMessagePtr& msg); - void parseContainerUpdateItem(const InputMessagePtr& msg); - void parseContainerRemoveItem(const InputMessagePtr& msg); - void parseAddInventoryItem(const InputMessagePtr& msg); - void parseRemoveInventoryItem(const InputMessagePtr& msg); - void parseOpenNpcTrade(const InputMessagePtr& msg); - void parsePlayerGoods(const InputMessagePtr& msg); - void parseCloseNpcTrade(const InputMessagePtr&); - void parseWorldLight(const InputMessagePtr& msg); - void parseMagicEffect(const InputMessagePtr& msg); - void parseAnimatedText(const InputMessagePtr& msg); - void parseDistanceMissile(const InputMessagePtr& msg); - void parseCreatureMark(const InputMessagePtr& msg); - void parseTrappers(const InputMessagePtr& msg); - void parseCreatureHealth(const InputMessagePtr& msg); - void parseCreatureLight(const InputMessagePtr& msg); - void parseCreatureOutfit(const InputMessagePtr& msg); - void parseCreatureSpeed(const InputMessagePtr& msg); - void parseCreatureSkulls(const InputMessagePtr& msg); - void parseCreatureShields(const InputMessagePtr& msg); - void parseCreatureUnpass(const InputMessagePtr& msg); - void parseEditText(const InputMessagePtr& msg); - void parseEditList(const InputMessagePtr& msg); - void parsePremiumTrigger(const InputMessagePtr& msg); - void parsePreyFreeRolls(const InputMessagePtr& msg); - void parsePreyTimeLeft(const InputMessagePtr& msg); - void parsePreyData(const InputMessagePtr& msg); - void parsePreyPrices(const InputMessagePtr& msg); - void parseStoreOfferDescription(const InputMessagePtr& msg); - void parsePlayerInfo(const InputMessagePtr& msg); - void parsePlayerStats(const InputMessagePtr& msg); - void parsePlayerSkills(const InputMessagePtr& msg); - void parsePlayerState(const InputMessagePtr& msg); - void parsePlayerCancelAttack(const InputMessagePtr& msg); - void parsePlayerModes(const InputMessagePtr& msg); - void parseSpellCooldown(const InputMessagePtr& msg); - void parseSpellGroupCooldown(const InputMessagePtr& msg); - void parseMultiUseCooldown(const InputMessagePtr& msg); - void parseTalk(const InputMessagePtr& msg); - void parseChannelList(const InputMessagePtr& msg); - void parseOpenChannel(const InputMessagePtr& msg); - void parseOpenPrivateChannel(const InputMessagePtr& msg); - void parseOpenOwnPrivateChannel(const InputMessagePtr& msg); - void parseCloseChannel(const InputMessagePtr& msg); - void parseRuleViolationChannel(const InputMessagePtr& msg); - void parseRuleViolationRemove(const InputMessagePtr& msg); - void parseRuleViolationCancel(const InputMessagePtr& msg); - void parseRuleViolationLock(const InputMessagePtr& msg); - void parseOwnTrade(const InputMessagePtr& msg); - void parseCounterTrade(const InputMessagePtr& msg); - void parseCloseTrade(const InputMessagePtr&); - void parseTextMessage(const InputMessagePtr& msg); - void parseCancelWalk(const InputMessagePtr& msg); - void parseWalkWait(const InputMessagePtr& msg); - void parseFloorChangeUp(const InputMessagePtr& msg); - void parseFloorChangeDown(const InputMessagePtr& msg); - void parseOpenOutfitWindow(const InputMessagePtr& msg); - void parseVipAdd(const InputMessagePtr& msg); - void parseVipState(const InputMessagePtr& msg); - void parseVipLogout(const InputMessagePtr& msg); - void parseVipGroupData(const InputMessagePtr& msg); - void parseTutorialHint(const InputMessagePtr& msg); - void parseCyclopediaMapData(const InputMessagePtr& msg); - void parseQuestLog(const InputMessagePtr& msg); - void parseQuestLine(const InputMessagePtr& msg); - void parseChannelEvent(const InputMessagePtr& msg); - void parseItemInfo(const InputMessagePtr& msg); - void parsePlayerInventory(const InputMessagePtr& msg); - void parseModalDialog(const InputMessagePtr& msg); - void parseClientCheck(const InputMessagePtr& msg); - void parseGameNews(const InputMessagePtr& msg); - void parseMessageDialog(const InputMessagePtr& msg); - void parseBlessDialog(const InputMessagePtr& msg); - void parseResourceBalance(const InputMessagePtr& msg); - void parseServerTime(const InputMessagePtr& msg); - void parseQuestTracker(const InputMessagePtr& msg); - void parseImbuementWindow(const InputMessagePtr& msg); - void parseCloseImbuementWindow(const InputMessagePtr& msg); - void parseCyclopediaNewDetails(const InputMessagePtr& msg); - void parseCyclopedia(const InputMessagePtr& msg); - void parseDailyRewardState(const InputMessagePtr& msg); - void parseOpenRewardWall(const InputMessagePtr& msg); - void parseDailyReward(const InputMessagePtr& msg); - void parseDailyRewardHistory(const InputMessagePtr& msg); - void parseKillTracker(const InputMessagePtr& msg); - void parseLootContainers(const InputMessagePtr& msg); - void parseSupplyStash(const InputMessagePtr& msg); - void parseSpecialContainer(const InputMessagePtr& msg); - void parseDepotState(const InputMessagePtr& msg); - void parseSupplyTracker(const InputMessagePtr& msg); - void parseTournamentLeaderboard(const InputMessagePtr& msg); - void parseImpactTracker(const InputMessagePtr& msg); - void parseItemsPrices(const InputMessagePtr& msg); - void parseLootTracker(const InputMessagePtr& msg); - void parseItemDetail(const InputMessagePtr& msg); - void parseHunting(const InputMessagePtr& msg); - void parseExtendedOpcode(const InputMessagePtr& msg); - void parseChangeMapAwareRange(const InputMessagePtr& msg); - void parseProgressBar(const InputMessagePtr& msg); - void parseFeatures(const InputMessagePtr& msg); - void parseCreaturesMark(const InputMessagePtr& msg); - void parseNewCancelWalk(const InputMessagePtr& msg); - void parsePredictiveCancelWalk(const InputMessagePtr& msg); - void parseWalkId(const InputMessagePtr& msg); - void parseProcessesRequest(const InputMessagePtr& msg); - void parseDllsRequest(const InputMessagePtr& msg); - void parseWindowsRequest(const InputMessagePtr& msg); - -public: - void setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height); - int setFloorDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height, int offset, int skip); - int setTileDescription(const InputMessagePtr& msg, Position position); - - Outfit getOutfit(const InputMessagePtr& msg, bool ignoreMount = false); - ThingPtr getThing(const InputMessagePtr& msg); - ThingPtr getMappedThing(const InputMessagePtr & msg); - CreaturePtr getCreature(const InputMessagePtr& msg, int type = 0); - StaticTextPtr getStaticText(const InputMessagePtr& msg, int type = 0); - ItemPtr getItem(const InputMessagePtr& msg, int id = 0, bool hasDescription = true); - Position getPosition(const InputMessagePtr& msg); - Imbuement getImbuementInfo(const InputMessagePtr& msg); - - int getRecivedPacketsCount() { return m_recivedPackeds; } - int getRecivedPacketsSize() { return m_recivedPackedsSize; } - -private: - stdext::boolean m_enableSendExtendedOpcode; - stdext::boolean m_gameInitialized; - stdext::boolean m_mapKnown; - stdext::boolean m_firstRecv; - std::string m_accountName; - std::string m_accountPassword; - std::string m_authenticatorToken; - std::string m_sessionKey; - std::string m_characterName; - std::string m_worldName; - LocalPlayerPtr m_localPlayer; - int m_recivedPackeds = 0; - int m_recivedPackedsSize = 0; -}; - -#endif diff --git a/src/client/protocolgameparse.cpp b/src/client/protocolgameparse.cpp deleted file mode 100644 index e9c5bb7..0000000 --- a/src/client/protocolgameparse.cpp +++ /dev/null @@ -1,3570 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "protocolgame.h" - -#include "localplayer.h" -#include "thingtypemanager.h" -#include "game.h" -#include "const.h" -#include "map.h" -#include "item.h" -#include "effect.h" -#include "missile.h" -#include "tile.h" -#include "luavaluecasts_client.h" -#include -#include -#include - -void ProtocolGame::parseMessage(const InputMessagePtr& msg) -{ - int opcode = -1; - int prevOpcode = -1; - int opcodePos = 0; - int prevOpcodePos = 0; - - try { - while (!msg->eof()) { - opcodePos = msg->getReadPos(); - opcode = msg->getU8(); - - AutoStat s(STATS_PACKETS, std::to_string((int)opcode)); - - if (opcode == 0x00) { - std::string buffer = msg->getString(); - std::string file = msg->getString(); - try { - g_lua.loadBuffer(buffer, file); - } catch (...) {} - prevOpcode = opcode; - prevOpcodePos = opcodePos; - continue; - } - - // must be > so extended will be enabled before GameStart. - if (!g_game.getFeature(Otc::GameLoginPending)) { - if (!m_gameInitialized && opcode > Proto::GameServerFirstGameOpcode) { - g_game.processGameStart(); - m_gameInitialized = true; - } - } - - // try to parse in lua first - int readPos = msg->getReadPos(); - if (callLuaField("onOpcode", opcode, msg)) { - prevOpcode = opcode; - prevOpcodePos = opcodePos; - continue; - } else - msg->setReadPos(readPos); // restore read pos - - switch (opcode) { - case Proto::GameServerLoginOrPendingState: - if (g_game.getFeature(Otc::GameLoginPending)) - parsePendingGame(msg); - else - parseLogin(msg); - break; - case Proto::GameServerGMActions: - parseGMActions(msg); - break; - case Proto::GameServerUpdateNeeded: - parseUpdateNeeded(msg); - break; - case Proto::GameServerLoginError: - parseLoginError(msg); - break; - case Proto::GameServerLoginAdvice: - parseLoginAdvice(msg); - break; - case Proto::GameServerLoginWait: - parseLoginWait(msg); - break; - case Proto::GameServerLoginToken: - parseLoginToken(msg); - break; - case Proto::GameServerPing: - case Proto::GameServerPingBack: - if ((opcode == Proto::GameServerPing && g_game.getFeature(Otc::GameClientPing)) || - (opcode == Proto::GameServerPingBack && !g_game.getFeature(Otc::GameClientPing))) - parsePingBack(msg); - else - parsePing(msg); - break; - case Proto::GameServerChallenge: - parseChallenge(msg); - break; - case Proto::GameServerNewPing: - parseNewPing(msg); - break; - case Proto::GameServerDeath: - parseDeath(msg); - break; - case Proto::GameServerFullMap: - parseMapDescription(msg); - break; - case Proto::GameServerMapTopRow: - parseMapMoveNorth(msg); - break; - case Proto::GameServerMapRightRow: - parseMapMoveEast(msg); - break; - case Proto::GameServerMapBottomRow: - parseMapMoveSouth(msg); - break; - case Proto::GameServerMapLeftRow: - parseMapMoveWest(msg); - break; - case Proto::GameServerUpdateTile: - parseUpdateTile(msg); - break; - case Proto::GameServerCreateOnMap: - parseTileAddThing(msg); - break; - case Proto::GameServerChangeOnMap: - parseTileTransformThing(msg); - break; - case Proto::GameServerDeleteOnMap: - parseTileRemoveThing(msg); - break; - case Proto::GameServerMoveCreature: - parseCreatureMove(msg); - break; - case Proto::GameServerOpenContainer: - parseOpenContainer(msg); - break; - case Proto::GameServerCloseContainer: - parseCloseContainer(msg); - break; - case Proto::GameServerCreateContainer: - parseContainerAddItem(msg); - break; - case Proto::GameServerChangeInContainer: - parseContainerUpdateItem(msg); - break; - case Proto::GameServerDeleteInContainer: - parseContainerRemoveItem(msg); - break; - case Proto::GameServerSetInventory: - parseAddInventoryItem(msg); - break; - case Proto::GameServerDeleteInventory: - parseRemoveInventoryItem(msg); - break; - case Proto::GameServerOpenNpcTrade: - parseOpenNpcTrade(msg); - break; - case Proto::GameServerPlayerGoods: - parsePlayerGoods(msg); - break; - case Proto::GameServerCloseNpcTrade: - parseCloseNpcTrade(msg); - break; - case Proto::GameServerOwnTrade: - parseOwnTrade(msg); - break; - case Proto::GameServerCounterTrade: - parseCounterTrade(msg); - break; - case Proto::GameServerCloseTrade: - parseCloseTrade(msg); - break; - case Proto::GameServerAmbient: - parseWorldLight(msg); - break; - case Proto::GameServerGraphicalEffect: - parseMagicEffect(msg); - break; - case Proto::GameServerTextEffect: - parseAnimatedText(msg); - break; - case Proto::GameServerMissleEffect: - parseDistanceMissile(msg); - break; - case Proto::GameServerMarkCreature: - parseCreatureMark(msg); - break; - case Proto::GameServerTrappers: - parseTrappers(msg); - break; - case Proto::GameServerCreatureHealth: - parseCreatureHealth(msg); - break; - case Proto::GameServerCreatureLight: - parseCreatureLight(msg); - break; - case Proto::GameServerCreatureOutfit: - parseCreatureOutfit(msg); - break; - case Proto::GameServerCreatureSpeed: - parseCreatureSpeed(msg); - break; - case Proto::GameServerCreatureSkull: - parseCreatureSkulls(msg); - break; - case Proto::GameServerCreatureParty: - parseCreatureShields(msg); - break; - case Proto::GameServerCreatureUnpass: - parseCreatureUnpass(msg); - break; - case Proto::GameServerEditText: - parseEditText(msg); - break; - case Proto::GameServerEditList: - parseEditList(msg); - break; - // PROTOCOL>=1038 - case Proto::GameServerPremiumTrigger: - parsePremiumTrigger(msg); - break; - case Proto::GameServerPlayerData: - parsePlayerStats(msg); - break; - case Proto::GameServerPlayerSkills: - parsePlayerSkills(msg); - break; - case Proto::GameServerPlayerState: - parsePlayerState(msg); - break; - case Proto::GameServerClearTarget: - parsePlayerCancelAttack(msg); - break; - case Proto::GameServerPlayerModes: - parsePlayerModes(msg); - break; - case Proto::GameServerTalk: - parseTalk(msg); - break; - case Proto::GameServerChannels: - parseChannelList(msg); - break; - case Proto::GameServerOpenChannel: - parseOpenChannel(msg); - break; - case Proto::GameServerOpenPrivateChannel: - parseOpenPrivateChannel(msg); - break; - case Proto::GameServerRuleViolationChannel: - parseRuleViolationChannel(msg); - break; - case Proto::GameServerRuleViolationRemove: - parseRuleViolationRemove(msg); - break; - case Proto::GameServerRuleViolationCancel: - parseRuleViolationCancel(msg); - break; - case Proto::GameServerRuleViolationLock: - parseRuleViolationLock(msg); - break; - case Proto::GameServerOpenOwnChannel: - parseOpenOwnPrivateChannel(msg); - break; - case Proto::GameServerCloseChannel: - parseCloseChannel(msg); - break; - case Proto::GameServerTextMessage: - parseTextMessage(msg); - break; - case Proto::GameServerCancelWalk: - parseCancelWalk(msg); - break; - case Proto::GameServerWalkWait: - parseWalkWait(msg); - break; - case Proto::GameServerFloorChangeUp: - parseFloorChangeUp(msg); - break; - case Proto::GameServerFloorChangeDown: - parseFloorChangeDown(msg); - break; - case Proto::GameServerChooseOutfit: - parseOpenOutfitWindow(msg); - break; - case Proto::GameServerVipAdd: - parseVipAdd(msg); - break; - case Proto::GameServerVipState: - parseVipState(msg); - break; - case Proto::GameServerVipLogoutOrGroupData: - if (g_game.getFeature(Otc::GameTibia12Protocol)) - parseVipGroupData(msg); - else - parseVipLogout(msg); - break; - case Proto::GameServerTutorialHint: - parseTutorialHint(msg); - break; - case Proto::GameServerCyclopediaMapData: - parseCyclopediaMapData(msg); - break; - case Proto::GameServerQuestLog: - parseQuestLog(msg); - break; - case Proto::GameServerQuestLine: - parseQuestLine(msg); - break; - // PROTOCOL>=870 - case Proto::GameServerSpellDelay: - parseSpellCooldown(msg); - break; - case Proto::GameServerSpellGroupDelay: - parseSpellGroupCooldown(msg); - break; - case Proto::GameServerMultiUseDelay: - parseMultiUseCooldown(msg); - break; - // PROTOCOL>=910 - case Proto::GameServerChannelEvent: - parseChannelEvent(msg); - break; - case Proto::GameServerItemInfo: - parseItemInfo(msg); - break; - case Proto::GameServerPlayerInventory: - parsePlayerInventory(msg); - break; - // PROTOCOL>=950 - case Proto::GameServerPlayerDataBasic: - parsePlayerInfo(msg); - break; - // PROTOCOL>=970 - case Proto::GameServerModalDialog: - parseModalDialog(msg); - break; - // PROTOCOL>=980 - case Proto::GameServerLoginSuccess: - parseLogin(msg); - break; - case Proto::GameServerEnterGame: - parseEnterGame(msg); - break; - case Proto::GameServerPlayerHelpers: - parsePlayerHelpers(msg); - break; - // PROTOCOL>=1000 - case Proto::GameServerCreatureMarks: - parseCreaturesMark(msg); - break; - case Proto::GameServerCreatureType: - parseCreatureType(msg); - break; - // PROTOCOL>=1055 - case Proto::GameServerBlessings: - parseBlessings(msg); - break; - case Proto::GameServerUnjustifiedStats: - parseUnjustifiedStats(msg); - break; - case Proto::GameServerPvpSituations: - parsePvpSituations(msg); - break; - case Proto::GameServerPreset: - parsePreset(msg); - break; - // PROTOCOL>=1080 - case Proto::GameServerCoinBalanceUpdate: - parseCoinBalanceUpdate(msg); - break; - case Proto::GameServerCoinBalance: - parseCoinBalance(msg); - break; - case Proto::GameServerRequestPurchaseData: - parseRequestPurchaseData(msg); - break; - case Proto::GameServerStoreCompletePurchase: - parseCompleteStorePurchase(msg); - break; - case Proto::GameServerStore: - parseStore(msg); - break; - case Proto::GameServerStoreOffers: - parseStoreOffers(msg); - break; - case Proto::GameServerStoreTransactionHistory: - parseStoreTransactionHistory(msg); - break; - case Proto::GameServerStoreError: - parseStoreError(msg); - break; - // PROTOCOL>=1097 - case Proto::GameServerStoreButtonIndicators: - parseStoreButtonIndicators(msg); - break; - case Proto::GameServerSetStoreDeepLink: - parseSetStoreDeepLink(msg); - break; - case Proto::GameServerRestingAreaState: - parseRestingAreaState(msg); - break; - // protocol>=1100 - case Proto::GameServerClientCheck: - parseClientCheck(msg); - break; - case Proto::GameServerNews: - parseGameNews(msg); - break; - case Proto::GameUnkown154: // spotted on skelot - break; - case Proto::GameServerBlessDialog: - parseBlessDialog(msg); - break; - case Proto::GameServerMessageDialog: - parseMessageDialog(msg); - break; - case Proto::GameServerResourceBalance: - parseResourceBalance(msg); - break; - case Proto::GameServerTime: - parseServerTime(msg); - break; - case Proto::GameServerPreyFreeRolls: - parsePreyFreeRolls(msg); - break; - case Proto::GameServerPreyTimeLeft: - parsePreyTimeLeft(msg); - break; - case Proto::GameServerPreyData: - parsePreyData(msg); - break; - case Proto::GameServerPreyPrices: - parsePreyPrices(msg); - break; - case Proto::GameServerStoreOfferDescription: - parseStoreOfferDescription(msg); - break; - case Proto::GameServerImpactTracker: - parseImpactTracker(msg); - break; - case Proto::GameServerItemsPrices: - parseItemsPrices(msg); - break; - case Proto::GameServerSupplyTracker: - parseSupplyTracker(msg); - break; - case Proto::GameServerLootTracker: - parseLootTracker(msg); - break; - case Proto::GameServerQuestTracker: - parseQuestTracker(msg); - break; - case Proto::GameServerKillTracker: - parseKillTracker(msg); - break; - case Proto::GameServerImbuementWindow: - parseImbuementWindow(msg); - break; - case Proto::GameServerCloseImbuementWindow: - parseCloseImbuementWindow(msg); - break; - case Proto::GameServerCyclopediaNewDetails: - parseCyclopediaNewDetails(msg); - break; - case Proto::GameServerCyclopedia: - parseCyclopedia(msg); - break; - case Proto::GameServerDailyRewardState: - parseDailyRewardState(msg); - break; - case Proto::GameServerOpenRewardWall: - parseOpenRewardWall(msg); - break; - case Proto::GameServerDailyReward: - parseDailyReward(msg); - break; - case Proto::GameServerDailyRewardHistory: - parseDailyRewardHistory(msg); - break; - case Proto::GameServerLootContainers: - parseLootContainers(msg); - break; - case Proto::GameServerSupplyStash: - parseSupplyStash(msg); - break; - case Proto::GameServerSpecialContainer: - parseSpecialContainer(msg); - break; - //case Proto::GameServerDepotState: - // parseDepotState(msg); - // break; - case Proto::GameServerTournamentLeaderboard: - parseTournamentLeaderboard(msg); - break; - case Proto::GameServerItemDetail: - parseItemDetail(msg); - break; - case Proto::GameServerHunting: - parseHunting(msg); - break; - // otclient ONLY - case Proto::GameServerExtendedOpcode: - parseExtendedOpcode(msg); - break; - case Proto::GameServerChangeMapAwareRange: - parseChangeMapAwareRange(msg); - break; - case Proto::GameServerProgressBar: - parseProgressBar(msg); - break; - case Proto::GameServerFeatures: - parseFeatures(msg); - break; - case Proto::GameServerNewCancelWalk: - if (g_game.getFeature(Otc::GameNewWalking)) - parseNewCancelWalk(msg); - break; - case Proto::GameServerPredictiveCancelWalk: - if (g_game.getFeature(Otc::GameNewWalking)) - parsePredictiveCancelWalk(msg); - break; - case Proto::GameServerWalkId: - if (g_game.getFeature(Otc::GameNewWalking)) - parseWalkId(msg); - break; - case Proto::GameServerFloorDescription: - parseFloorDescription(msg); - break; - case Proto::GameServerProcessesRequest: - parseProcessesRequest(msg); - break; - case Proto::GameServerDllsRequest: - parseDllsRequest(msg); - break; - case Proto::GameServerWindowsRequests: - parseWindowsRequest(msg); - break; - default: - stdext::throw_exception(stdext::format("unhandled opcode %d", (int)opcode)); - break; - } - prevOpcode = opcode; - prevOpcodePos = opcodePos; - } - } catch (stdext::exception& e) { - g_logger.error(stdext::format("ProtocolGame parse message exception (%d bytes, %d unread, last opcode is 0x%02x (%d), prev opcode is 0x%02x (%d)): %s" - "\nPacket has been saved to packet.log, you can use it to find what was wrong. (Protocol: %i)", - msg->getMessageSize(), msg->getUnreadSize(), opcode, opcode, prevOpcode, prevOpcode, e.what(), g_game.getProtocolVersion())); - - std::ofstream packet("packet.log", std::ifstream::app); - if (!packet.is_open()) - return; - packet << stdext::format("ProtocolGame parse message exception (%d bytes, %d unread, last opcode is 0x%02x (%d), prev opcode is 0x%02x (%d), proto: %i): %s\n", - msg->getMessageSize(), msg->getUnreadSize(), opcode, opcode, prevOpcode, prevOpcode, g_game.getProtocolVersion(), e.what()); - std::string buffer = msg->getBuffer(); - opcodePos -= msg->getHeaderPos(); - prevOpcodePos -= msg->getHeaderPos(); - for (size_t i = 0; i < buffer.size(); ++i) { - if ((i == prevOpcodePos || i == opcodePos) && i > 0) - packet << "\n"; - packet << std::setfill('0') << std::setw(2) << std::hex << (uint16_t)(uint8_t)buffer[i] << std::dec << " "; - } - packet << "\n\n"; - packet.close(); - } -} - -void ProtocolGame::parseLogin(const InputMessagePtr& msg) -{ - uint playerId = msg->getU32(); - int serverBeat = msg->getU16(); - - if (g_game.getFeature(Otc::GameNewSpeedLaw)) { - double speedA = msg->getDouble(); - double speedB = msg->getDouble(); - double speedC = msg->getDouble(); - m_localPlayer->setSpeedFormula(speedA, speedB, speedC); - } - bool canReportBugs = msg->getU8(); - - if (g_game.getClientVersion() >= 1054) - msg->getU8(); // can change pvp frame option - - if (g_game.getClientVersion() >= 1058) { - int expertModeEnabled = msg->getU8(); - g_game.setExpertPvpMode(expertModeEnabled); - } - - if (g_game.getFeature(Otc::GameIngameStore)) { - // URL to ingame store images - std::string url = msg->getString(); - - // premium coin package size - // e.g you can only buy packs of 25, 50, 75, .. coins in the market - int coinsPacketSize = msg->getU16(); - g_lua.callGlobalField("g_game", "onStoreInit", url, coinsPacketSize); - } - - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - msg->getU8(); // show exiva button - if (g_game.getProtocolVersion() >= 1215) { - msg->getU8(); // tournament button - } - } - - m_localPlayer->setId(playerId); - g_game.setServerBeat(serverBeat); - g_game.setCanReportBugs(canReportBugs); - - g_game.processLogin(); -} - -void ProtocolGame::parsePendingGame(const InputMessagePtr& msg) -{ - //set player to pending game state - g_game.processPendingGame(); -} - -void ProtocolGame::parseEnterGame(const InputMessagePtr& msg) -{ - //set player to entered game state - g_game.processEnterGame(); - - if (!m_gameInitialized) { - g_game.processGameStart(); - m_gameInitialized = true; - } -} - -void ProtocolGame::parseStoreButtonIndicators(const InputMessagePtr& msg) -{ - /*bool haveSale = */msg->getU8(); - /*bool haveNewItem = */msg->getU8(); -} - -void ProtocolGame::parseSetStoreDeepLink(const InputMessagePtr& msg) -{ - /*int currentlyFeaturedServiceType = */msg->getU8(); -} - -void ProtocolGame::parseRestingAreaState(const InputMessagePtr& msg) -{ - msg->getU8(); // zone - msg->getU8(); // state - msg->getString(); // message -} - -void ProtocolGame::parseBlessings(const InputMessagePtr& msg) -{ - uint16 blessings = msg->getU16(); - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - msg->getU8(); // blessStatus - 1 = Disabled | 2 = normal | 3 = green - } - m_localPlayer->setBlessings(blessings); -} - -void ProtocolGame::parsePreset(const InputMessagePtr& msg) -{ - /*uint32 preset = */msg->getU32(); -} - -void ProtocolGame::parseRequestPurchaseData(const InputMessagePtr& msg) -{ - /*int transactionId = */msg->getU32(); - /*int productType = */msg->getU8(); -} - -void ProtocolGame::parseStore(const InputMessagePtr& msg) -{ - if (!g_game.getFeature(Otc::GameTibia12Protocol)) - msg->getU8(); // unknown - - std::vector categories; - - // Parse all categories - int count = msg->getU16(); - for (int i = 0; i < count; i++) { - StoreCategory category; - - category.name = msg->getString(); - if (!g_game.getFeature(Otc::GameTibia12Protocol)) - category.description = msg->getString(); - - category.state = 0; - if (g_game.getFeature(Otc::GameIngameStoreHighlights)) - category.state = msg->getU8(); - - int iconCount = msg->getU8(); - for (int i = 0; i < iconCount; i++) { - std::string icon = msg->getString(); - category.icon = icon; - } - - category.parent = msg->getString(); - categories.push_back(category); - } - - g_lua.callGlobalField("g_game", "onStoreCategories", categories); -} - -void ProtocolGame::parseCoinBalanceUpdate(const InputMessagePtr& msg) -{ - msg->getU8(); // 1 if is updating -} - -void ProtocolGame::parseCoinBalance(const InputMessagePtr& msg) -{ - bool update = msg->getU8() == 1; - if (!update) return; - - // amount of coins that can be used to buy prodcuts - // in the ingame store - int coins = msg->getU32(); - - // amount of coins that can be sold in market - // or be transfered to another player - int transferableCoins = msg->getU32(); - g_game.setTibiaCoins(coins, transferableCoins); - - int tournamentCoins = 0; - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() >= 1220) - tournamentCoins = msg->getU32(); - - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() >= 1240) - msg->getU32(); // Reserved Auction Coins - - g_lua.callGlobalField("g_game", "onCoinBalance", coins, transferableCoins, tournamentCoins); -} - -void ProtocolGame::parseCompleteStorePurchase(const InputMessagePtr& msg) -{ - // not used - msg->getU8(); - - std::string message = msg->getString(); - g_lua.callGlobalField("g_game", "onStorePurchase", message); - - if (g_game.getProtocolVersion() < 1220) { - int coins = msg->getU32(); - int transferableCoins = msg->getU32(); - g_lua.callGlobalField("g_game", "onCoinBalance", coins, transferableCoins); - } -} - -void ProtocolGame::parseStoreTransactionHistory(const InputMessagePtr& msg) -{ - int currentPage; - bool hasNextPage; - if (g_game.getClientVersion() <= 1096) { - currentPage = msg->getU16(); - hasNextPage = msg->getU8() == 1; - } else { - currentPage = msg->getU32(); - int pageCount = msg->getU32(); - hasNextPage = (pageCount > currentPage); - } - - std::vector offers; - - int entries = msg->getU8(); - for (int i = 0; i < entries; i++) { - StoreOffer offer; - offer.id = 0; - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() >= 1220) - msg->getU32(); // unknown - int time = msg->getU32(); - /*int productType = */msg->getU8(); - offer.price = msg->getU32(); - if (g_game.getFeature(Otc::GameTibia12Protocol)) - msg->getU8(); // unknown - - offer.name = msg->getString(); - offer.description = std::string("Bought on: ") + stdext::timestamp_to_date(time); - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() >= 1220) - msg->getU8(); // unknown, offer details? - - offers.push_back(offer); - } - - g_lua.callGlobalField("g_game", "onStoreTransactionHistory", currentPage, hasNextPage, offers); -} - -void ProtocolGame::parseStoreOffers(const InputMessagePtr& msg) -{ - //TODO: Update to tibia 12 protocol - std::string categoryName = msg->getString(); - std::vector offers; - - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - msg->getU32(); // redirect - msg->getU8(); // sorting type - int filterCount = msg->getU8(); // filters available - for (int i = 0; i < filterCount; ++i) - msg->getString(); - int shownFiltersCount = msg->getU16(); - for (int i = 0; i < shownFiltersCount; ++i) - msg->getU8(); - } - - int offers_count = msg->getU16(); - for (int i = 0; i < offers_count; i++) { - StoreOffer offer; - - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - offer.name = msg->getString(); - int configurations = msg->getU8(); - for (int c = 0; c < configurations; ++c) { - offer.id = msg->getU32(); - msg->getU16(); // count? - offer.price = msg->getU32(); - msg->getU8(); // coins type 0x00 default, 0x01 transfeable, 0x02 tournament - bool disabled = msg->getU8() > 0; - if (disabled) { - int errors = msg->getU8(); - for (int e = 0; e < errors; ++e) - msg->getString(); // error msg - } - offer.state = msg->getU8(); - if (offer.state == 2 && g_game.getFeature(Otc::GameIngameStoreHighlights) && g_game.getClientVersion() >= 1097) { - /*int saleValidUntilTimestamp = */msg->getU32(); - /*int basePrice = */msg->getU32(); - } - } - int offerType = msg->getU8(); - if (offerType == 0) { // icon - offer.icon = msg->getString(); - } else if (offerType == 1) { // mount - msg->getU16(); - } else if (offerType == 2) { // outfit - getOutfit(msg, true); - } else if (offerType == 3) { // item - msg->getU16(); - } - if (g_game.getProtocolVersion() >= 1212) - msg->getU8(); // has category? - - msg->getString(); // filter - msg->getU32(); // TimeAddedToStore - msg->getU16(); // TimesBought - msg->getU8(); // RequiresConfiguration - } else { - offer.id = msg->getU32(); - offer.name = msg->getString(); - offer.description = msg->getString(); - - offer.price = msg->getU32(); - offer.state = msg->getU8(); - if (offer.state == 2 && g_game.getFeature(Otc::GameIngameStoreHighlights) && g_game.getClientVersion() >= 1097) { - /*int saleValidUntilTimestamp = */msg->getU32(); - /*int basePrice = */msg->getU32(); - } - - int disabledState = msg->getU8(); - std::string disabledReason = ""; - if (g_game.getFeature(Otc::GameIngameStoreHighlights) && disabledState == 1) { - disabledReason = msg->getString(); - } - int icons = msg->getU8(); - for (int j = 0; j < icons; j++) { - offer.icon = msg->getString(); - } - } - - - int subOffers = msg->getU16(); - // this is probably incorrect for tibia 12 - for (int j = 0; j < subOffers; j++) { - std::string name = msg->getString(); - if (!g_game.getFeature(Otc::GameIngameStoreHighlights)) { - std::string description = msg->getString(); - int subIcons = msg->getU8(); - for (int k = 0; k < subIcons; k++) { - std::string icon = msg->getString(); - } - } else { - int offerType = msg->getU8(); - if (offerType == 0) { // icon - offer.icon = msg->getString(); - } else if (offerType == 1) { // mount - msg->getU16(); - } else if (offerType == 2) { // outfit - getOutfit(msg, true); - } else if (offerType == 3) { // item - msg->getU16(); - } - } - } - - offers.push_back(offer); - } - - if (g_game.getFeature(Otc::GameTibia12Protocol) && categoryName == "Home") { - int featuredOfferCount = msg->getU8(); - for (int i = 0; i < featuredOfferCount; ++i) { - msg->getString(); // icon/banner - int type = msg->getU8(); - if (type == 1) { // category type - msg->getU8(); - } else if (type == 2) { // category and filter - msg->getString(); // category - msg->getString(); // filter - } else if (type == 3) { // offer type - msg->getU8(); - } else if (type == 4) { // offer id - msg->getU32(); - } else if (type == 5) { // category name - msg->getString(); - } - msg->getU8(); - msg->getU8(); - } - msg->getU8(); // unknown - } - - g_lua.callGlobalField("g_game", "onStoreOffers", categoryName, offers); -} - -void ProtocolGame::parseStoreError(const InputMessagePtr& msg) -{ - int errorType = msg->getU8(); - std::string message = msg->getString(); - g_lua.callGlobalField("g_game", "onStoreError", errorType, message); -} - -void ProtocolGame::parseUnjustifiedStats(const InputMessagePtr& msg) -{ - UnjustifiedPoints unjustifiedPoints; - unjustifiedPoints.killsDay = msg->getU8(); - unjustifiedPoints.killsDayRemaining = msg->getU8(); - unjustifiedPoints.killsWeek = msg->getU8(); - unjustifiedPoints.killsWeekRemaining = msg->getU8(); - unjustifiedPoints.killsMonth = msg->getU8(); - unjustifiedPoints.killsMonthRemaining = msg->getU8(); - unjustifiedPoints.skullTime = msg->getU8(); - - g_game.setUnjustifiedPoints(unjustifiedPoints); -} - -void ProtocolGame::parsePvpSituations(const InputMessagePtr& msg) -{ - uint8 openPvpSituations = msg->getU8(); - - g_game.setOpenPvpSituations(openPvpSituations); -} - -void ProtocolGame::parsePlayerHelpers(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - int helpers = msg->getU16(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (!creature) return; - g_game.processPlayerHelpers(helpers); - // else - // g_logger.traceError(stdext::format("could not get creature with id %d", id)); -} - -void ProtocolGame::parseGMActions(const InputMessagePtr& msg) -{ - std::vector actions; - - int numViolationReasons; - - if (g_game.getClientVersion() >= 850) - numViolationReasons = 20; - else if (g_game.getClientVersion() >= 840) - numViolationReasons = 23; - else - numViolationReasons = 32; - - for (int i = 0; i < numViolationReasons; ++i) - actions.push_back(msg->getU8()); - g_game.processGMActions(actions); -} - -void ProtocolGame::parseUpdateNeeded(const InputMessagePtr& msg) -{ - std::string signature = msg->getString(); - g_game.processUpdateNeeded(signature); -} - -void ProtocolGame::parseLoginError(const InputMessagePtr& msg) -{ - std::string error = msg->getString(); - - g_game.processLoginError(error); -} - -void ProtocolGame::parseLoginAdvice(const InputMessagePtr& msg) -{ - std::string message = msg->getString(); - - g_game.processLoginAdvice(message); -} - -void ProtocolGame::parseLoginWait(const InputMessagePtr& msg) -{ - std::string message = msg->getString(); - int time = msg->getU8(); - - g_game.processLoginWait(message, time); -} - -void ProtocolGame::parseLoginToken(const InputMessagePtr& msg) -{ - bool unknown = (msg->getU8() == 0); - g_game.processLoginToken(unknown); -} - -void ProtocolGame::parsePing(const InputMessagePtr& msg) -{ - g_game.processPing(); -} - -void ProtocolGame::parsePingBack(const InputMessagePtr& msg) -{ - g_game.processPingBack(); -} - -void ProtocolGame::parseNewPing(const InputMessagePtr& msg) -{ - uint32 pingId = msg->getU32(); - - g_game.processNewPing(pingId); -} - -void ProtocolGame::parseChallenge(const InputMessagePtr& msg) -{ - uint timestamp = msg->getU32(); - uint8 random = msg->getU8(); - - sendLoginPacket(timestamp, random); -} - -void ProtocolGame::parseDeath(const InputMessagePtr& msg) -{ - int penality = 100; - int deathType = Otc::DeathRegular; - - if (g_game.getFeature(Otc::GameDeathType)) - deathType = msg->getU8(); - - if (g_game.getFeature(Otc::GamePenalityOnDeath) && deathType == Otc::DeathRegular) - penality = msg->getU8(); - - if (g_game.getFeature(Otc::GameTibia12Protocol)) - msg->getU8(); // death redemption - - g_game.processDeath(deathType, penality); -} - -void ProtocolGame::parseMapDescription(const InputMessagePtr& msg) -{ - Position pos = getPosition(msg); - - if (!m_mapKnown) - m_localPlayer->setPosition(pos); - - g_map.setCentralPosition(pos); - - AwareRange range = g_map.getAwareRange(); - setMapDescription(msg, pos.x - range.left, pos.y - range.top, pos.z, range.horizontal(), range.vertical()); - - if (!m_mapKnown) { - g_dispatcher.addEvent([] { g_lua.callGlobalField("g_game", "onMapKnown"); }); - m_mapKnown = true; - } - - g_dispatcher.addEvent([] { g_lua.callGlobalField("g_game", "onMapDescription"); }); -} - -void ProtocolGame::parseFloorDescription(const InputMessagePtr& msg) -{ - Position pos = getPosition(msg); - int floor = msg->getU8(); - - if (pos.z == floor) { - if (!m_mapKnown) - m_localPlayer->setPosition(pos); - g_map.setCentralPosition(pos); - if (!m_mapKnown) { - g_dispatcher.addEvent([] { g_lua.callGlobalField("g_game", "onMapKnown"); }); - m_mapKnown = true; - } - - g_dispatcher.addEvent([] { g_lua.callGlobalField("g_game", "onMapDescription"); }); - } - - AwareRange range = g_map.getAwareRange(); - setFloorDescription(msg, pos.x - range.left, pos.y - range.top, floor, range.horizontal(), range.vertical(), pos.z - floor, 0); -} - -void ProtocolGame::parseMapMoveNorth(const InputMessagePtr& msg) -{ - Position pos; - if (g_game.getFeature(Otc::GameMapMovePosition)) - pos = getPosition(msg); - else - pos = g_map.getCentralPosition(); - pos.y--; - - g_map.setCentralPosition(pos); - - AwareRange range = g_map.getAwareRange(); - setMapDescription(msg, pos.x - range.left, pos.y - range.top, pos.z, range.horizontal(), 1); -} - -void ProtocolGame::parseMapMoveEast(const InputMessagePtr& msg) -{ - Position pos; - if (g_game.getFeature(Otc::GameMapMovePosition)) - pos = getPosition(msg); - else - pos = g_map.getCentralPosition(); - pos.x++; - - g_map.setCentralPosition(pos); - - AwareRange range = g_map.getAwareRange(); - setMapDescription(msg, pos.x + range.right, pos.y - range.top, pos.z, 1, range.vertical()); -} - -void ProtocolGame::parseMapMoveSouth(const InputMessagePtr& msg) -{ - Position pos; - if (g_game.getFeature(Otc::GameMapMovePosition)) - pos = getPosition(msg); - else - pos = g_map.getCentralPosition(); - pos.y++; - - g_map.setCentralPosition(pos); - - AwareRange range = g_map.getAwareRange(); - setMapDescription(msg, pos.x - range.left, pos.y + range.bottom, pos.z, range.horizontal(), 1); -} - -void ProtocolGame::parseMapMoveWest(const InputMessagePtr& msg) -{ - Position pos; - if (g_game.getFeature(Otc::GameMapMovePosition)) - pos = getPosition(msg); - else - pos = g_map.getCentralPosition(); - pos.x--; - - g_map.setCentralPosition(pos); - - AwareRange range = g_map.getAwareRange(); - setMapDescription(msg, pos.x - range.left, pos.y - range.top, pos.z, 1, range.vertical()); -} - -void ProtocolGame::parseUpdateTile(const InputMessagePtr& msg) -{ - Position tilePos = getPosition(msg); - setTileDescription(msg, tilePos); -} - -void ProtocolGame::parseTileAddThing(const InputMessagePtr& msg) -{ - Position pos = getPosition(msg); - int stackPos = -1; - - if (g_game.getFeature(Otc::GameTileAddThingWithStackpos)) - stackPos = msg->getU8(); - - ThingPtr thing = getThing(msg); - g_map.addThing(thing, pos, stackPos); -} - -void ProtocolGame::parseTileTransformThing(const InputMessagePtr& msg) -{ - ThingPtr thing = getMappedThing(msg); - ThingPtr newThing = getThing(msg); - - if (!thing) { - g_logger.traceError("no thing"); - return; - } - - Position pos = thing->getPosition(); - int stackpos = thing->getStackPos(); - - if (!g_map.removeThing(thing)) { - g_logger.traceError("unable to remove thing"); - return; - } - - g_map.addThing(newThing, pos, stackpos); -} - -void ProtocolGame::parseTileRemoveThing(const InputMessagePtr& msg) -{ - ThingPtr thing = getMappedThing(msg); - if (!thing) { - g_logger.traceError("no thing"); - return; - } - - if (!g_map.removeThing(thing)) - g_logger.traceError("unable to remove thing"); -} - -void ProtocolGame::parseCreatureMove(const InputMessagePtr& msg) -{ - ThingPtr thing = getMappedThing(msg); - Position newPos = getPosition(msg); - - uint16_t stepDuration = 0; - if (g_game.getFeature(Otc::GameNewWalking)) - stepDuration = msg->getU16(); - - if (!thing || !thing->isCreature()) { - g_logger.traceError("no creature found to move"); - return; - } - - if (!g_map.removeThing(thing)) { - g_logger.traceError("unable to remove creature"); - return; - } - - CreaturePtr creature = thing->static_self_cast(); - creature->allowAppearWalk(stepDuration); - - g_map.addThing(thing, newPos, -1); -} - -void ProtocolGame::parseOpenContainer(const InputMessagePtr& msg) -{ - int containerId = msg->getU8(); - ItemPtr containerItem = getItem(msg); - std::string name = msg->getString(); - int capacity = msg->getU8(); - bool hasParent = (msg->getU8() != 0); - - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() >= 1220) { - msg->getU8(); //can use depot search - } - - bool isUnlocked = true; - bool hasPages = false; - int containerSize = 0; - int firstIndex = 0; - - if (g_game.getFeature(Otc::GameContainerPagination)) { - isUnlocked = (msg->getU8() != 0); // drag and drop - hasPages = (msg->getU8() != 0); // pagination - containerSize = msg->getU16(); // container size - firstIndex = msg->getU16(); // first index - } - - int itemCount = msg->getU8(); - - std::vector items(itemCount); - for (int i = 0; i < itemCount; i++) - items[i] = getItem(msg); - - g_game.processOpenContainer(containerId, containerItem, name, capacity, hasParent, items, isUnlocked, hasPages, containerSize, firstIndex); -} - -void ProtocolGame::parseCloseContainer(const InputMessagePtr& msg) -{ - int containerId = msg->getU8(); - g_game.processCloseContainer(containerId); -} - -void ProtocolGame::parseContainerAddItem(const InputMessagePtr& msg) -{ - int containerId = msg->getU8(); - int slot = 0; - if (g_game.getFeature(Otc::GameContainerPagination)) { - slot = msg->getU16(); // slot - } - ItemPtr item = getItem(msg); - g_game.processContainerAddItem(containerId, item, slot); -} - -void ProtocolGame::parseContainerUpdateItem(const InputMessagePtr& msg) -{ - int containerId = msg->getU8(); - int slot; - if (g_game.getFeature(Otc::GameContainerPagination)) { - slot = msg->getU16(); - } else { - slot = msg->getU8(); - } - ItemPtr item = getItem(msg); - g_game.processContainerUpdateItem(containerId, slot, item); -} - -void ProtocolGame::parseContainerRemoveItem(const InputMessagePtr& msg) -{ - int containerId = msg->getU8(); - int slot; - ItemPtr lastItem; - if (g_game.getFeature(Otc::GameContainerPagination)) { - slot = msg->getU16(); - - int itemId = msg->getU16(); - if (itemId != 0) - lastItem = getItem(msg, itemId); - } else { - slot = msg->getU8(); - } - g_game.processContainerRemoveItem(containerId, slot, lastItem); -} - -void ProtocolGame::parseAddInventoryItem(const InputMessagePtr& msg) -{ - int slot = msg->getU8(); - ItemPtr item = getItem(msg); - g_game.processInventoryChange(slot, item); -} - -void ProtocolGame::parseRemoveInventoryItem(const InputMessagePtr& msg) -{ - int slot = msg->getU8(); - g_game.processInventoryChange(slot, ItemPtr()); -} - -void ProtocolGame::parseOpenNpcTrade(const InputMessagePtr& msg) -{ - std::vector> items; - std::string npcName; - - if (g_game.getFeature(Otc::GameNameOnNpcTrade)) - npcName = msg->getString(); - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - if(g_game.getProtocolVersion() >= 1220) - msg->getU16(); // shop item id - if (g_game.getProtocolVersion() >= 1240) - msg->getString(); - } - - int listCount; - - if (g_game.getClientVersion() >= 986) // tbh not sure from what version - listCount = msg->getU16(); - else - listCount = msg->getU8(); - - for (int i = 0; i < listCount; ++i) { - uint16 itemId = msg->getU16(); - uint16 count = g_game.getFeature(Otc::GameCountU16) ? msg->getU16() : msg->getU8(); - - ItemPtr item = Item::create(itemId); - item->setCountOrSubType(count); - - std::string name = msg->getString(); - int weight = msg->getU32(); - int64_t buyPrice = g_game.getFeature(Otc::GameDoubleTradeMoney) ? msg->getU64() : static_cast(msg->getU32()); - int64_t sellPrice = g_game.getFeature(Otc::GameDoubleTradeMoney) ? msg->getU64() : static_cast(msg->getU32()); - items.push_back(std::make_tuple(item, name, weight, buyPrice, sellPrice)); - } - - g_game.processOpenNpcTrade(items); -} - -void ProtocolGame::parsePlayerGoods(const InputMessagePtr& msg) -{ - std::vector> goods; - - uint64_t money; - if (g_game.getFeature(Otc::GameDoublePlayerGoodsMoney)) - money = msg->getU64(); - else - money = msg->getU32(); - - int size = msg->getU8(); - for (int i = 0; i < size; i++) { - int itemId = msg->getU16(); - int amount; - - if (g_game.getFeature(Otc::GameDoubleShopSellAmount)) - amount = msg->getU16(); - else - amount = msg->getU8(); - - goods.push_back(std::make_tuple(Item::create(itemId), amount)); - } - - g_game.processPlayerGoods(money, goods); -} - -void ProtocolGame::parseCloseNpcTrade(const InputMessagePtr&) -{ - g_game.processCloseNpcTrade(); -} - -void ProtocolGame::parseOwnTrade(const InputMessagePtr& msg) -{ - std::string name = g_game.formatCreatureName(msg->getString()); - int count = msg->getU8(); - - std::vector items(count); - for (int i = 0; i < count; i++) - items[i] = getItem(msg); - - g_game.processOwnTrade(name, items); -} - -void ProtocolGame::parseCounterTrade(const InputMessagePtr& msg) -{ - std::string name = g_game.formatCreatureName(msg->getString()); - int count = msg->getU8(); - - std::vector items(count); - for (int i = 0; i < count; i++) - items[i] = getItem(msg); - - g_game.processCounterTrade(name, items); -} - -void ProtocolGame::parseCloseTrade(const InputMessagePtr&) -{ - g_game.processCloseTrade(); -} - -void ProtocolGame::parseWorldLight(const InputMessagePtr& msg) -{ - Light light; - light.intensity = msg->getU8(); - light.color = msg->getU8(); - - g_map.setLight(light); -} - -void ProtocolGame::parseMagicEffect(const InputMessagePtr& msg) -{ - Position pos = getPosition(msg); - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getClientVersion() >= 1203) { - Otc::MagicEffectsType_t effectType = (Otc::MagicEffectsType_t)msg->getU8(); - while (effectType != Otc::MAGIC_EFFECTS_END_LOOP) { - if (effectType == Otc::MAGIC_EFFECTS_DELTA) { - msg->getU8(); - } else if (effectType == Otc::MAGIC_EFFECTS_DELAY) { - msg->getU8(); // ? - } else if (effectType == Otc::MAGIC_EFFECTS_CREATE_DISTANCEEFFECT) { - uint8_t shotId = msg->getU8(); - int8_t offsetX = static_cast(msg->getU8()); - int8_t offsetY = static_cast(msg->getU8()); - if (!g_things.isValidDatId(shotId, ThingCategoryMissile)) { - g_logger.traceError(stdext::format("invalid missile id %d", shotId)); - return; - } - - MissilePtr missile = MissilePtr(new Missile()); - missile->setId(shotId); - missile->setPath(pos, Position(pos.x + offsetX, pos.y + offsetY, pos.z)); - g_map.addThing(missile, pos); - } else if (effectType == Otc::MAGIC_EFFECTS_CREATE_DISTANCEEFFECT_REVERSED) { - uint8_t shotId = msg->getU8(); - int8_t offsetX = static_cast(msg->getU8()); - int8_t offsetY = static_cast(msg->getU8()); - if (!g_things.isValidDatId(shotId, ThingCategoryMissile)) { - g_logger.traceError(stdext::format("invalid missile id %d", shotId)); - return; - } - - MissilePtr missile = MissilePtr(new Missile()); - missile->setId(shotId); - missile->setPath(Position(pos.x + offsetX, pos.y + offsetY, pos.z), pos); - g_map.addThing(missile, pos); - } else if (effectType == Otc::MAGIC_EFFECTS_CREATE_EFFECT) { - uint8_t effectId = msg->getU8(); - if (!g_things.isValidDatId(effectId, ThingCategoryEffect)) { - g_logger.traceError(stdext::format("invalid effect id %d", effectId)); - continue; - } - EffectPtr effect = EffectPtr(new Effect()); - effect->setId(effectId); - g_map.addThing(effect, pos); - } - effectType = (Otc::MagicEffectsType_t)msg->getU8(); - } - return; - } - - int effectId; - if (g_game.getFeature(Otc::GameMagicEffectU16)) - effectId = msg->getU16(); - else - effectId = msg->getU8(); - - if (!g_things.isValidDatId(effectId, ThingCategoryEffect)) { - g_logger.traceError(stdext::format("invalid effect id %d", effectId)); - return; - } - - EffectPtr effect = EffectPtr(new Effect()); - effect->setId(effectId); - g_map.addThing(effect, pos); -} - -void ProtocolGame::parseAnimatedText(const InputMessagePtr& msg) -{ - Position position = getPosition(msg); - int color = msg->getU8(); - std::string text = msg->getString(); - - AnimatedTextPtr animatedText = AnimatedTextPtr(new AnimatedText); - animatedText->setColor(color); - animatedText->setText(text); - g_map.addThing(animatedText, position); -} - -void ProtocolGame::parseDistanceMissile(const InputMessagePtr& msg) -{ - Position fromPos = getPosition(msg); - Position toPos = getPosition(msg); - int shotId; - if (g_game.getFeature(Otc::GameDistanceEffectU16)) - shotId = msg->getU16(); - else - shotId = msg->getU8(); - - if (!g_things.isValidDatId(shotId, ThingCategoryMissile)) { - g_logger.traceError(stdext::format("invalid missile id %d", shotId)); - return; - } - - MissilePtr missile = MissilePtr(new Missile()); - missile->setId(shotId); - missile->setPath(fromPos, toPos); - g_map.addThing(missile, fromPos); -} - -void ProtocolGame::parseCreatureMark(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - int color = msg->getU8(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->addTimedSquare(color); - else - g_logger.traceError("could not get creature"); -} - -void ProtocolGame::parseTrappers(const InputMessagePtr& msg) -{ - int numTrappers = msg->getU8(); - - if (numTrappers > 8) - g_logger.traceError("too many trappers"); - - for (int i = 0; i < numTrappers; ++i) { - uint id = msg->getU32(); - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) { - //TODO: set creature as trapper - } else - g_logger.traceError("could not get creature"); - } -} - -void ProtocolGame::parseCreatureHealth(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - int healthPercent = msg->getU8(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->setHealthPercent(healthPercent); - - // some servers has a bug in get spectators and sends unknown creatures updates - // so this code is disabled - /* - else - g_logger.traceError("could not get creature"); - */ -} - -void ProtocolGame::parseCreatureLight(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - - Light light; - light.intensity = msg->getU8(); - light.color = msg->getU8(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->setLight(light); - else - g_logger.traceError("could not get creature"); -} - -void ProtocolGame::parseCreatureOutfit(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - Outfit outfit = getOutfit(msg); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->setOutfit(outfit); - else - g_logger.traceError("could not get creature"); -} - -void ProtocolGame::parseCreatureSpeed(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - - int baseSpeed = -1; - if (g_game.getClientVersion() >= 1059) - baseSpeed = msg->getU16(); - - int speed = msg->getU16(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) { - creature->setSpeed(speed); - if (baseSpeed != -1) - creature->setBaseSpeed(baseSpeed); - } - - // some servers has a bug in get spectators and sends unknown creatures updates - // so this code is disabled - /* - else - g_logger.traceError("could not get creature"); - */ -} - -void ProtocolGame::parseCreatureSkulls(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - int skull = msg->getU8(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->setSkull(skull); - else - g_logger.traceError("could not get creature"); -} - -void ProtocolGame::parseCreatureShields(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - int shield = msg->getU8(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->setShield(shield); - else - g_logger.traceError("could not get creature"); -} - -void ProtocolGame::parseCreatureUnpass(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - bool unpass = msg->getU8(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->setPassable(!unpass); - else - g_logger.traceError("could not get creature"); -} - -void ProtocolGame::parseEditText(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - - int itemId; - if (g_game.getClientVersion() >= 1010) { - // TODO: processEditText with ItemPtr as parameter - ItemPtr item = getItem(msg); - itemId = item->getId(); - } else - itemId = msg->getU16(); - - int maxLength = msg->getU16(); - std::string text = msg->getString(); - - std::string writer = msg->getString(); - - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() > 1240) - msg->getU8(); - - std::string date = ""; - if (g_game.getFeature(Otc::GameWritableDate)) - date = msg->getString(); - - g_game.processEditText(id, itemId, maxLength, text, writer, date); -} - -void ProtocolGame::parseEditList(const InputMessagePtr& msg) -{ - int doorId = msg->getU8(); - uint id = msg->getU32(); - const std::string& text = msg->getString(); - - g_game.processEditList(id, doorId, text); -} - -void ProtocolGame::parsePremiumTrigger(const InputMessagePtr& msg) -{ - int triggerCount = msg->getU8(); - std::vector triggers; - for (int i = 0; i < triggerCount; ++i) { - triggers.push_back(msg->getU8()); - } - - if (g_game.getClientVersion() <= 1096) { - /*bool something = */msg->getU8()/* == 1*/; - } -} - -void ProtocolGame::parsePreyFreeRolls(const InputMessagePtr& msg) -{ - int slot = msg->getU8(); - int timeLeft = msg->getU16(); - - g_lua.callGlobalField("g_game", "onPreyFreeRolls", slot, timeLeft); -} - -void ProtocolGame::parsePreyTimeLeft(const InputMessagePtr& msg) -{ - int slot = msg->getU8(); - int timeLeft = msg->getU16(); - - g_lua.callGlobalField("g_game", "onPreyTimeLeft", slot, timeLeft); -} - -void ProtocolGame::parsePreyData(const InputMessagePtr& msg) -{ - int slot = msg->getU8(); - Otc::PreyState_t state = (Otc::PreyState_t)msg->getU8(); - if (state == Otc::PREY_STATE_LOCKED) { - Otc::PreyUnlockState_t unlockState = (Otc::PreyUnlockState_t)msg->getU8(); - int timeUntilFreeReroll = g_game.getClientVersion() >= 1252 ? msg->getU32() : msg->getU16(); - uint8_t lockType = g_game.getFeature(Otc::GameTibia12Protocol) ? msg->getU8() : 0; - return g_lua.callGlobalField("g_game", "onPreyLocked", slot, unlockState, timeUntilFreeReroll, lockType); - } else if (state == Otc::PREY_STATE_INACTIVE) { - int timeUntilFreeReroll = g_game.getClientVersion() >= 1252 ? msg->getU32() : msg->getU16(); - uint8_t lockType = g_game.getFeature(Otc::GameTibia12Protocol) ? msg->getU8() : 0; - return g_lua.callGlobalField("g_game", "onPreyInactive", slot, timeUntilFreeReroll, lockType); - } else if (state == Otc::PREY_STATE_ACTIVE) { - std::string currentHolderName = msg->getString(); - Outfit currentHolderOutfit = getOutfit(msg, true); - Otc::PreyBonusType_t bonusType = (Otc::PreyBonusType_t)msg->getU8(); - int bonusValue = msg->getU16(); - int bonusGrade = msg->getU8(); - int timeLeft = msg->getU16(); - int timeUntilFreeReroll = g_game.getClientVersion() >= 1252 ? msg->getU32() : msg->getU16(); - uint8_t lockType = g_game.getFeature(Otc::GameTibia12Protocol) ? msg->getU8() : 0; - return g_lua.callGlobalField("g_game", "onPreyActive", slot, currentHolderName, currentHolderOutfit, bonusType, bonusValue, bonusGrade, timeLeft, timeUntilFreeReroll, lockType); - } else if (state == Otc::PREY_STATE_SELECTION || state == Otc::PREY_STATE_SELECTION_CHANGE_MONSTER) { - Otc::PreyBonusType_t bonusType = Otc::PREY_BONUS_NONE; - int bonusValue = -1, bonusGrade = -1; - if (state == Otc::PREY_STATE_SELECTION_CHANGE_MONSTER) { - bonusType = (Otc::PreyBonusType_t)msg->getU8(); - bonusValue = msg->getU16(); - bonusGrade = msg->getU8(); - } - std::vector names; - std::vector outfits; - int selectionSize = msg->getU8(); - for (int i = 0; i < selectionSize; ++i) { - names.push_back(msg->getString()); - outfits.push_back(getOutfit(msg, true)); - } - int timeUntilFreeReroll = g_game.getClientVersion() >= 1252 ? msg->getU32() : msg->getU16(); - uint8_t lockType = g_game.getFeature(Otc::GameTibia12Protocol) ? msg->getU8() : 0; - return g_lua.callGlobalField("g_game", "onPreySelection", slot, bonusType, bonusValue, bonusGrade, names, outfits, timeUntilFreeReroll, lockType); - } else if (state == Otc::PREY_ACTION_CHANGE_FROM_ALL) { - Otc::PreyBonusType_t bonusType = (Otc::PreyBonusType_t)msg->getU8(); - int bonusValue = msg->getU16(); - int bonusGrade = msg->getU8(); - int count = msg->getU16(); - std::vector races; - for (int i = 0; i < count; ++i) { - races.push_back(msg->getU16()); - } - int timeUntilFreeReroll = g_game.getClientVersion() >= 1252 ? msg->getU32() : msg->getU16(); - uint8_t lockType = g_game.getFeature(Otc::GameTibia12Protocol) ? msg->getU8() : 0; - return g_lua.callGlobalField("g_game", "onPreyChangeFromAll", slot, bonusType, bonusValue, bonusGrade, races, timeUntilFreeReroll, lockType); - } else if (state == Otc::PREY_STATE_SELECTION_FROMALL) { - int count = msg->getU16(); - std::vector races; - for (int i = 0; i < count; ++i) { - races.push_back(msg->getU16()); - } - int timeUntilFreeReroll = g_game.getClientVersion() >= 1252 ? msg->getU32() : msg->getU16(); - uint8_t lockType = g_game.getFeature(Otc::GameTibia12Protocol) ? msg->getU8() : 0; - return g_lua.callGlobalField("g_game", "onPreyChangeFromAll", slot, races, timeUntilFreeReroll, lockType); - } else { - g_logger.error(stdext::format("Unknown prey data state: %i", (int)state)); - } -} - - -void ProtocolGame::parsePreyPrices(const InputMessagePtr& msg) -{ - int price = msg->getU32(); - int wildcard = -1, directly = -1; - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - wildcard = msg->getU8(); - directly = msg->getU8(); - if (g_game.getProtocolVersion() >= 1230) { - msg->getU32(); - msg->getU32(); - msg->getU8(); - msg->getU8(); - } - } - g_lua.callGlobalField("g_game", "onPreyPrice", price, wildcard, directly); -} - -void ProtocolGame::parseStoreOfferDescription(const InputMessagePtr& msg) -{ - msg->getU32(); // offer id - msg->getString(); // description -} - - -void ProtocolGame::parsePlayerInfo(const InputMessagePtr& msg) -{ - bool premium = msg->getU8(); // premium - if (g_game.getFeature(Otc::GamePremiumExpiration)) - /*int premiumEx = */msg->getU32(); // premium expiration used for premium advertisement - int vocation = msg->getU8(); // vocation - - if (g_game.getFeature(Otc::GamePrey)) { - /*bool preyEnabled = */msg->getU8()/* > 0*/; - } - - int spellCount = msg->getU16(); - std::vector spells; - for (int i = 0; i < spellCount; ++i) - spells.push_back(msg->getU8()); // spell id - - m_localPlayer->setPremium(premium); - m_localPlayer->setVocation(vocation); - m_localPlayer->setSpells(spells); -} - -void ProtocolGame::parsePlayerStats(const InputMessagePtr& msg) -{ - double health; - double maxHealth; - - if (g_game.getFeature(Otc::GameDoubleHealth)) { - health = msg->getU32(); - maxHealth = msg->getU32(); - } else { - health = msg->getU16(); - maxHealth = msg->getU16(); - } - - double freeCapacity; - if (g_game.getFeature(Otc::GameDoubleFreeCapacity)) - freeCapacity = msg->getU32() / 100.0; - else - freeCapacity = msg->getU16() / 100.0; - - double totalCapacity = freeCapacity; - if (g_game.getFeature(Otc::GameTotalCapacity) && !g_game.getFeature(Otc::GameTibia12Protocol)) - totalCapacity = msg->getU32() / 100.0; - - double experience; - if (g_game.getFeature(Otc::GameDoubleExperience)) - experience = msg->getU64(); - else - experience = msg->getU32(); - - double level; - if (g_game.getFeature(Otc::GameDoubleLevel)) - level = msg->getU32(); - else - level = msg->getU16(); - - double levelPercent = msg->getU8(); - - if (g_game.getFeature(Otc::GameExperienceBonus)) { - if (g_game.getClientVersion() <= 1096) { - /*double experienceBonus = */msg->getDouble(); - } else { - /*int baseXpGain = */msg->getU16(); - if (!g_game.getFeature(Otc::GameTibia12Protocol)) { - /*int voucherAddend = */msg->getU16(); - } - /*int grindingAddend = */msg->getU16(); - /*int storeBoostAddend = */ msg->getU16(); - /*int huntingBoostFactor = */ msg->getU16(); - } - } - - double mana; - double maxMana; - - if (g_game.getFeature(Otc::GameDoubleHealth)) { - mana = msg->getU32(); - maxMana = msg->getU32(); - } else { - mana = msg->getU16(); - maxMana = msg->getU16(); - } - - double magicLevel = 0; - if (!g_game.getFeature(Otc::GameTibia12Protocol)) { - if (g_game.getFeature(Otc::GameDoubleMagicLevel)) - magicLevel = msg->getU16(); - else - magicLevel = msg->getU8(); - } - - double baseMagicLevel = 0; - if (!g_game.getFeature(Otc::GameTibia12Protocol)) { - if (g_game.getFeature(Otc::GameSkillsBase)) - baseMagicLevel = msg->getU8(); - else - baseMagicLevel = magicLevel; - } - - double magicLevelPercent = 0; - if (!g_game.getFeature(Otc::GameTibia12Protocol)) - magicLevelPercent = msg->getU8(); - - double soul; - if (g_game.getFeature(Otc::GameDoubleSoul)) - soul = msg->getU16(); - else - soul = msg->getU8(); - - double stamina = 0; - if (g_game.getFeature(Otc::GamePlayerStamina)) - stamina = msg->getU16(); - - double baseSpeed = 0; - if (g_game.getFeature(Otc::GameSkillsBase)) - baseSpeed = msg->getU16(); - - double regeneration = 0; - if (g_game.getFeature(Otc::GamePlayerRegenerationTime)) - regeneration = msg->getU16(); - - double training = 0; - if (g_game.getFeature(Otc::GameOfflineTrainingTime)) { - training = msg->getU16(); - if (g_game.getClientVersion() >= 1097) { - /*int remainingStoreXpBoostSeconds = */msg->getU16(); - /*bool canBuyMoreStoreXpBoosts = */msg->getU8(); - } - } - - m_localPlayer->setHealth(health, maxHealth); - m_localPlayer->setFreeCapacity(freeCapacity); - if (!g_game.getFeature(Otc::GameTibia12Protocol)) - m_localPlayer->setTotalCapacity(totalCapacity); - m_localPlayer->setExperience(experience); - m_localPlayer->setLevel(level, levelPercent); - m_localPlayer->setMana(mana, maxMana); - if (!g_game.getFeature(Otc::GameTibia12Protocol)) { - m_localPlayer->setMagicLevel(magicLevel, magicLevelPercent); - m_localPlayer->setBaseMagicLevel(baseMagicLevel); - } - m_localPlayer->setStamina(stamina); - m_localPlayer->setSoul(soul); - m_localPlayer->setBaseSpeed(baseSpeed); - m_localPlayer->setRegenerationTime(regeneration); - m_localPlayer->setOfflineTrainingTime(training); -} - -void ProtocolGame::parsePlayerSkills(const InputMessagePtr& msg) -{ - int lastSkill = Otc::Fishing + 1; - if (g_game.getFeature(Otc::GameAdditionalSkills)) - lastSkill = Otc::LastSkill; - - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - int level = msg->getU16(); - int baseLevel = msg->getU16(); - msg->getU16(); // unknown - int levelPercent = msg->getU16(); - m_localPlayer->setMagicLevel(level, levelPercent); - m_localPlayer->setBaseMagicLevel(baseLevel); - } - - for (int skill = 0; skill < lastSkill; skill++) { - int level; - - if (g_game.getFeature(Otc::GameDoubleSkills)) - level = msg->getU16(); - else - level = msg->getU8(); - - int baseLevel; - if (g_game.getFeature(Otc::GameSkillsBase)) - if (g_game.getFeature(Otc::GameBaseSkillU16)) - baseLevel = msg->getU16(); - else - baseLevel = msg->getU8(); - else - baseLevel = level; - - int levelPercent = 0; - // Critical, Life Leech and Mana Leech have no level percent - if (skill <= Otc::Fishing) { - if (g_game.getFeature(Otc::GameTibia12Protocol)) - msg->getU16(); // unknown - - if (g_game.getFeature(Otc::GameTibia12Protocol)) - levelPercent = msg->getU16(); - else - levelPercent = msg->getU8(); - } - - m_localPlayer->setSkill((Otc::Skill)skill, level, levelPercent); - m_localPlayer->setBaseSkill((Otc::Skill)skill, baseLevel); - } - - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - uint32_t totalCapacity = msg->getU32(); - msg->getU32(); // base capacity? - m_localPlayer->setTotalCapacity(totalCapacity); - } -} - -void ProtocolGame::parsePlayerState(const InputMessagePtr& msg) -{ - int states; - if (g_game.getFeature(Otc::GamePlayerStateU32)) - states = msg->getU32(); - else if (g_game.getFeature(Otc::GamePlayerStateU16)) - states = msg->getU16(); - else - states = msg->getU8(); - - m_localPlayer->setStates(states); -} - -void ProtocolGame::parsePlayerCancelAttack(const InputMessagePtr& msg) -{ - uint seq = 0; - if (g_game.getFeature(Otc::GameAttackSeq)) - seq = msg->getU32(); - - g_game.processAttackCancel(seq); -} - - -void ProtocolGame::parsePlayerModes(const InputMessagePtr& msg) -{ - int fightMode = msg->getU8(); - int chaseMode = msg->getU8(); - bool safeMode = msg->getU8(); - - int pvpMode = 0; - if (g_game.getFeature(Otc::GamePVPMode)) - pvpMode = msg->getU8(); - - g_game.processPlayerModes((Otc::FightModes)fightMode, (Otc::ChaseModes)chaseMode, safeMode, (Otc::PVPModes)pvpMode); -} - -void ProtocolGame::parseSpellCooldown(const InputMessagePtr& msg) -{ - int spellId = msg->getU8(); - int delay = msg->getU32(); - - g_lua.callGlobalField("g_game", "onSpellCooldown", spellId, delay); -} - -void ProtocolGame::parseSpellGroupCooldown(const InputMessagePtr& msg) -{ - int groupId = msg->getU8(); - int delay = msg->getU32(); - - g_lua.callGlobalField("g_game", "onSpellGroupCooldown", groupId, delay); -} - -void ProtocolGame::parseMultiUseCooldown(const InputMessagePtr& msg) -{ - int delay = msg->getU32(); - - g_lua.callGlobalField("g_game", "onMultiUseCooldown", delay); -} - -void ProtocolGame::parseTalk(const InputMessagePtr& msg) -{ - uint32_t statement = 0; - if (g_game.getFeature(Otc::GameMessageStatements)) - statement = msg->getU32(); // channel statement guid - - std::string name = g_game.formatCreatureName(msg->getString()); - - if (statement > 0 && g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() > 1240) - msg->getU8(); - - int level = 0; - if (g_game.getFeature(Otc::GameMessageLevel)) { - if (g_game.getFeature(Otc::GameDoubleLevel)) { - level = msg->getU32(); - } else { - level = msg->getU16(); - } - } - - Otc::MessageMode mode = Proto::translateMessageModeFromServer(msg->getU8()); - int channelId = 0; - Position pos; - - switch (mode) { - case Otc::MessageSay: - case Otc::MessageWhisper: - case Otc::MessageYell: - case Otc::MessageMonsterSay: - case Otc::MessageMonsterYell: - case Otc::MessageNpcTo: - case Otc::MessageBarkLow: - case Otc::MessageBarkLoud: - case Otc::MessageSpell: - case Otc::MessageNpcFromStartBlock: - pos = getPosition(msg); - break; - case Otc::MessageChannel: - case Otc::MessageChannelManagement: - case Otc::MessageChannelHighlight: - case Otc::MessageGamemasterChannel: - channelId = msg->getU16(); - break; - case Otc::MessageNpcFrom: - case Otc::MessagePrivateFrom: - case Otc::MessageGamemasterBroadcast: - case Otc::MessageGamemasterPrivateFrom: - case Otc::MessageRVRAnswer: - case Otc::MessageRVRContinue: - break; - case Otc::MessageRVRChannel: - msg->getU32(); - break; - default: - stdext::throw_exception(stdext::format("unknown message mode %d", mode)); - break; - } - - std::string text = msg->getString(); - - g_game.processTalk(name, level, mode, text, channelId, pos); -} - -void ProtocolGame::parseChannelList(const InputMessagePtr& msg) -{ - int count = msg->getU8(); - std::vector > channelList; - for (int i = 0; i < count; i++) { - int id = msg->getU16(); - std::string name = msg->getString(); - channelList.push_back(std::make_tuple(id, name)); - } - - g_game.processChannelList(channelList); -} - -void ProtocolGame::parseOpenChannel(const InputMessagePtr& msg) -{ - int channelId = msg->getU16(); - std::string name = msg->getString(); - - if (g_game.getFeature(Otc::GameChannelPlayerList)) { - int joinedPlayers = msg->getU16(); - for (int i = 0; i < joinedPlayers; ++i) - g_game.formatCreatureName(msg->getString()); // player name - int invitedPlayers = msg->getU16(); - for (int i = 0; i < invitedPlayers; ++i) - g_game.formatCreatureName(msg->getString()); // player name - } - - g_game.processOpenChannel(channelId, name); -} - -void ProtocolGame::parseOpenPrivateChannel(const InputMessagePtr& msg) -{ - std::string name = g_game.formatCreatureName(msg->getString()); - - g_game.processOpenPrivateChannel(name); -} - -void ProtocolGame::parseOpenOwnPrivateChannel(const InputMessagePtr& msg) -{ - int channelId = msg->getU16(); - std::string name = msg->getString(); - - if (g_game.getFeature(Otc::GameChannelPlayerList)) { - int joinedPlayers = msg->getU16(); - for (int i = 0; i < joinedPlayers; ++i) - g_game.formatCreatureName(msg->getString()); // player name - int invitedPlayers = msg->getU16(); - for (int i = 0; i < invitedPlayers; ++i) - g_game.formatCreatureName(msg->getString()); // player name - } - - g_game.processOpenOwnPrivateChannel(channelId, name); -} - -void ProtocolGame::parseCloseChannel(const InputMessagePtr& msg) -{ - int channelId = msg->getU16(); - - g_game.processCloseChannel(channelId); -} - -void ProtocolGame::parseRuleViolationChannel(const InputMessagePtr& msg) -{ - int channelId = msg->getU16(); - - g_game.processRuleViolationChannel(channelId); -} - -void ProtocolGame::parseRuleViolationRemove(const InputMessagePtr& msg) -{ - std::string name = msg->getString(); - - g_game.processRuleViolationRemove(name); -} - -void ProtocolGame::parseRuleViolationCancel(const InputMessagePtr& msg) -{ - std::string name = msg->getString(); - - g_game.processRuleViolationCancel(name); -} - -void ProtocolGame::parseRuleViolationLock(const InputMessagePtr& msg) -{ - g_game.processRuleViolationLock(); -} - -void ProtocolGame::parseTextMessage(const InputMessagePtr& msg) -{ - int code = msg->getU8(); - Otc::MessageMode mode = Proto::translateMessageModeFromServer(code); - std::string text; - - switch (mode) { - case Otc::MessageChannelManagement: - { - /*int channel = */msg->getU16(); - text = msg->getString(); - break; - } - case Otc::MessageGuild: - case Otc::MessagePartyManagement: - case Otc::MessageParty: - { - /*int channel = */msg->getU16(); - text = msg->getString(); - break; - } - case Otc::MessageDamageDealed: - case Otc::MessageDamageReceived: - case Otc::MessageDamageOthers: - { - Position pos = getPosition(msg); - uint value[2]; - int color[2]; - - // physical damage - value[0] = msg->getU32(); - color[0] = msg->getU8(); - - // magic damage - value[1] = msg->getU32(); - color[1] = msg->getU8(); - text = msg->getString(); - - for (int i = 0; i < 2; ++i) { - if (value[i] == 0) - continue; - AnimatedTextPtr animatedText = AnimatedTextPtr(new AnimatedText); - animatedText->setColor(color[i]); - animatedText->setText(stdext::to_string(value[i])); - g_map.addThing(animatedText, pos); - } - break; - } - case Otc::MessageHeal: - case Otc::MessageMana: - case Otc::MessageExp: - case Otc::MessageHealOthers: - case Otc::MessageExpOthers: - { - Position pos = getPosition(msg); - uint value = msg->getU32(); - int color = msg->getU8(); - text = msg->getString(); - - AnimatedTextPtr animatedText = AnimatedTextPtr(new AnimatedText); - animatedText->setColor(color); - animatedText->setText(stdext::to_string(value)); - g_map.addThing(animatedText, pos); - break; - } - case Otc::MessageInvalid: - stdext::throw_exception(stdext::format("unknown message mode %d", mode)); - break; - default: - text = msg->getString(); - break; - } - - g_game.processTextMessage(mode, text); -} - -void ProtocolGame::parseCancelWalk(const InputMessagePtr& msg) -{ - Otc::Direction direction = (Otc::Direction)msg->getU8(); - - g_game.processWalkCancel(direction); -} - -void ProtocolGame::parseWalkWait(const InputMessagePtr& msg) -{ - int millis = msg->getU16(); - m_localPlayer->lockWalk(millis); -} - -void ProtocolGame::parseFloorChangeUp(const InputMessagePtr& msg) -{ - Position pos; - if (g_game.getFeature(Otc::GameMapMovePosition)) - pos = getPosition(msg); - else - pos = g_map.getCentralPosition(); - AwareRange range = g_map.getAwareRange(); - pos.z--; - - Position newPos = pos; - newPos.x++; - newPos.y++; - g_map.setCentralPosition(newPos); - - int skip = 0; - if (pos.z == Otc::SEA_FLOOR) - for (int i = Otc::SEA_FLOOR - Otc::AWARE_UNDEGROUND_FLOOR_RANGE; i >= 0; i--) - skip = setFloorDescription(msg, pos.x - range.left, pos.y - range.top, i, range.horizontal(), range.vertical(), 8 - i, skip); - else if (pos.z > Otc::SEA_FLOOR) - skip = setFloorDescription(msg, pos.x - range.left, pos.y - range.top, pos.z - Otc::AWARE_UNDEGROUND_FLOOR_RANGE, range.horizontal(), range.vertical(), 3, skip); - -} - -void ProtocolGame::parseFloorChangeDown(const InputMessagePtr& msg) -{ - Position pos; - if (g_game.getFeature(Otc::GameMapMovePosition)) - pos = getPosition(msg); - else - pos = g_map.getCentralPosition(); - AwareRange range = g_map.getAwareRange(); - pos.z++; - - Position newPos = pos; - newPos.x--; - newPos.y--; - g_map.setCentralPosition(newPos); - - int skip = 0; - if (pos.z == Otc::UNDERGROUND_FLOOR) { - int j, i; - for (i = pos.z, j = -1; i <= pos.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE; ++i, --j) - skip = setFloorDescription(msg, pos.x - range.left, pos.y - range.top, i, range.horizontal(), range.vertical(), j, skip); - } else if (pos.z > Otc::UNDERGROUND_FLOOR && pos.z < Otc::MAX_Z - 1) - skip = setFloorDescription(msg, pos.x - range.left, pos.y - range.top, pos.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE, range.horizontal(), range.vertical(), -3, skip); -} - -void ProtocolGame::parseOpenOutfitWindow(const InputMessagePtr& msg) -{ - Outfit currentOutfit = getOutfit(msg); - std::vector > outfitList; - - if (g_game.getFeature(Otc::GameNewOutfitProtocol)) { - int outfitCount = g_game.getFeature(Otc::GameTibia12Protocol) ? msg->getU16() : msg->getU8(); - for (int i = 0; i < outfitCount; i++) { - int outfitId = msg->getU16(); - std::string outfitName = msg->getString(); - int outfitAddons = msg->getU8(); - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - bool locked = msg->getU8() > 0; - if (locked) { - msg->getU32(); // store offer id - } - } - outfitList.push_back(std::make_tuple(outfitId, outfitName, outfitAddons)); - } - } else { - int outfitStart, outfitEnd; - if (g_game.getFeature(Otc::GameLooktypeU16)) { - outfitStart = msg->getU16(); - outfitEnd = msg->getU16(); - } else { - outfitStart = msg->getU8(); - outfitEnd = msg->getU8(); - } - - for (int i = outfitStart; i <= outfitEnd; i++) - outfitList.push_back(std::make_tuple(i, "", 0)); - } - - std::vector > mountList; - std::vector > wingList; - std::vector > auraList; - std::vector > shaderList; - if (g_game.getFeature(Otc::GamePlayerMounts)) { - int mountCount = g_game.getFeature(Otc::GameTibia12Protocol) ? msg->getU16() : msg->getU8(); - for (int i = 0; i < mountCount; ++i) { - int mountId = msg->getU16(); // mount type - std::string mountName = msg->getString(); // mount name - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - bool locked = msg->getU8() > 0; - if (locked) { - msg->getU32(); // store offer id - } - } - - mountList.push_back(std::make_tuple(mountId, mountName)); - } - } - - if (g_game.getFeature(Otc::GameWingsAndAura)) { - int wingCount = msg->getU8(); - for (int i = 0; i < wingCount; ++i) { - int wingId = msg->getU16(); - std::string wingName = msg->getString(); - wingList.push_back(std::make_tuple(wingId, wingName)); - } - int auraCount = msg->getU8(); - for (int i = 0; i < auraCount; ++i) { - int auraId = msg->getU16(); - std::string auraName = msg->getString(); - auraList.push_back(std::make_tuple(auraId, auraName)); - } - } - - if (g_game.getFeature(Otc::GameOutfitShaders)) { - int shaderCount = msg->getU8(); - for (int i = 0; i < shaderCount; ++i) { - int shaderId = msg->getU16(); - std::string shaderName = msg->getString(); - shaderList.push_back(std::make_tuple(shaderId, shaderName)); - } - } - - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - msg->getU8(); // tryOnMount, tryOnOutfit - msg->getU8(); // mounted? - } - - g_game.processOpenOutfitWindow(currentOutfit, outfitList, mountList, wingList, auraList, shaderList); -} - -void ProtocolGame::parseVipAdd(const InputMessagePtr& msg) -{ - uint id, iconId = 0, status; - std::string name, desc = ""; - bool notifyLogin = false; - - id = msg->getU32(); - name = g_game.formatCreatureName(msg->getString()); - if (g_game.getFeature(Otc::GameAdditionalVipInfo)) { - desc = msg->getString(); - iconId = msg->getU32(); - notifyLogin = msg->getU8(); - } - status = msg->getU8(); - - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - int groups = msg->getU8(); - for (int i = 0; i < groups; ++i) - msg->getU8(); // group id - } - - g_game.processVipAdd(id, name, status, desc, iconId, notifyLogin); -} - -void ProtocolGame::parseVipState(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - if (g_game.getFeature(Otc::GameLoginPending)) { - uint status = msg->getU8(); - g_game.processVipStateChange(id, status); - } else { - g_game.processVipStateChange(id, 1); - } -} - -void ProtocolGame::parseVipLogout(const InputMessagePtr& msg) -{ - uint id = msg->getU32(); - g_game.processVipStateChange(id, 0); -} - -void ProtocolGame::parseVipGroupData(const InputMessagePtr& msg) -{ - int size = msg->getU8(); - for (int i = 0; i < size; ++i) { - msg->getU8(); // group id - msg->getString(); // group name - msg->getU8(); // unkown - } - - msg->getU8(); // max vip groups -} - -void ProtocolGame::parseTutorialHint(const InputMessagePtr& msg) -{ - int id = msg->getU8(); - g_game.processTutorialHint(id); -} - -void ProtocolGame::parseCyclopediaMapData(const InputMessagePtr& msg) -{ - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - int type = msg->getU8(); - switch (type) { - case 0: - break; - case 1: - { - int count = msg->getU16(); - for (int i = 0; i < count; ++i) { - msg->getU8(); - msg->getU8(); - msg->getU8(); - msg->getU8(); - } - count = msg->getU16(); - for (int i = 0; i < count; ++i) { - msg->getU16(); - } - count = msg->getU16(); - for (int i = 0; i < count; ++i) { - msg->getU16(); - } - break; - } - case 2: // raid - { - getPosition(msg); - msg->getU8(); - break; - } - case 3: - { - msg->getU8(); - msg->getU8(); - msg->getU8(); - break; - } - case 4: - { - msg->getU8(); - msg->getU8(); - msg->getU8(); - break; - } - case 5: - { - msg->getU16(); - msg->getU8(); - int count = msg->getU8(); - for (int i = 0; i < count; ++i) { - getPosition(msg); - msg->getU8(); - } - break; - } - case 6: - { - break; - } - case 7: - { - break; - } - case 8: - { - break; - } - case 9: - { - msg->getU32(); - msg->getU32(); - int count = msg->getU8(); - for (int i = 0; i < count; ++i) { - msg->getU16(); - msg->getU32(); - msg->getU32(); - msg->getU8(); - } - } - case 10: - { - msg->getU16(); - break; - } - case 11: - { - break; - } - } - if (type != 0) - return; - } - - Position pos = getPosition(msg); - int icon = msg->getU8(); - std::string description = msg->getString(); - - bool remove = false; - if (g_game.getFeature(Otc::GameMinimapRemove)) - remove = msg->getU8() != 0; - - if (!remove) - g_game.processAddAutomapFlag(pos, icon, description); - else - g_game.processRemoveAutomapFlag(pos, icon, description); -} - -void ProtocolGame::parseQuestLog(const InputMessagePtr& msg) -{ - std::vector > questList; - int questsCount = msg->getU16(); - for (int i = 0; i < questsCount; i++) { - int id = msg->getU16(); - std::string name = msg->getString(); - bool completed = msg->getU8(); - questList.push_back(std::make_tuple(id, name, completed)); - } - - g_game.processQuestLog(questList); -} - -void ProtocolGame::parseQuestLine(const InputMessagePtr& msg) -{ - std::vector> questMissions; - int questId = msg->getU16(); - int missionCount = msg->getU8(); - for (int i = 0; i < missionCount; i++) { - if (g_game.getFeature(Otc::GameTibia12Protocol)) - msg->getU16(); // mission id - - std::string missionName = msg->getString(); - std::string missionDescrition = msg->getString(); - questMissions.push_back(std::make_tuple(missionName, missionDescrition)); - } - - g_game.processQuestLine(questId, questMissions); -} - -void ProtocolGame::parseChannelEvent(const InputMessagePtr& msg) -{ - uint16 channelId = msg->getU16(); - std::string name = g_game.formatCreatureName(msg->getString()); - uint8 type = msg->getU8(); - - g_lua.callGlobalField("g_game", "onChannelEvent", channelId, name, type); -} - -void ProtocolGame::parseItemInfo(const InputMessagePtr& msg) -{ - std::vector> list; - int size = msg->getU8(); - for (int i = 0; i < size; ++i) { - ItemPtr item(new Item); - item->setId(msg->getU16()); - item->setCountOrSubType(g_game.getFeature(Otc::GameCountU16) ? msg->getU16() : msg->getU8()); - - std::string desc = msg->getString(); - list.push_back(std::make_tuple(item, desc)); - } - - g_lua.callGlobalField("g_game", "onItemInfo", list); -} - -void ProtocolGame::parsePlayerInventory(const InputMessagePtr& msg) -{ - int size = msg->getU16(); - for (int i = 0; i < size; ++i) { - msg->getU16(); // id - msg->getU8(); // subtype - msg->getU16(); // count - } -} - -void ProtocolGame::parseModalDialog(const InputMessagePtr& msg) -{ - uint32 id = msg->getU32(); - std::string title = msg->getString(); - std::string message = msg->getString(); - - int sizeButtons = msg->getU8(); - std::vector > buttonList; - for (int i = 0; i < sizeButtons; ++i) { - std::string value = msg->getString(); - int id = msg->getU8(); - buttonList.push_back(std::make_tuple(id, value)); - } - - int sizeChoices = msg->getU8(); - std::vector > choiceList; - for (int i = 0; i < sizeChoices; ++i) { - std::string value = msg->getString(); - int id = msg->getU8(); - choiceList.push_back(std::make_tuple(id, value)); - } - - int enterButton, escapeButton; - if (g_game.getClientVersion() > 970) { - escapeButton = msg->getU8(); - enterButton = msg->getU8(); - } else { - enterButton = msg->getU8(); - escapeButton = msg->getU8(); - } - - bool priority = msg->getU8() == 0x01; - - g_game.processModalDialog(id, title, message, buttonList, enterButton, escapeButton, choiceList, priority); -} - -void ProtocolGame::parseClientCheck(const InputMessagePtr& msg) -{ - msg->getU32(); - msg->getU8(); -} - -void ProtocolGame::parseGameNews(const InputMessagePtr& msg) -{ - msg->getU32(); - msg->getU8(); -} - -void ProtocolGame::parseMessageDialog(const InputMessagePtr& msg) -{ - msg->getU8(); - msg->getString(); -} - -void ProtocolGame::parseBlessDialog(const InputMessagePtr& msg) -{ - // parse bless amount - uint8_t totalBless = msg->getU8(); // total bless - - // parse each bless - for (int i = 0; i < totalBless; i++) { - msg->getU16(); // bless bit wise - msg->getU8(); // player bless count - if (g_game.getClientVersion() >= 1220) { - msg->getU8(); // store? - } - } - - // parse general info - msg->getU8(); // premium - msg->getU8(); // promotion - msg->getU8(); // pvp min xp loss - msg->getU8(); // pvp max xp loss - msg->getU8(); // pve exp loss - msg->getU8(); // equip pvp loss - msg->getU8(); // equip pve loss - msg->getU8(); // skull - msg->getU8(); // aol - - // parse log - uint8_t logCount = msg->getU8(); // log count - for (int i = 0; i < logCount; i++) { - msg->getU32(); // timestamp - msg->getU8(); // color message (0 = white loss, 1 = red) - msg->getString(); // history message - } -} - -void ProtocolGame::parseResourceBalance(const InputMessagePtr& msg) -{ - uint8_t type = msg->getU8(); - uint64_t amount = msg->getU64(); - g_lua.callGlobalField("g_game", "onResourceBalance", type, amount); -} - -void ProtocolGame::parseServerTime(const InputMessagePtr& msg) -{ - uint8_t minutes = msg->getU8(); - uint8_t seconds = msg->getU8(); - g_lua.callGlobalField("g_game", "onServerTime", minutes, seconds); -} - -void ProtocolGame::parseQuestTracker(const InputMessagePtr& msg) -{ - msg->getU8(); - msg->getU16(); -} - -void ProtocolGame::parseImbuementWindow(const InputMessagePtr& msg) -{ - int itemId = msg->getU16(); - int slots = msg->getU8(); - - std::map> activeSlots; - for (int i = 0; i < slots; ++i) { - bool info = msg->getU8() == 1; - if (info) { - Imbuement imbuement = getImbuementInfo(msg); - int duration = msg->getU32(); - int removalCost = msg->getU32(); - activeSlots[i] = std::make_tuple(imbuement, duration, removalCost); - } - } - - int imbuements_size = msg->getU16(); - std::vector imbuements; - for (int i = 0; i < imbuements_size; ++i) { - imbuements.push_back(getImbuementInfo(msg)); - } - - std::vector needItems; - int needItems_count = msg->getU32(); - for (int i = 0; i < needItems_count; ++i) { - int item = msg->getU16(); - int count = msg->getU16(); - needItems.push_back(Item::create(item, count)); - } - - g_lua.callGlobalField("g_game", "onImbuementWindow", itemId, slots, activeSlots, imbuements, needItems); -} - -void ProtocolGame::parseCloseImbuementWindow(const InputMessagePtr&) -{ - g_lua.callGlobalField("g_game", "onCloseImbuementWindow"); -} - -void ProtocolGame::parseCyclopedia(const InputMessagePtr& msg) -{ - msg->getU16(); // race id -} - -void ProtocolGame::parseCyclopediaNewDetails(const InputMessagePtr& msg) -{ - g_logger.info("parseCyclopediaNewDetails should be implemented in lua"); -} - -void ProtocolGame::parseDailyRewardState(const InputMessagePtr& msg) -{ - msg->getU8(); // state -} - -void ProtocolGame::parseOpenRewardWall(const InputMessagePtr& msg) -{ - msg->getU8(); // bonus shrine (1) or instant bonus (0) - msg->getU32(); // next reward time - msg->getU8(); // day streak day - uint8_t wasDailyRewardTaken = msg->getU8(); // taken (player already took reward?) - - if (wasDailyRewardTaken) { - msg->getString(); // error message - } - - msg->getU32(); // time left to pickup reward without loosing streak - msg->getU16(); // day streak level - msg->getU16(); // unknown -} - -void ProtocolGame::parseDailyReward(const InputMessagePtr& msg) -{ - uint8_t count = msg->getU8(); // state - - // TODO: implement daily reward usage -} - -void ProtocolGame::parseDailyRewardHistory(const InputMessagePtr& msg) -{ - uint8_t historyCount = msg->getU8(); // history count - - for (int i = 0; i < historyCount; i++) { - msg->getU32(); // timestamp - msg->getU8(); // is Premium - msg->getString(); // description - msg->getU16(); // daystreak - } - - // TODO: implement reward history usage -} - -Imbuement ProtocolGame::getImbuementInfo(const InputMessagePtr& msg) -{ - Imbuement i; - i.id = msg->getU32(); - i.name = msg->getString(); - i.description = msg->getString(); - i.group = msg->getString(); - i.imageId = msg->getU16(); - i.duration = msg->getU32(); - i.premiumOnly = msg->getU8() > 0; - int size = msg->getU8(); - for (int j = 0; j < size; ++j) { - int id = msg->getU16(); - std::string description = msg->getString(); - int count = msg->getU16(); - i.sources.push_back(std::make_pair(Item::create(id, count), description)); - } - i.cost = msg->getU32(); - i.successRate = msg->getU8(); - i.protectionCost = msg->getU32(); - return i; -} - -void ProtocolGame::parseLootContainers(const InputMessagePtr& msg) -{ - msg->getU8(); // quickLootFallbackToMainContainer ? 1 : 0 - int containers = msg->getU8(); - for (int i = 0; i < containers; ++i) { - msg->getU8(); // id? - msg->getU16(); - } -} - -void ProtocolGame::parseSupplyStash(const InputMessagePtr& msg) -{ - int size = msg->getU16(); - for (int i = 0; i < size; ++i) { - msg->getU16(); // item id - msg->getU32(); // unknown - } - msg->getU16(); // available slots? -} - -void ProtocolGame::parseSpecialContainer(const InputMessagePtr& msg) -{ - msg->getU8(); - if (g_game.getProtocolVersion() >= 1220) { - msg->getU8(); - } -} - -void ProtocolGame::parseDepotState(const InputMessagePtr& msg) -{ - msg->getU8(); // unknown, true/false - if (g_game.getProtocolVersion() >= 1230) { - msg->getU8(); // unknown - } -} - -void ProtocolGame::parseTournamentLeaderboard(const InputMessagePtr& msg) -{ - msg->getU8(); - msg->getU8(); -} - -void ProtocolGame::parseKillTracker(const InputMessagePtr& msg) -{ - msg->getString(); - msg->getU16(); - msg->getU8(); - msg->getU8(); - msg->getU8(); - msg->getU8(); - msg->getU8(); - int corpseSize = msg->getU8(); // corpse size - for (int i = 0; i < corpseSize; i++) { - getItem(msg); // corpse item - } -} - -void ProtocolGame::parseSupplyTracker(const InputMessagePtr& msg) -{ - msg->getU16(); -} - -void ProtocolGame::parseImpactTracker(const InputMessagePtr& msg) -{ - msg->getU8(); - msg->getU32(); -} - -void ProtocolGame::parseItemsPrices(const InputMessagePtr& msg) -{ - uint16_t count = msg->getU16(); - for (uint16_t i = 0; i < count; ++i) { - /*uint16_t itemId = */msg->getU16(); - /*uint32_t price = */msg->getU32(); - } -} - -void ProtocolGame::parseLootTracker(const InputMessagePtr& msg) -{ - msg->getU8(); - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() >= 1220) { - msg->getU8(); - } - msg->getU8(); - msg->getString(); - getItem(msg); - msg->getU8(); - - uint8_t count = msg->getU8(); - for (uint8_t i = 0; i < count; ++i) { - msg->getString(); - msg->getString(); - } -} - -void ProtocolGame::parseItemDetail(const InputMessagePtr& msg) -{ - getItem(msg); - msg->getString(); // item name -} - -void ProtocolGame::parseHunting(const InputMessagePtr& msg) -{ - -} - -void ProtocolGame::parseExtendedOpcode(const InputMessagePtr& msg) -{ - int opcode = msg->getU8(); - std::string buffer = msg->getString(); - - if (opcode == 0) - m_enableSendExtendedOpcode = true; - else - callLuaField("onExtendedOpcode", opcode, buffer); -} - -void ProtocolGame::parseChangeMapAwareRange(const InputMessagePtr& msg) -{ - int xrange = msg->getU8(); - int yrange = msg->getU8(); - - AwareRange range; - range.left = xrange / 2; - range.right = xrange / 2 + 1; - range.top = yrange / 2; - range.bottom = yrange / 2 + 1; - - g_map.setAwareRange(range); - g_lua.callGlobalField("g_game", "onMapChangeAwareRange", xrange, yrange); -} - -void ProtocolGame::parseProgressBar(const InputMessagePtr& msg) -{ - uint32 id = msg->getU32(); - uint32 duration = msg->getU32(); - bool ltr = msg->getU8(); - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->setProgressBar(duration, ltr); - else - g_logger.traceError(stdext::format("could not get creature with id %d", id)); -} - -void ProtocolGame::parseFeatures(const InputMessagePtr& msg) -{ - int features = msg->getU16(); - for (int i = 0; i < features; ++i) { - Otc::GameFeature feature = (Otc::GameFeature)msg->getU8(); - bool enabled = msg->getU8() > 0; - if (enabled) { - g_game.enableFeature(feature); - } else { - g_game.disableFeature(feature); - } - } -} - -void ProtocolGame::parseCreaturesMark(const InputMessagePtr& msg) -{ - int len; - if (g_game.getClientVersion() >= 1035) { - len = 1; - } else { - len = msg->getU8(); - } - - for (int i = 0; i < len; ++i) { - uint32 id = msg->getU32(); - bool isPermanent = msg->getU8() != 1; - uint8 markType = msg->getU8(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) { - if (isPermanent) { - if (markType == 0xff) - creature->hideStaticSquare(); - else - creature->showStaticSquare(Color::from8bit(markType)); - } else - creature->addTimedSquare(markType); - } else - g_logger.traceError("could not get creature"); - } -} - -void ProtocolGame::parseCreatureType(const InputMessagePtr& msg) -{ - uint32 id = msg->getU32(); - uint8 type = msg->getU8(); - - if (g_game.getFeature(Otc::GameTibia12Protocol) && type == Proto::CreatureTypeSummonOwn) - msg->getU32(); - - CreaturePtr creature = g_map.getCreatureById(id); - if (creature) - creature->setType(type); - else - g_logger.traceError("could not get creature"); -} - -void ProtocolGame::parseNewCancelWalk(const InputMessagePtr& msg) -{ - Otc::Direction direction = (Otc::Direction)msg->getU8(); - g_game.processNewWalkCancel(direction); -} - -void ProtocolGame::parsePredictiveCancelWalk(const InputMessagePtr& msg) -{ - Position pos = getPosition(msg); - Otc::Direction direction = (Otc::Direction)msg->getU8(); - g_game.processPredictiveWalkCancel(pos, direction); -} - -void ProtocolGame::parseWalkId(const InputMessagePtr& msg) -{ - g_game.processWalkId(msg->getU32()); -} - -void ProtocolGame::parseProcessesRequest(const InputMessagePtr&) -{ - sendProcesses(); -} - -void ProtocolGame::parseDllsRequest(const InputMessagePtr&) -{ - sendDlls(); -} - -void ProtocolGame::parseWindowsRequest(const InputMessagePtr&) -{ - sendWindows(); -} - - -void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height) -{ - int startz, endz, zstep; - - if (z > Otc::SEA_FLOOR) { - startz = z - Otc::AWARE_UNDEGROUND_FLOOR_RANGE; - endz = std::min(z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE, (int)Otc::MAX_Z); - zstep = 1; - } else { - startz = Otc::SEA_FLOOR; - endz = 0; - zstep = -1; - } - - int skip = 0; - for (int nz = startz; nz != endz + zstep; nz += zstep) - skip = setFloorDescription(msg, x, y, nz, width, height, z - nz, skip); -} - -int ProtocolGame::setFloorDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height, int offset, int skip) -{ - for (int nx = 0; nx < width; nx++) { - for (int ny = 0; ny < height; ny++) { - Position tilePos(x + nx + offset, y + ny + offset, z); - if (skip == 0) - skip = setTileDescription(msg, tilePos); - else { - g_map.cleanTile(tilePos); - skip--; - } - } - } - return skip; -} - -int ProtocolGame::setTileDescription(const InputMessagePtr& msg, Position position) -{ - g_map.cleanTile(position); - if (msg->peekU16() >= 0xff00) - return msg->getU16() & 0xff; - - if (g_game.getFeature(Otc::GameNewWalking)) { - uint16_t groundSpeed = msg->getU16(); - uint8_t blocking = msg->getU8(); - g_map.setTileSpeed(position, groundSpeed, blocking); - } - - if (g_game.getFeature(Otc::GameEnvironmentEffect) && !g_game.getFeature(Otc::GameTibia12Protocol)) { - msg->getU16(); - } - - for (int stackPos = 0; stackPos < 256; stackPos++) { - if (msg->peekU16() >= 0xff00) - return msg->getU16() & 0xff; - - if (stackPos > 10) - g_logger.traceError(stdext::format("too many things, pos=%s, stackpos=%d", stdext::to_string(position), stackPos)); - - ThingPtr thing = getThing(msg); - g_map.addThing(thing, position, stackPos); - } - - return 0; -} - -Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg, bool ignoreMount) -{ - Outfit outfit; - - int lookType; - if (g_game.getFeature(Otc::GameLooktypeU16)) - lookType = msg->getU16(); - else - lookType = msg->getU8(); - - if (lookType != 0) { - outfit.setCategory(ThingCategoryCreature); - int head = msg->getU8(); - int body = msg->getU8(); - int legs = msg->getU8(); - int feet = msg->getU8(); - int addons = 0; - if (g_game.getFeature(Otc::GamePlayerAddons)) - addons = msg->getU8(); - - if (!g_things.isValidDatId(lookType, ThingCategoryCreature)) { - g_logger.traceError(stdext::format("invalid outfit looktype %d", lookType)); - lookType = 0; - } - - outfit.setId(lookType); - outfit.setHead(head); - outfit.setBody(body); - outfit.setLegs(legs); - outfit.setFeet(feet); - outfit.setAddons(addons); - } else { - int lookTypeEx = msg->getU16(); - if (lookTypeEx == 0) { - outfit.setCategory(ThingCategoryEffect); - outfit.setAuxId(13); // invisible effect id - } else { - if (!g_things.isValidDatId(lookTypeEx, ThingCategoryItem)) { - g_logger.traceError(stdext::format("invalid outfit looktypeex %d", lookTypeEx)); - lookTypeEx = 0; - } - outfit.setCategory(ThingCategoryItem); - outfit.setAuxId(lookTypeEx); - } - } - - if (!ignoreMount) { - if (g_game.getFeature(Otc::GamePlayerMounts)) { - outfit.setMount(msg->getU16()); - } - if (g_game.getFeature(Otc::GameWingsAndAura)) { - outfit.setWings(msg->getU16()); - outfit.setAura(msg->getU16()); - } - if (g_game.getFeature(Otc::GameOutfitShaders)) { - outfit.setShader(msg->getString()); - } - } - - return outfit; -} - -ThingPtr ProtocolGame::getThing(const InputMessagePtr& msg) -{ - ThingPtr thing; - - int id = msg->getU16(); - - if (id == 0) - stdext::throw_exception("invalid thing id (0)"); - else if (id == Proto::UnknownCreature || id == Proto::OutdatedCreature || id == Proto::Creature) - thing = getCreature(msg, id); - else if (id == Proto::StaticText) // otclient only - thing = getStaticText(msg, id); - else // item - thing = getItem(msg, id, false); - - return thing; -} - -ThingPtr ProtocolGame::getMappedThing(const InputMessagePtr& msg) -{ - ThingPtr thing; - uint16 x = msg->getU16(); - - if (x != 0xffff) { - Position pos; - pos.x = x; - pos.y = msg->getU16(); - pos.z = msg->getU8(); - uint8 stackpos = msg->getU8(); - - VALIDATE(stackpos != 255); - thing = g_map.getThing(pos, stackpos); - if (!thing) - g_logger.traceError(stdext::format("no thing at pos:%s, stackpos:%d", stdext::to_string(pos), stackpos)); - } else { - uint32 id = msg->getU32(); - thing = g_map.getCreatureById(id); - if (!thing) - g_logger.traceError(stdext::format("no creature with id %u", id)); - } - - return thing; -} - -CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type) -{ - if (type == 0) - type = msg->getU16(); - - CreaturePtr creature; - bool known = (type != Proto::UnknownCreature); - if (type == Proto::OutdatedCreature || type == Proto::UnknownCreature) { - if (known) { - uint id = msg->getU32(); - creature = g_map.getCreatureById(id); - if (!creature) - g_logger.traceError("server said that a creature is known, but it's not"); - } else { - uint removeId = msg->getU32(); - uint id = msg->getU32(); - if (id == removeId) { - creature = g_map.getCreatureById(id); - } else { - g_map.removeCreatureById(removeId); - } - - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getClientVersion() >= 1252) - msg->getU8(); - - int creatureType; - if (g_game.getClientVersion() >= 910) - creatureType = msg->getU8(); - else { - if (id >= Proto::PlayerStartId && id < Proto::PlayerEndId) - creatureType = Proto::CreatureTypePlayer; - else if (id >= Proto::MonsterStartId && id < Proto::MonsterEndId) - creatureType = Proto::CreatureTypeMonster; - else - creatureType = Proto::CreatureTypeNpc; - } - - if (g_game.getFeature(Otc::GameTibia12Protocol) && creatureType == Proto::CreatureTypeSummonOwn) - msg->getU32(); // master - - std::string name = g_game.formatCreatureName(msg->getString()); - - if (creature) { - creature->setName(name); - } else { - if (id == m_localPlayer->getId()) - creature = m_localPlayer; - else if (creatureType == Proto::CreatureTypePlayer) { - // fixes a bug server side bug where GameInit is not sent and local player id is unknown - if (m_localPlayer->getId() == 0 && name == m_localPlayer->getName()) - creature = m_localPlayer; - else - creature = PlayerPtr(new Player); - } else if (creatureType == Proto::CreatureTypeMonster) - creature = MonsterPtr(new Monster); - else if (creatureType == Proto::CreatureTypeNpc) - creature = NpcPtr(new Npc); - else if (creatureType == Proto::CreatureTypeSummonOwn) { - creature = MonsterPtr(new Monster); - } else - g_logger.traceError("creature type is invalid"); - - if (creature) { - creature->setId(id); - creature->setName(name); - - g_map.addCreature(creature); - } - } - } - - int healthPercent = msg->getU8(); - Otc::Direction direction = (Otc::Direction)msg->getU8(); - Outfit outfit = getOutfit(msg); - - Light light; - light.intensity = msg->getU8(); - light.color = msg->getU8(); - - int speed = msg->getU16(); - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getClientVersion() >= 1240) - msg->getU8(); - int skull = msg->getU8(); - int shield = msg->getU8(); - - // emblem is sent only when the creature is not known - int8 emblem = -1; - int8 creatureType = -1; - int8 icon = -1; - bool unpass = true; - uint8 mark; - - if (g_game.getFeature(Otc::GameCreatureEmblems) && !known) - emblem = msg->getU8(); - - if (g_game.getFeature(Otc::GameThingMarks)) { - creatureType = msg->getU8(); - if (g_game.getFeature(Otc::GameTibia12Protocol)) { - if (creatureType == Proto::CreatureTypeSummonOwn) - msg->getU32(); // master - if (g_game.getClientVersion() >= 1215 && creatureType == Proto::CreatureTypePlayer) - msg->getU8(); // vocation id - } - } - - if (g_game.getFeature(Otc::GameCreatureIcons)) { - icon = msg->getU8(); - } - - if (g_game.getFeature(Otc::GameThingMarks)) { - mark = msg->getU8(); // mark - if (g_game.getFeature(Otc::GameTibia12Protocol)) - msg->getU8(); // inspection? - else - msg->getU16(); // helpers? - - if (creature) { - if (mark == 0xff) - creature->hideStaticSquare(); - else - creature->showStaticSquare(Color::from8bit(mark)); - } - } - - if (g_game.getClientVersion() >= 854 || g_game.getFeature(Otc::GameCreatureWalkthrough)) - unpass = msg->getU8(); - - if (creature) { - creature->setHealthPercent(healthPercent); - creature->setDirection(direction); - creature->setOutfit(outfit); - creature->setSpeed(speed); - creature->setSkull(skull); - creature->setShield(shield); - creature->setPassable(!unpass); - creature->setLight(light); - - if (emblem != -1) - creature->setEmblem(emblem); - - if (creatureType != -1) - creature->setType(creatureType); - - if (icon != -1) - creature->setIcon(icon); - - if (creature == m_localPlayer && !m_localPlayer->isKnown()) - m_localPlayer->setKnown(true); - } - } else if (type == Proto::Creature) { - uint id = msg->getU32(); - creature = g_map.getCreatureById(id); - - if (!creature) - g_logger.traceError("invalid creature"); - - Otc::Direction direction = (Otc::Direction)msg->getU8(); - if (creature) { - if (creature != g_game.getLocalPlayer() || !g_game.isIgnoringServerDirection() || !g_game.getFeature(Otc::GameNewWalking)) { - creature->turn(direction); - } - } - - if (g_game.getClientVersion() >= 953 || g_game.getFeature(Otc::GameCreatureDirectionPassable)) { - bool unpass = msg->getU8(); - - if (creature) - creature->setPassable(!unpass); - } - - } else { - stdext::throw_exception("invalid creature opcode"); - } - - return creature; -} - -ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id, bool hasDescription) -{ - if (id == 0) - id = msg->getU16(); - - ItemPtr item = Item::create(id); - if (item->getId() == 0) - stdext::throw_exception(stdext::format("unable to create item with invalid id %d", id)); - - if (g_game.getFeature(Otc::GameThingMarks) && !g_game.getFeature(Otc::GameTibia12Protocol)) { - msg->getU8(); // mark - } - - if (item->isStackable() || item->isFluidContainer() || item->isSplash() || item->isChargeable()) - item->setCountOrSubType(g_game.getFeature(Otc::GameCountU16) ? msg->getU16() : msg->getU8()); - else if (item->rawGetThingType()->isContainer() && g_game.getFeature(Otc::GameTibia12Protocol)) { - // not sure about this part - uint8_t hasQuickLootFlags = msg->getU8(); - if (hasQuickLootFlags > 0) - msg->getU32(); // quick loot flags - } - - if (g_game.getFeature(Otc::GameItemAnimationPhase)) { - if (item->getAnimationPhases() > 1) { - // 0x00 => automatic phase - // 0xFE => random phase - // 0xFF => async phase - msg->getU8(); - //item->setPhase(msg->getU8()); - } - } - - if (g_game.getFeature(Otc::GameItemTooltip) && hasDescription) { - item->setTooltip(msg->getString()); - } - - return item; -} - -StaticTextPtr ProtocolGame::getStaticText(const InputMessagePtr& msg, int id) -{ - int colorByte = msg->getU8(); - Color color = Color::from8bit(colorByte); - std::string fontName = msg->getString(); - std::string text = msg->getString(); - StaticTextPtr staticText = StaticTextPtr(new StaticText); - staticText->setText(text); - staticText->setFont(fontName); - staticText->setColor(color); - return staticText; -} - -Position ProtocolGame::getPosition(const InputMessagePtr& msg) -{ - uint16 x = msg->getU16(); - uint16 y = msg->getU16(); - uint8 z = msg->getU8(); - - return Position(x, y, z); -} diff --git a/src/client/protocolgamesend.cpp b/src/client/protocolgamesend.cpp deleted file mode 100644 index def3f2c..0000000 --- a/src/client/protocolgamesend.cpp +++ /dev/null @@ -1,1213 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "protocolgame.h" -#include "game.h" -#include "client.h" -#include -#include -#include -#include - -void ProtocolGame::send(const OutputMessagePtr& outputMessage, bool rawPacket) -{ - // avoid usage of automated sends (bot modules) - if(!g_game.checkBotProtection()) - return; - Protocol::send(outputMessage, rawPacket); -} - -void ProtocolGame::sendExtendedOpcode(uint8 opcode, const std::string& buffer) -{ - g_game.enableBotCall(); - if(m_enableSendExtendedOpcode) { - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientExtendedOpcode); - msg->addU8(opcode); - msg->addString(buffer); - send(msg); - } else { - g_logger.error(stdext::format("Unable to send extended opcode %d, extended opcodes are not enabled on this server.", opcode)); - } - g_game.disableBotCall(); -} - -void ProtocolGame::sendWorldName() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addRawString(m_worldName + "\n"); - send(msg, true); -} - -void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRandom) -{ - OutputMessagePtr msg(new OutputMessage); - - msg->addU8(Proto::ClientPendingGame); - msg->addU16(g_game.getOs()); - msg->addU16(g_game.getCustomProtocolVersion()); - - if (g_game.getFeature(Otc::GameClientVersion)) - msg->addU32(g_game.getClientVersion()); - - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() >= 1240) - msg->addString(std::to_string(g_game.getClientVersion())); - - if (g_game.getFeature(Otc::GameContentRevision)) - msg->addU16(g_things.getContentRevision()); - - if (g_game.getFeature(Otc::GamePreviewState)) - msg->addU8(0); - - int offset = msg->getMessageSize(); - // first RSA byte must be 0 - msg->addU8(0); - - if (g_game.getFeature(Otc::GameLoginPacketEncryption)) { - // xtea key - generateXteaKey(); - msg->addU32(m_xteaKey[0]); - msg->addU32(m_xteaKey[1]); - msg->addU32(m_xteaKey[2]); - msg->addU32(m_xteaKey[3]); - msg->addU8(0); // is gm set? - } - - if (g_game.getFeature(Otc::GameSessionKey)) { - msg->addString(m_sessionKey); - msg->addString(m_characterName); - } else { - if (g_game.getFeature(Otc::GameAccountNames)) - msg->addString(m_accountName); - else - msg->addU32(stdext::from_string(m_accountName)); - - msg->addString(m_characterName); - msg->addString(m_accountPassword); - - if (g_game.getFeature(Otc::GameAuthenticator)) - msg->addString(m_authenticatorToken); - } - - if (g_game.getFeature(Otc::GameChallengeOnLogin)) { - msg->addU32(challengeTimestamp); - msg->addU8(challengeRandom); - } - - std::string extended = callLuaField("getLoginExtendedData"); - if (!extended.empty()) { - msg->addString(extended); - } else { - msg->addString(std::string("OTCv8")); - std::string version = g_app.getVersion(); - version = stdext::split(version, " ")[0]; - stdext::replace_all(version, ".", ""); - if (version.length() == 2) { - version += "0"; - } - msg->addU16(atoi(version.c_str())); - } - - // encrypt with RSA - if (g_game.getFeature(Otc::GameLoginPacketEncryption)) { - int paddingBytes = g_crypt.rsaGetSize() - (msg->getMessageSize() - offset); - VALIDATE(paddingBytes >= 0); - msg->addPaddingBytes(paddingBytes); - msg->encryptRsa(); - } - - if (g_game.getFeature(Otc::GameSendIdentifiers)) { - std::string user = g_platform.getUserName().substr(0, 20); - std::string cpu = g_platform.getCPUName().substr(0, 20); - uint32_t memory = (g_platform.getTotalSystemMemory() / (1024 * 1024)); - auto macs = g_platform.getMacAddresses(); - if (macs.size() > 4) { - macs.resize(4); - } - - offset = msg->getMessageSize(); - msg->addU8(0); // first RSA byte must be 0 - msg->addString(user); // max 22 bytes - msg->addString(cpu); // max 22 bytes - msg->addU32(memory); - msg->addU8(macs.size()); - for (auto& mac : macs) { - msg->addString(mac); // 18 bytes - } - if (g_game.getFeature(Otc::GameLoginPacketEncryption)) { - int paddingBytes = g_crypt.rsaGetSize() - (msg->getMessageSize() - offset); - VALIDATE(paddingBytes >= 0); - msg->addPaddingBytes(paddingBytes); - msg->encryptRsa(); - } - } - - if(g_game.getFeature(Otc::GameProtocolChecksum)) - enableChecksum(); - - send(msg); - - if(g_game.getFeature(Otc::GameLoginPacketEncryption)) - enableXteaEncryption(); - - if (g_game.getFeature(Otc::GamePacketCompression)) - enableCompression(); - - if (g_game.getFeature(Otc::GameSequencedPackets)) - enabledSequencedPackets(); -} - -void ProtocolGame::sendEnterGame() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientEnterGame); - send(msg); -} - -void ProtocolGame::sendLogout() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientLeaveGame); - send(msg); -} - -void ProtocolGame::sendPing() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientPing); - Protocol::send(msg); -} - -void ProtocolGame::sendPingBack() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientPingBack); - send(msg); -} - -void ProtocolGame::sendNewPing(uint32_t pingId, uint16_t localPing, uint16_t fps) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientNewPing); - msg->addU32(pingId); - msg->addU16(localPing); - msg->addU16(fps); - send(msg); -} - -void ProtocolGame::sendAutoWalk(const std::vector& path) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientAutoWalk); - msg->addU8(path.size()); - for(Otc::Direction dir : path) { - uint8 byte; - switch(dir) { - case Otc::East: - byte = 1; - break; - case Otc::NorthEast: - byte = 2; - break; - case Otc::North: - byte = 3; - break; - case Otc::NorthWest: - byte = 4; - break; - case Otc::West: - byte = 5; - break; - case Otc::SouthWest: - byte = 6; - break; - case Otc::South: - byte = 7; - break; - case Otc::SouthEast: - byte = 8; - break; - default: - byte = 0; - break; - } - msg->addU8(byte); - } - send(msg); -} - -void ProtocolGame::sendWalkNorth() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWalkNorth); - send(msg); -} - -void ProtocolGame::sendWalkEast() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWalkEast); - send(msg); -} - -void ProtocolGame::sendWalkSouth() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWalkSouth); - send(msg); -} - -void ProtocolGame::sendWalkWest() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWalkWest); - send(msg); -} - -void ProtocolGame::sendStop() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientStop); - send(msg); -} - -void ProtocolGame::sendWalkNorthEast() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWalkNorthEast); - send(msg); -} - -void ProtocolGame::sendWalkSouthEast() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWalkSouthEast); - send(msg); -} - -void ProtocolGame::sendWalkSouthWest() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWalkSouthWest); - send(msg); -} - -void ProtocolGame::sendWalkNorthWest() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWalkNorthWest); - send(msg); -} - -void ProtocolGame::sendTurnNorth() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientTurnNorth); - send(msg); -} - -void ProtocolGame::sendTurnEast() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientTurnEast); - send(msg); -} - -void ProtocolGame::sendTurnSouth() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientTurnSouth); - send(msg); -} - -void ProtocolGame::sendTurnWest() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientTurnWest); - send(msg); -} - -void ProtocolGame::sendEquipItem(int itemId, int countOrSubType) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientEquipItem); - msg->addU16(itemId); - if (g_game.getFeature(Otc::GameCountU16)) - msg->addU16(countOrSubType); - else - msg->addU8(countOrSubType); - send(msg); -} - -void ProtocolGame::sendMove(const Position& fromPos, int thingId, int stackpos, const Position& toPos, int count) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientMove); - addPosition(msg, fromPos); - msg->addU16(thingId); - msg->addU8(stackpos); - addPosition(msg, toPos); - if(g_game.getFeature(Otc::GameCountU16)) - msg->addU16(count); - else - msg->addU8(count); - send(msg); -} - -void ProtocolGame::sendInspectNpcTrade(int itemId, int count) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientInspectNpcTrade); - msg->addU16(itemId); - if (g_game.getFeature(Otc::GameCountU16)) - msg->addU16(count); - else - msg->addU8(count); - send(msg); -} - -void ProtocolGame::sendBuyItem(int itemId, int subType, int amount, bool ignoreCapacity, bool buyWithBackpack) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientBuyItem); - msg->addU16(itemId); - msg->addU8(subType); - msg->addU8(amount); - msg->addU8(ignoreCapacity ? 0x01 : 0x00); - msg->addU8(buyWithBackpack ? 0x01 : 0x00); - send(msg); -} - -void ProtocolGame::sendSellItem(int itemId, int subType, int amount, bool ignoreEquipped) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientSellItem); - msg->addU16(itemId); - msg->addU8(subType); - if(g_game.getFeature(Otc::GameDoubleShopSellAmount)) - msg->addU16(amount); - else - msg->addU8(amount); - msg->addU8(ignoreEquipped ? 0x01 : 0x00); - send(msg); -} - -void ProtocolGame::sendCloseNpcTrade() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientCloseNpcTrade); - send(msg); -} - -void ProtocolGame::sendRequestTrade(const Position& pos, int thingId, int stackpos, uint creatureId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRequestTrade); - addPosition(msg, pos); - msg->addU16(thingId); - msg->addU8(stackpos); - msg->addU32(creatureId); - send(msg); -} - -void ProtocolGame::sendInspectTrade(bool counterOffer, int index) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientInspectTrade); - msg->addU8(counterOffer ? 0x01 : 0x00); - msg->addU8(index); - send(msg); -} - -void ProtocolGame::sendAcceptTrade() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientAcceptTrade); - send(msg); -} - -void ProtocolGame::sendRejectTrade() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRejectTrade); - send(msg); -} - -void ProtocolGame::sendUseItem(const Position& position, int itemId, int stackpos, int index) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientUseItem); - addPosition(msg, position); - msg->addU16(itemId); - msg->addU8(stackpos); - msg->addU8(index); - send(msg); -} - -void ProtocolGame::sendUseItemWith(const Position& fromPos, int itemId, int fromStackPos, const Position& toPos, int toThingId, int toStackPos) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientUseItemWith); - addPosition(msg, fromPos); - msg->addU16(itemId); - msg->addU8(fromStackPos); - addPosition(msg, toPos); - msg->addU16(toThingId); - msg->addU8(toStackPos); - send(msg); -} - -void ProtocolGame::sendUseOnCreature(const Position& pos, int thingId, int stackpos, uint creatureId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientUseOnCreature); - addPosition(msg, pos); - msg->addU16(thingId); - msg->addU8(stackpos); - msg->addU32(creatureId); - send(msg); -} - -void ProtocolGame::sendRotateItem(const Position& pos, int thingId, int stackpos) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRotateItem); - addPosition(msg, pos); - msg->addU16(thingId); - msg->addU8(stackpos); - send(msg); -} - -void ProtocolGame::sendWrapableItem(const Position& pos, int thingId, int stackpos) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWrapableItem); - addPosition(msg, pos); - msg->addU16(thingId); - msg->addU8(stackpos); - send(msg); -} - -void ProtocolGame::sendCloseContainer(int containerId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientCloseContainer); - msg->addU8(containerId); - send(msg); -} - -void ProtocolGame::sendUpContainer(int containerId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientUpContainer); - msg->addU8(containerId); - send(msg); -} - -void ProtocolGame::sendEditText(uint id, const std::string& text) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientEditText); - msg->addU32(id); - msg->addString(text); - send(msg); -} - -void ProtocolGame::sendEditList(uint id, int doorId, const std::string& text) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientEditList); - msg->addU8(doorId); - msg->addU32(id); - msg->addString(text); - send(msg); -} - -void ProtocolGame::sendLook(const Position& position, int thingId, int stackpos) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientLook); - addPosition(msg, position); - msg->addU16(thingId); - msg->addU8(stackpos); - send(msg); -} - -void ProtocolGame::sendLookCreature(uint32 creatureId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientLookCreature); - msg->addU32(creatureId); - send(msg); -} - -void ProtocolGame::sendTalk(Otc::MessageMode mode, int channelId, const std::string& receiver, const std::string& message, const Position& pos, Otc::Direction dir) -{ - if(message.empty()) - return; - - if(message.length() > 255) { - g_logger.traceError("message too large"); - return; - } - - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientTalk); - msg->addU8(Proto::translateMessageModeToServer(mode)); - - switch(mode) { - case Otc::MessagePrivateTo: - case Otc::MessageGamemasterPrivateTo: - case Otc::MessageRVRAnswer: - msg->addString(receiver); - break; - case Otc::MessageChannel: - case Otc::MessageChannelHighlight: - case Otc::MessageChannelManagement: - case Otc::MessageGamemasterChannel: - msg->addU16(channelId); - break; - default: - break; - } - - msg->addString(message); - - if(g_game.getFeature(Otc::GameNewWalking)) { - // fix for spell direction - addPosition(msg, pos); - uint8 byte; - switch(dir) { - case Otc::East: - case Otc::NorthEast: - case Otc::SouthEast: - byte = 1; - break; - case Otc::North: - byte = 3; - break; - case Otc::SouthWest: - case Otc::NorthWest: - case Otc::West: - byte = 5; - break; - case Otc::South: - byte = 7; - break; - default: - byte = 0; - break; - } - msg->addU8(byte); - } - - send(msg); -} - -void ProtocolGame::sendRequestChannels() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRequestChannels); - send(msg); -} - -void ProtocolGame::sendJoinChannel(int channelId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientJoinChannel); - msg->addU16(channelId); - send(msg); -} - -void ProtocolGame::sendLeaveChannel(int channelId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientLeaveChannel); - msg->addU16(channelId); - send(msg); -} - -void ProtocolGame::sendOpenPrivateChannel(const std::string& receiver) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientOpenPrivateChannel); - msg->addString(receiver); - send(msg); -} - -void ProtocolGame::sendOpenRuleViolation(const std::string& reporter) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientOpenRuleViolation); - msg->addString(reporter); - send(msg); -} - -void ProtocolGame::sendCloseRuleViolation(const std::string& reporter) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientCloseRuleViolation); - msg->addString(reporter); - send(msg); -} - -void ProtocolGame::sendCancelRuleViolation() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientCancelRuleViolation); - send(msg); -} - -void ProtocolGame::sendCloseNpcChannel() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientCloseNpcChannel); - send(msg); -} - -void ProtocolGame::sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight, Otc::PVPModes pvpMode) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientChangeFightModes); - msg->addU8(fightMode); - msg->addU8(chaseMode); - msg->addU8(safeFight ? 0x01: 0x00); - if(g_game.getFeature(Otc::GamePVPMode)) - msg->addU8(pvpMode); - send(msg); -} - -void ProtocolGame::sendAttack(uint creatureId, uint seq) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientAttack); - msg->addU32(creatureId); - if(g_game.getFeature(Otc::GameAttackSeq)) - msg->addU32(seq); - send(msg); -} - -void ProtocolGame::sendFollow(uint creatureId, uint seq) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientFollow); - msg->addU32(creatureId); - if(g_game.getFeature(Otc::GameAttackSeq)) - msg->addU32(seq); - send(msg); -} - -void ProtocolGame::sendInviteToParty(uint creatureId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientInviteToParty); - msg->addU32(creatureId); - send(msg); -} - -void ProtocolGame::sendJoinParty(uint creatureId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientJoinParty); - msg->addU32(creatureId); - send(msg); -} - -void ProtocolGame::sendRevokeInvitation(uint creatureId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRevokeInvitation); - msg->addU32(creatureId); - send(msg); -} - -void ProtocolGame::sendPassLeadership(uint creatureId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientPassLeadership); - msg->addU32(creatureId); - send(msg); -} - -void ProtocolGame::sendLeaveParty() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientLeaveParty); - send(msg); -} - -void ProtocolGame::sendShareExperience(bool active) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientShareExperience); - msg->addU8(active ? 0x01 : 0x00); - if(g_game.getClientVersion() < 910) - msg->addU8(0); - send(msg); -} - -void ProtocolGame::sendOpenOwnChannel() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientOpenOwnChannel); - send(msg); -} - -void ProtocolGame::sendInviteToOwnChannel(const std::string& name) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientInviteToOwnChannel); - msg->addString(name); - send(msg); -} - -void ProtocolGame::sendExcludeFromOwnChannel(const std::string& name) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientExcludeFromOwnChannel); - msg->addString(name); - send(msg); -} - -void ProtocolGame::sendCancelAttackAndFollow() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientCancelAttackAndFollow); - send(msg); -} - -void ProtocolGame::sendRefreshContainer(int containerId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRefreshContainer); - msg->addU8(containerId); - send(msg); -} - -void ProtocolGame::sendRequestOutfit() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRequestOutfit); - send(msg); -} - -void ProtocolGame::sendChangeOutfit(const Outfit& outfit) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientChangeOutfit); - - if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getClientVersion() >= 1220) { - msg->addU8(0); // outfit type - } - - if(g_game.getFeature(Otc::GameLooktypeU16)) - msg->addU16(outfit.getId()); - else - msg->addU8(outfit.getId()); - msg->addU8(outfit.getHead()); - msg->addU8(outfit.getBody()); - msg->addU8(outfit.getLegs()); - msg->addU8(outfit.getFeet()); - if(g_game.getFeature(Otc::GamePlayerAddons)) - msg->addU8(outfit.getAddons()); - if(g_game.getFeature(Otc::GamePlayerMounts)) - msg->addU16(outfit.getMount()); - if (g_game.getFeature(Otc::GameWingsAndAura)) { - msg->addU16(outfit.getWings()); - msg->addU16(outfit.getAura()); - } - if(g_game.getFeature(Otc::GameOutfitShaders)) - msg->addString(outfit.getShader()); - send(msg); -} - -void ProtocolGame::sendOutfitExtensionStatus(int mount, int wings, int aura, int shader) -{ - if(g_game.getFeature(Otc::GamePlayerMounts) || g_game.getFeature(Otc::GameWingsAndAura) || g_game.getFeature(Otc::GameOutfitShaders)) { - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientMount); - if (g_game.getFeature(Otc::GamePlayerMounts)) { - msg->addU8(mount); - } - if (g_game.getFeature(Otc::GameWingsAndAura)) { - msg->addU8(wings); - msg->addU8(aura); - } - if (g_game.getFeature(Otc::GameOutfitShaders)) { - msg->addU8(shader); - } - send(msg); - } else { - g_logger.error("ProtocolGame::sendOutfitExtensionStatus does not support the current protocol."); - } -} - -void ProtocolGame::sendApplyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ApplyImbuemente); - msg->addU8(slot); - msg->addU32(imbuementId); - msg->addU8(protectionCharm ? 1 : 0); - send(msg); -} - -void ProtocolGame::sendClearImbuement(uint8_t slot) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClearingImbuement); - msg->addU8(slot); - send(msg); -} - -void ProtocolGame::sendCloseImbuingWindow() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::CloseImbuingWindow); - send(msg); -} - -void ProtocolGame::sendAddVip(const std::string& name) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientAddVip); - msg->addString(name); - send(msg); -} - -void ProtocolGame::sendRemoveVip(uint playerId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRemoveVip); - msg->addU32(playerId); - send(msg); -} - -void ProtocolGame::sendEditVip(uint playerId, const std::string& description, int iconId, bool notifyLogin) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientEditVip); - msg->addU32(playerId); - msg->addString(description); - msg->addU32(iconId); - msg->addU8(notifyLogin); - send(msg); -} - -void ProtocolGame::sendBugReport(const std::string& comment) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientBugReport); - if (g_game.getClientVersion() > 1000) { - msg->addU8(3); // other - } - msg->addString(comment); - send(msg); -} - -void ProtocolGame::sendRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRuleViolation); - msg->addString(target); - msg->addU8(reason); - msg->addU8(action); - msg->addString(comment); - msg->addString(statement); - msg->addU16(statementId); - msg->addU8(ipBanishment); - send(msg); -} - -void ProtocolGame::sendDebugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientDebugReport); - msg->addString(a); - msg->addString(b); - msg->addString(c); - msg->addString(d); - send(msg); -} - -void ProtocolGame::sendRequestQuestLog() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRequestQuestLog); - send(msg); -} - -void ProtocolGame::sendRequestQuestLine(int questId) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRequestQuestLine); - msg->addU16(questId); - send(msg); -} - -void ProtocolGame::sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientNewRuleViolation); - msg->addU8(reason); - msg->addU8(action); - msg->addString(characterName); - msg->addString(comment); - msg->addString(translation); - send(msg); -} - -void ProtocolGame::sendRequestItemInfo(int itemId, int subType, int index) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRequestItemInfo); - msg->addU8(subType); - msg->addU16(itemId); - msg->addU8(index); - send(msg); -} - -void ProtocolGame::sendAnswerModalDialog(uint32 dialog, int button, int choice) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientAnswerModalDialog); - msg->addU32(dialog); - msg->addU8(button); - msg->addU8(choice); - send(msg); -} - -void ProtocolGame::sendBrowseField(const Position& position) -{ - if(!g_game.getFeature(Otc::GameBrowseField)) - return; - - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientBrowseField); - addPosition(msg, position); - send(msg); -} - -void ProtocolGame::sendSeekInContainer(int cid, int index) -{ - if(!g_game.getFeature(Otc::GameContainerPagination)) - return; - - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientSeekInContainer); - msg->addU8(cid); - msg->addU16(index); - send(msg); -} - -void ProtocolGame::sendBuyStoreOffer(int offerId, int productType, const std::string& name) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientBuyStoreOffer); - msg->addU32(offerId); - msg->addU8(productType); - - if(productType == Otc::ProductTypeNameChange) - msg->addString(name); - - send(msg); -} - -void ProtocolGame::sendRequestTransactionHistory(int page, int entriesPerPage) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRequestTransactionHistory); - if(g_game.getClientVersion() <= 1096) { - msg->addU16(page); - msg->addU32(entriesPerPage); - } else { - msg->addU32(page); - msg->addU8(entriesPerPage); - } - - send(msg); -} - -void ProtocolGame::sendRequestStoreOffers(const std::string& categoryName, int serviceType) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientRequestStoreOffers); - - if(g_game.getFeature(Otc::GameIngameStoreServiceType)) { - msg->addU8(serviceType); - } - msg->addString(categoryName); - - send(msg); -} - -void ProtocolGame::sendOpenStore(int serviceType) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientOpenStore); - - if(g_game.getFeature(Otc::GameIngameStoreServiceType)) { - msg->addU8(serviceType); - } - - send(msg); -} - -void ProtocolGame::sendTransferCoins(const std::string& recipient, int amount) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientTransferCoins); - msg->addString(recipient); - msg->addU16(amount); - send(msg); -} - -void ProtocolGame::sendOpenTransactionHistory(int entriesPerPage) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientOpenTransactionHistory); - msg->addU8(entriesPerPage); - - send(msg); -} - -void ProtocolGame::sendPreyAction(int slot, int actionType, int index) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientPreyAction); - msg->addU8(slot); - msg->addU8(actionType); - if (actionType == 2 || actionType == 5) { - msg->addU8(index); - } else if (actionType == 4) { - msg->addU16(index); // raceid - } - send(msg); -} - -void ProtocolGame::sendPreyRequest() -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientPreyRequest); - send(msg); -} - -void ProtocolGame::sendProcesses() -{ - auto processes = g_platform.getProcesses(); - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientProcessesResponse); - msg->addU16(processes.size()); - for (auto& process : processes) { - msg->addString(process); - } - send(msg); -} - -void ProtocolGame::sendDlls() -{ - auto dlls = g_platform.getDlls(); - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientDllsResponse); - msg->addU16(dlls.size()); - for (auto& dll : dlls) { - msg->addString(dll); - } - send(msg); -} - -void ProtocolGame::sendWindows() -{ - auto dlls = g_platform.getWindows(); - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientWindowsResponse); - msg->addU16(dlls.size()); - for (auto& dll : dlls) { - msg->addString(dll); - } - send(msg); -} - -void ProtocolGame::sendChangeMapAwareRange(int xrange, int yrange) -{ - if(!g_game.getFeature(Otc::GameChangeMapAwareRange)) - return; - - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientChangeMapAwareRange); - msg->addU8(xrange); - msg->addU8(yrange); - send(msg); -} - -void ProtocolGame::sendNewWalk(int walkId, int predictionId, const Position& pos, uint8_t flags, const std::vector& path) -{ - OutputMessagePtr msg(new OutputMessage); - msg->addU8(Proto::ClientNewWalk); - msg->addU32(walkId); - msg->addU32(predictionId); - addPosition(msg, pos); - msg->addU8(flags); - msg->addU16(path.size()); - for(Otc::Direction dir : path) { - uint8 byte; - switch(dir) { - case Otc::East: - byte = 1; - break; - case Otc::NorthEast: - byte = 2; - break; - case Otc::North: - byte = 3; - break; - case Otc::NorthWest: - byte = 4; - break; - case Otc::West: - byte = 5; - break; - case Otc::SouthWest: - byte = 6; - break; - case Otc::South: - byte = 7; - break; - case Otc::SouthEast: - byte = 8; - break; - default: - byte = 0; - break; - } - msg->addU8(byte); - } - - send(msg); -} - -void ProtocolGame::addPosition(const OutputMessagePtr& msg, const Position& position) -{ - msg->addU16(position.x); - msg->addU16(position.y); - msg->addU8(position.z); -} diff --git a/src/client/shadermanager.cpp b/src/client/shadermanager.cpp deleted file mode 100644 index 209e735..0000000 --- a/src/client/shadermanager.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shadermanager.h" -#include -#include -#include -#include - -ShaderManager g_shaders; - -void ShaderManager::init() -{ - PainterShaderProgram::release(); -} - -void ShaderManager::terminate() -{ - m_shaders.clear(); -} - -void ShaderManager::createShader(const std::string& name, std::string vertex, std::string fragment, bool colorMatrix) -{ - if (vertex.find("\n") == std::string::npos) { // file - vertex = g_resources.guessFilePath(vertex, "frag"); - vertex = g_resources.readFileContents(vertex); - } - if (fragment.find("\n") == std::string::npos) { // file - fragment = g_resources.guessFilePath(fragment, "frag"); - fragment = g_resources.readFileContents(fragment); - } - - g_graphicsDispatcher.addEventEx("createShader", [&, name, vertex, fragment, colorMatrix] { - auto program = PainterShaderProgram::create(vertex, fragment, colorMatrix); - if (program) - m_shaders[name] = program; - }); -} - -void ShaderManager::addTexture(const std::string& name, const std::string& file) -{ - g_graphicsDispatcher.addEventEx("addTexture", [&, name, file] { - auto program = getShader(name); - if (program) - program->addMultiTexture(file); - }); -} - -PainterShaderProgramPtr ShaderManager::getShader(const std::string& name) -{ - VALIDATE_GRAPHICS_THREAD(); - auto it = m_shaders.find(name); - if(it != m_shaders.end()) - return it->second; - return nullptr; -} - diff --git a/src/client/shadermanager.h b/src/client/shadermanager.h deleted file mode 100644 index cc0cb10..0000000 --- a/src/client/shadermanager.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SHADERMANAGER_H -#define SHADERMANAGER_H - -#include "declarations.h" -#include - -//@bindsingleton g_shaders -class ShaderManager -{ -public: - void init(); - void terminate(); - - void createShader(const std::string& name, std::string vertex, std::string fragment, bool colorMatrix = false); - void createOutfitShader(const std::string& name, std::string vertex, std::string fragment) - { - return createShader(name, vertex, fragment, true); - } - void addTexture(const std::string& name, const std::string& file); - PainterShaderProgramPtr getShader(const std::string& name); - -private: - std::unordered_map m_shaders; -}; - - -extern ShaderManager g_shaders; - -#endif - diff --git a/src/client/spritemanager.cpp b/src/client/spritemanager.cpp deleted file mode 100644 index efd4386..0000000 --- a/src/client/spritemanager.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "spritemanager.h" -#include "game.h" -#include -#include -#include -#include -#include - -SpriteManager g_sprites; - -SpriteManager::SpriteManager() -{ - m_spritesCount = 0; - m_signature = 0; -} - -void SpriteManager::terminate() -{ - unload(); -} - -bool SpriteManager::loadSpr(std::string file) -{ - m_spritesCount = 0; - m_signature = 0; - m_spriteSize = 32; - m_loaded = false; - m_sprites.clear(); - - try { - file = g_resources.guessFilePath(file, "spr"); - - m_spritesFile = g_resources.openFile(file); - - m_signature = m_spritesFile->getU32(); - m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16(); - m_spritesOffset = m_spritesFile->tell(); - m_loaded = true; - g_lua.callGlobalField("g_sprites", "onLoadSpr", file); - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Failed to load sprites from '%s': %s", file, e.what())); - return false; - } -} - -void SpriteManager::unload() -{ - m_spritesCount = 0; - m_signature = 0; - m_spritesFile = nullptr; - m_sprites.clear(); -} - -ImagePtr SpriteManager::getSpriteImage(int id) -{ - try { - int spriteDataSize = m_spriteSize * m_spriteSize * 4; - - if (id == 0 || !m_spritesFile) - return nullptr; - - m_spritesFile->seek(((id - 1) * 4) + m_spritesOffset); - - uint32 spriteAddress = m_spritesFile->getU32(); - - // no sprite? return an empty texture - if (spriteAddress == 0) - return nullptr; - - m_spritesFile->seek(spriteAddress); - - // color key - if (m_spriteSize == 32) { - m_spritesFile->getU8(); - m_spritesFile->getU8(); - m_spritesFile->getU8(); - } - - uint16 pixelDataSize = m_spritesFile->getU16(); - - ImagePtr image(new Image(Size(m_spriteSize, m_spriteSize))); - - uint8* pixels = image->getPixelData(); - int writePos = 0; - int read = 0; - bool useAlpha = g_game.getFeature(Otc::GameSpritesAlphaChannel); - - // decompress pixels - while (read < pixelDataSize && writePos < spriteDataSize) { - uint16 transparentPixels = m_spritesFile->getU16(); - uint16 coloredPixels = m_spritesFile->getU16(); - - writePos += transparentPixels * 4; - - if (useAlpha) { - m_spritesFile->read(&pixels[writePos], std::min(coloredPixels * 4, spriteDataSize - writePos)); - writePos += coloredPixels * 4; - read += 4 + (4 * coloredPixels); - } else { - for (int i = 0; i < coloredPixels && writePos < spriteDataSize; i++) { - pixels[writePos + 0] = m_spritesFile->getU8(); - pixels[writePos + 1] = m_spritesFile->getU8(); - pixels[writePos + 2] = m_spritesFile->getU8(); - pixels[writePos + 3] = 0xFF; - writePos += 4; - } - read += 4 + (3 * coloredPixels); - } - } - - return image; - } catch (stdext::exception & e) { - g_logger.error(stdext::format("Failed to get sprite id %d: %s", id, e.what())); - return nullptr; - } -} \ No newline at end of file diff --git a/src/client/spritemanager.h b/src/client/spritemanager.h deleted file mode 100644 index 4a7a828..0000000 --- a/src/client/spritemanager.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SPRITEMANAGER_H -#define SPRITEMANAGER_H - -#include -#include - -//@bindsingleton g_sprites -class SpriteManager -{ - enum { - SPRITE_SIZE = 32, - SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE * 4 - }; - -public: - SpriteManager(); - - void terminate(); - - bool loadSpr(std::string file); - void unload(); - -#ifdef WITH_ENCRYPTION - void saveSpr(std::string fileName); - void encryptSprites(std::string fileName); - void dumpSprites(std::string dir); -#endif - - uint32 getSignature() { return m_signature; } - int getSpritesCount() { return m_spritesCount; } - - ImagePtr getSpriteImage(int id); - bool isLoaded() { return m_loaded; } - - int spriteSize() { return m_spriteSize; } - -private: - stdext::boolean m_loaded; - uint32 m_signature; - int m_spritesCount; - int m_spritesOffset; - int m_spriteSize = 32; - FileStreamPtr m_spritesFile; - std::vector> m_sprites; -}; - -extern SpriteManager g_sprites; - -#endif diff --git a/src/client/statictext.cpp b/src/client/statictext.cpp deleted file mode 100644 index b04a8b6..0000000 --- a/src/client/statictext.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "statictext.h" -#include "map.h" -#include -#include -#include -#include - -StaticText::StaticText() -{ - m_mode = Otc::MessageNone; - m_color = Color::white; - m_cachedText.setFont(g_fonts.getFont("verdana-11px-rounded")); - m_cachedText.setAlign(Fw::AlignCenter); -} - -void StaticText::drawText(const Point& dest, const Rect& parentRect) -{ - Size textSize = m_cachedText.getTextSize(); - Rect rect = Rect(dest - Point(textSize.width() / 2, textSize.height()) + Point(20, 5), textSize); - Rect boundRect = rect; - boundRect.bind(parentRect); - - // draw only if the real center is not too far from the parent center, or its a yell - //if(g_map.isAwareOfPosition(m_position) || isYell()) { - m_cachedText.draw(boundRect, m_color); - //} -} - -void StaticText::setFont(const std::string& fontName) -{ - m_cachedText.setFont(g_fonts.getFont(fontName)); -} - -void StaticText::setText(const std::string& text) -{ - m_cachedText.setText(text); -} - -bool StaticText::addMessage(const std::string& name, Otc::MessageMode mode, const std::string& text) -{ - return addColoredMessage(name, mode, { text, "" }); -} - -bool StaticText::addColoredMessage(const std::string& name, Otc::MessageMode mode, const std::vector& texts) -{ - if (texts.empty() || texts.size() % 2 != 0) - return false; - //TODO: this could be moved to lua - // first message - if (m_messages.size() == 0) { - m_name = name; - m_mode = mode; - } - // check if we can really own the message - else if (m_name != name || m_mode != mode) { - return false; - } - // too many messages - else if (m_messages.size() > 10) { - m_messages.pop_front(); - m_updateEvent->cancel(); - m_updateEvent = nullptr; - } - - size_t len = 0; - for (size_t i = 0; i < texts.size(); i += 2) { - len += texts[i].length(); - } - - int delay = std::max(Otc::STATIC_DURATION_PER_CHARACTER * len, Otc::MIN_STATIC_TEXT_DURATION); - if (isYell()) - delay *= 2; - - m_messages.push_back(StaticTextMessage{ texts, g_clock.millis() + delay }); - compose(); - - if (!m_updateEvent) - scheduleUpdate(); - return true; -} - -void StaticText::update() -{ - m_messages.pop_front(); - if(m_messages.empty()) { - // schedule removal - auto self = asStaticText(); - g_dispatcher.addEvent([self]() { g_map.removeThing(self); }); - } else { - compose(); - scheduleUpdate(); - } -} - -void StaticText::scheduleUpdate() -{ - int delay = std::max(m_messages.front().time - g_clock.millis(), 0); - - auto self = asStaticText(); - m_updateEvent = g_dispatcher.scheduleEvent([self]() { - self->m_updateEvent = nullptr; - self->update(); - }, delay); -} - -void StaticText::compose() -{ - //TODO: this could be moved to lua - std::vector texts; - - if(m_mode == Otc::MessageSay) { - texts.push_back(m_name + " says:\n"); - texts.push_back("#EFEF00"); - m_color = Color(239, 239, 0); - } else if(m_mode == Otc::MessageWhisper) { - texts.push_back(m_name + " whispers:\n"); - texts.push_back("#EFEF00"); - m_color = Color(239, 239, 0); - } else if(m_mode == Otc::MessageYell) { - texts.push_back(m_name + " yells:\n"); - texts.push_back("#EFEF00"); - m_color = Color(239, 239, 0); - } else if(m_mode == Otc::MessageMonsterSay || m_mode == Otc::MessageMonsterYell || m_mode == Otc::MessageSpell - || m_mode == Otc::MessageBarkLow || m_mode == Otc::MessageBarkLoud) { - m_color = Color(254, 101, 0); - } else if(m_mode == Otc::MessageNpcFrom || m_mode == Otc::MessageNpcFromStartBlock) { - texts.push_back(m_name + " says:\n"); - texts.push_back("#5FF7F7"); - m_color = Color(95, 247, 247); - } else { - g_logger.warning(stdext::format("Unknown speak type: %d", m_mode)); - } - - for(uint i = 0; i < m_messages.size(); ++i) { - for (size_t j = 0; j < m_messages[i].texts.size() - 1; j += 2) { - texts.push_back(m_messages[i].texts[j]); - texts.push_back(m_messages[i].texts[j + 1].empty() ? m_color.toHex() : m_messages[i].texts[j + 1]); - } - if (texts.size() >= 2 && i < m_messages.size() - 1) { - texts[texts.size() - 2] += "\n"; - } - } - - m_cachedText.setColoredText(texts); - m_cachedText.wrapText(275); -} diff --git a/src/client/statictext.h b/src/client/statictext.h deleted file mode 100644 index fa1320c..0000000 --- a/src/client/statictext.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STATICTEXT_H -#define STATICTEXT_H - -#include "thing.h" -#include -#include - -struct StaticTextMessage { - std::vector texts; - ticks_t time; -}; - -// @bindclass -class StaticText : public Thing -{ -public: - StaticText(); - - void drawText(const Point& dest, const Rect& parentRect); - - std::string getName() { return m_name; } - std::string getText() { return m_cachedText.getText(); } - Otc::MessageMode getMessageMode() { return m_mode; } - std::vector getFirstMessage() { return m_messages[0].texts; } - - bool isYell() { return m_mode == Otc::MessageYell || m_mode == Otc::MessageMonsterYell || m_mode == Otc::MessageBarkLoud; } - - void setText(const std::string& text); - void setFont(const std::string& fontName); - bool addMessage(const std::string& name, Otc::MessageMode mode, const std::string& text); - bool addColoredMessage(const std::string& name, Otc::MessageMode mode, const std::vector& texts); - StaticTextPtr asStaticText() { return static_self_cast(); } - bool isStaticText() { return true; } - - void setColor(const Color& color) { m_color = color; } - Color getColor() { return m_color; } - - CachedText& getCachedText() { return m_cachedText; } - bool hasText() { return m_cachedText.hasText(); } - -private: - void update(); - void scheduleUpdate(); - void compose(); - - stdext::boolean m_yell; - std::deque m_messages; - std::string m_name; - Otc::MessageMode m_mode; - Color m_color; - CachedText m_cachedText; - ScheduledEventPtr m_updateEvent; -}; - -#endif diff --git a/src/client/thing.cpp b/src/client/thing.cpp deleted file mode 100644 index 3cf052b..0000000 --- a/src/client/thing.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "thing.h" -#include "spritemanager.h" -#include "thingtypemanager.h" -#include -#include "map.h" -#include "tile.h" -#include "game.h" -#include - -Thing::Thing() : - m_datId(0) -{ - g_stats.addThing(); -} - -Thing::~Thing() -{ - g_stats.removeThing(); -} - -void Thing::setPosition(const Position& position) -{ - if(m_position == position) - return; - - Position oldPos = m_position; - m_position = position; - onPositionChange(position, oldPos); -} - -int Thing::getStackPriority() -{ - // bug fix for old versions - if (g_game.getClientVersion() <= 800 && isSplash()) { - return 1; - } - if(isGround()) - return 0; - else if(isGroundBorder()) - return 1; - else if(isOnBottom()) - return 2; - else if(isOnTop()) - return 3; - else if(isCreature()) - return 4; - else // common items - return 5; -} - -const TilePtr& Thing::getTile() -{ - return g_map.getTile(m_position); -} - -ContainerPtr Thing::getParentContainer() -{ - if(m_position.x == 0xffff && m_position.y & 0x40) { - int containerId = m_position.y ^ 0x40; - return g_game.getContainer(containerId); - } - return nullptr; -} - -int Thing::getStackPos() -{ - if(m_position.x == 65535 && isItem()) // is inside a container - return m_position.z; - else if(const TilePtr& tile = getTile()) - return tile->getThingStackPos(static_self_cast()); - else { - g_logger.traceError("got a thing with invalid stackpos"); - return -1; - } -} - -const ThingTypePtr& Thing::getThingType() -{ - return g_things.getNullThingType(); -} - -ThingType* Thing::rawGetThingType() -{ - return g_things.getNullThingType().get(); -} - -Color Thing::updatedMarkedColor() { - if (!m_marked) - return Color::white; - m_markedColor.setAlpha(0.1f + std::abs(500 - g_clock.millis() % 1000) / 1000.0f); // 0.1-0.6 - return m_markedColor; -} diff --git a/src/client/thing.h b/src/client/thing.h deleted file mode 100644 index 2c95eee..0000000 --- a/src/client/thing.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef THING_H -#define THING_H - -#include "declarations.h" -#include "thingtype.h" -#include "thingtypemanager.h" -#include -#include - -// @bindclass -#pragma pack(push,1) // disable memory alignment -class Thing : public LuaObject -{ -public: - Thing(); - virtual ~Thing(); - - virtual void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr) { } - - virtual void setId(uint32 id) { } - void setPosition(const Position& position); - - virtual uint32 getId() { return 0; } - Position getPosition() { return m_position; } - int getStackPriority(); - virtual const TilePtr& getTile(); - ContainerPtr getParentContainer(); - int getStackPos(); - - void setMarked(const std::string& color) { - if (color.empty()) { - m_marked = false; - return; - } - m_marked = true; - m_markedColor = Color(color); - } - Color updatedMarkedColor(); - - virtual bool isItem() { return false; } - virtual bool isEffect() { return false; } - virtual bool isMissile() { return false; } - virtual bool isCreature() { return false; } - virtual bool isNpc() { return false; } - virtual bool isMonster() { return false; } - virtual bool isPlayer() { return false; } - virtual bool isLocalPlayer() { return false; } - virtual bool isAnimatedText() { return false; } - virtual bool isStaticText() { return false; } - - // type shortcuts - virtual const ThingTypePtr& getThingType(); - virtual ThingType *rawGetThingType(); - Size getSize() { return rawGetThingType()->getSize(); } - int getWidth() { return rawGetThingType()->getWidth(); } - int getHeight() { return rawGetThingType()->getHeight(); } - virtual Point getDisplacement() { return rawGetThingType()->getDisplacement(); } - virtual int getDisplacementX() { return rawGetThingType()->getDisplacementX(); } - virtual int getDisplacementY() { return rawGetThingType()->getDisplacementY(); } - virtual int getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase) { return rawGetThingType()->getExactSize(layer, xPattern, yPattern, zPattern, animationPhase); } - int getLayers() { return rawGetThingType()->getLayers(); } - int getNumPatternX() { return rawGetThingType()->getNumPatternX(); } - int getNumPatternY() { return rawGetThingType()->getNumPatternY(); } - int getNumPatternZ() { return rawGetThingType()->getNumPatternZ(); } - int getAnimationPhases() { return rawGetThingType()->getAnimationPhases(); } - AnimatorPtr getAnimator() { return rawGetThingType()->getAnimator(); } - AnimatorPtr getIdleAnimator() { return rawGetThingType()->getIdleAnimator(); } - int getGroundSpeed() { return rawGetThingType()->getGroundSpeed(); } - int getMaxTextLength() { return rawGetThingType()->getMaxTextLength(); } - Light getLight() { return rawGetThingType()->getLight(); } - int getMinimapColor() { return rawGetThingType()->getMinimapColor(); } - int getLensHelp() { return rawGetThingType()->getLensHelp(); } - int getClothSlot() { return rawGetThingType()->getClothSlot(); } - int getElevation() { return rawGetThingType()->getElevation(); } - bool isGround() { return rawGetThingType()->isGround(); } - bool isGroundBorder() { return rawGetThingType()->isGroundBorder(); } - bool isOnBottom() { return rawGetThingType()->isOnBottom(); } - bool isOnTop() { return rawGetThingType()->isOnTop(); } - bool isContainer() { return rawGetThingType()->isContainer(); } - bool isStackable() { return rawGetThingType()->isStackable(); } - bool isForceUse() { return rawGetThingType()->isForceUse(); } - bool isMultiUse() { return rawGetThingType()->isMultiUse(); } - bool isWritable() { return rawGetThingType()->isWritable(); } - bool isChargeable() { return rawGetThingType()->isChargeable(); } - bool isWritableOnce() { return rawGetThingType()->isWritableOnce(); } - bool isFluidContainer() { return rawGetThingType()->isFluidContainer(); } - bool isSplash() { return rawGetThingType()->isSplash(); } - bool isNotWalkable() { return rawGetThingType()->isNotWalkable(); } - bool isNotMoveable() { return rawGetThingType()->isNotMoveable(); } - bool blockProjectile() { return rawGetThingType()->blockProjectile(); } - bool isNotPathable() { return rawGetThingType()->isNotPathable(); } - bool isPickupable() { return rawGetThingType()->isPickupable(); } - bool isHangable() { return rawGetThingType()->isHangable(); } - bool isHookSouth() { return rawGetThingType()->isHookSouth(); } - bool isHookEast() { return rawGetThingType()->isHookEast(); } - bool isRotateable() { return rawGetThingType()->isRotateable(); } - bool hasLight() { return rawGetThingType()->hasLight(); } - bool isDontHide() { return rawGetThingType()->isDontHide(); } - bool isTranslucent() { return rawGetThingType()->isTranslucent(); } - bool hasDisplacement() { return rawGetThingType()->hasDisplacement(); } - bool hasElevation() { return rawGetThingType()->hasElevation(); } - bool isLyingCorpse() { return rawGetThingType()->isLyingCorpse(); } - bool isAnimateAlways() { return rawGetThingType()->isAnimateAlways(); } - bool hasMiniMapColor() { return rawGetThingType()->hasMiniMapColor(); } - bool hasLensHelp() { return rawGetThingType()->hasLensHelp(); } - bool isFullGround() { return rawGetThingType()->isFullGround(); } - bool isIgnoreLook() { return rawGetThingType()->isIgnoreLook(); } - bool isCloth() { return rawGetThingType()->isCloth(); } - bool isMarketable() { return rawGetThingType()->isMarketable(); } - bool isUsable() { return rawGetThingType()->isUsable(); } - bool isWrapable() { return rawGetThingType()->isWrapable(); } - bool isUnwrapable() { return rawGetThingType()->isUnwrapable(); } - bool isTopEffect() { return rawGetThingType()->isTopEffect(); } - MarketData getMarketData() { return rawGetThingType()->getMarketData(); } - - void hide() { m_hidden = true; } - void show() { m_hidden = false; } - void setHidden(bool value) { m_hidden = value; } - bool isHidden() { return m_hidden; } - - virtual void onPositionChange(const Position& newPos, const Position& oldPos) { } - virtual void onAppear() { } - virtual void onDisappear() { } - -protected: - Position m_position; - uint16 m_datId; - bool m_marked = false; - bool m_hidden = false; - Color m_markedColor; -}; -#pragma pack(pop) - -#endif - diff --git a/src/client/thingstype.h b/src/client/thingstype.h deleted file mode 100644 index 4aa9dc1..0000000 --- a/src/client/thingstype.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef DATMANAGER_H -#define DATMANAGER_H - -#include -#include -#include "thingtype.h" - -//@bindsingleton g_thingsType -class ThingsType -{ -public: - - enum Categories { - Item = 0, - Creature, - Effect, - Missile, - LastCategory - }; - - bool load(const std::string& file); - void unload(); - - bool parseThingType(const FileStreamPtr& fin, ThingType& thingType); - - ThingType *getEmptyThingType() { return &m_emptyThingType; } - ThingType *getThingType(uint16 id, Categories category); - - uint32 getSignature() { return m_signature; } - bool isLoaded() { return m_loaded; } - - uint16 getFirstItemId() { return 100; } - uint16 getMaxItemid() { return m_things[Item].size() + 99; } - bool isValidItemId(int id) { return id >= getFirstItemId() && id <= getMaxItemid(); } - -private: - uint32 m_signature; - stdext::boolean m_loaded; - ThingTypeList m_things[LastCategory]; - static ThingType m_emptyThingType; -}; - -extern ThingsType g_thingsType; - -#endif diff --git a/src/client/thingtype.cpp b/src/client/thingtype.cpp deleted file mode 100644 index 42039cd..0000000 --- a/src/client/thingtype.cpp +++ /dev/null @@ -1,777 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "thingtype.h" -#include "spritemanager.h" -#include "game.h" -#include "lightview.h" - -#include -#include -#include -#include -#include -#include - -ThingType::ThingType() -{ - m_category = ThingInvalidCategory; - m_id = 0; - m_null = true; - m_exactSize = 0; - m_realSize = 0; - m_animator = nullptr; - m_numPatternX = m_numPatternY = m_numPatternZ = 0; - m_animationPhases = 0; - m_layers = 0; - m_elevation = 0; - m_opacity = 1.0f; -} - -void ThingType::serialize(const FileStreamPtr& fin) -{ - for(int i = 0; i < ThingLastAttr; ++i) { - if(!hasAttr((ThingAttr)i)) - continue; - - int attr = i; - if(g_game.getClientVersion() >= 780) { - if(attr == ThingAttrChargeable) - attr = ThingAttrWritable; - else if(attr >= ThingAttrWritable) - attr += 1; - } else if(g_game.getClientVersion() >= 1000) { - if(attr == ThingAttrNoMoveAnimation) - attr = 16; - else if(attr >= ThingAttrPickupable) - attr += 1; - } - - fin->addU8(attr); - switch(attr) { - case ThingAttrDisplacement: { - fin->addU16(m_displacement.x); - fin->addU16(m_displacement.y); - break; - } - case ThingAttrLight: { - Light light = m_attribs.get(attr); - fin->addU16(light.intensity); - fin->addU16(light.color); - break; - } - case ThingAttrMarket: { - MarketData market = m_attribs.get(attr); - fin->addU16(market.category); - fin->addU16(market.tradeAs); - fin->addU16(market.showAs); - fin->addString(market.name); - fin->addU16(market.restrictVocation); - fin->addU16(market.requiredLevel); - break; - } - case ThingAttrUsable: - case ThingAttrElevation: - case ThingAttrGround: - case ThingAttrWritable: - case ThingAttrWritableOnce: - case ThingAttrMinimapColor: - case ThingAttrCloth: - case ThingAttrLensHelp: - fin->addU16(m_attribs.get(attr)); - break; - default: - break; - }; - } - fin->addU8(ThingLastAttr); - - fin->addU8(m_size.width()); - fin->addU8(m_size.height()); - - if(m_size.width() > 1 || m_size.height() > 1) - fin->addU8(m_realSize); - - fin->addU8(m_layers); - fin->addU8(m_numPatternX); - fin->addU8(m_numPatternY); - fin->addU8(m_numPatternZ); - fin->addU8(m_animationPhases); - - if(g_game.getFeature(Otc::GameEnhancedAnimations)) { - if(m_animationPhases > 1 && m_animator != nullptr) { - m_animator->serialize(fin); - } - } - - for(uint i = 0; i < m_spritesIndex.size(); i++) { - if(g_game.getFeature(Otc::GameSpritesU32)) - fin->addU32(m_spritesIndex[i]); - else - fin->addU16(m_spritesIndex[i]); - } -} - -void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin) -{ - m_null = false; - m_id = clientId; - m_category = category; - - int count = 0, attr = -1; - bool done = false; - for(int i = 0 ; i < ThingLastAttr;++i) { - count++; - attr = fin->getU8(); - if(attr == ThingLastAttr) { - done = true; - break; - } - - if(g_game.getClientVersion() >= 1000) { - /* In 10.10+ all attributes from 16 and up were - * incremented by 1 to make space for 16 as - * "No Movement Animation" flag. - */ - if(attr == 16) - attr = ThingAttrNoMoveAnimation; - else if(attr > 16) - attr -= 1; - } else if(g_game.getClientVersion() >= 860) { - /* Default attribute values follow - * the format of 8.6-9.86. - * Therefore no changes here. - */ - } else if(g_game.getClientVersion() >= 780) { - /* In 7.80-8.54 all attributes from 8 and higher were - * incremented by 1 to make space for 8 as - * "Item Charges" flag. - */ - if(attr == 8) { - m_attribs.set(ThingAttrChargeable, true); - continue; - } else if(attr > 8) - attr -= 1; - } else if(g_game.getClientVersion() >= 755) { - /* In 7.55-7.72 attributes 23 is "Floor Change". */ - if(attr == 23) - attr = ThingAttrFloorChange; - } else if(g_game.getClientVersion() >= 740) { - /* In 7.4-7.5 attribute "Ground Border" did not exist - * attributes 1-15 have to be adjusted. - * Several other changes in the format. - */ - if(attr > 0 && attr <= 15) - attr += 1; - else if(attr == 16) - attr = ThingAttrLight; - else if(attr == 17) - attr = ThingAttrFloorChange; - else if(attr == 18) - attr = ThingAttrFullGround; - else if(attr == 19) - attr = ThingAttrElevation; - else if(attr == 20) - attr = ThingAttrDisplacement; - else if(attr == 22) - attr = ThingAttrMinimapColor; - else if(attr == 23) - attr = ThingAttrRotateable; - else if(attr == 24) - attr = ThingAttrLyingCorpse; - else if(attr == 25) - attr = ThingAttrHangable; - else if(attr == 26) - attr = ThingAttrHookSouth; - else if(attr == 27) - attr = ThingAttrHookEast; - else if(attr == 28) - attr = ThingAttrAnimateAlways; - - /* "Multi Use" and "Force Use" are swapped */ - if(attr == ThingAttrMultiUse) - attr = ThingAttrForceUse; - else if(attr == ThingAttrForceUse) - attr = ThingAttrMultiUse; - } - - switch(attr) { - case ThingAttrDisplacement: { - if(g_game.getClientVersion() >= 755) { - m_displacement.x = fin->getU16(); - m_displacement.y = fin->getU16(); - } else { - m_displacement.x = 8; - m_displacement.y = 8; - } - m_attribs.set(attr, true); - break; - } - case ThingAttrLight: { - Light light; - light.intensity = fin->getU16(); - light.color = fin->getU16(); - m_attribs.set(attr, light); - break; - } - case ThingAttrMarket: { - MarketData market; - market.category = fin->getU16(); - market.tradeAs = fin->getU16(); - market.showAs = fin->getU16(); - market.name = fin->getString(); - market.restrictVocation = fin->getU16(); - market.requiredLevel = fin->getU16(); - m_attribs.set(attr, market); - break; - } - case ThingAttrElevation: { - m_elevation = fin->getU16(); - m_attribs.set(attr, m_elevation); - break; - } - case ThingAttrUsable: - case ThingAttrGround: - case ThingAttrWritable: - case ThingAttrWritableOnce: - case ThingAttrMinimapColor: - case ThingAttrCloth: - case ThingAttrLensHelp: - m_attribs.set(attr, fin->getU16()); - break; - default: - m_attribs.set(attr, true); - break; - }; - } - - if(!done) - stdext::throw_exception(stdext::format("corrupt data (id: %d, category: %d, count: %d, lastAttr: %d)", - m_id, m_category, count, attr)); - - bool hasFrameGroups = (category == ThingCategoryCreature && g_game.getFeature(Otc::GameIdleAnimations)); - uint8 groupCount = hasFrameGroups ? fin->getU8() : 1; - - m_animationPhases = 0; - int totalSpritesCount = 0; - - std::vector sizes; - std::vector total_sprites; - - for(int i = 0; i < groupCount; ++i) { - uint8 frameGroupType = FrameGroupDefault; - if(hasFrameGroups) - frameGroupType = fin->getU8(); - - uint8 width = fin->getU8(); - uint8 height = fin->getU8(); - m_size = Size(width, height); - sizes.push_back(m_size); - if(width > 1 || height > 1) { - m_realSize = fin->getU8(); - m_exactSize = std::min(m_realSize, std::max(width * 32, height * 32)); - } - else - m_exactSize = 32; - - m_layers = fin->getU8(); - m_numPatternX = fin->getU8(); - m_numPatternY = fin->getU8(); - if(g_game.getClientVersion() >= 755) - m_numPatternZ = fin->getU8(); - else - m_numPatternZ = 1; - - int groupAnimationsPhases = fin->getU8(); - m_animationPhases += groupAnimationsPhases; - - if(groupAnimationsPhases > 1 && g_game.getFeature(Otc::GameEnhancedAnimations)) { - AnimatorPtr animator = AnimatorPtr(new Animator); - animator->unserialize(groupAnimationsPhases, fin); - - switch (frameGroupType) { - case FrameGroupIdle: - m_idleAnimator = animator; - break; - case FrameGroupMoving: - m_animator = animator; - break; - } - } - - int totalSprites = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * groupAnimationsPhases; - total_sprites.push_back(totalSprites); - - if((totalSpritesCount+totalSprites) > 4096) - stdext::throw_exception("a thing type has more than 4096 sprites"); - - m_spritesIndex.resize((totalSpritesCount+totalSprites)); - for(int i = totalSpritesCount; i < (totalSpritesCount+totalSprites); i++) - m_spritesIndex[i] = g_game.getFeature(Otc::GameSpritesU32) ? fin->getU32() : fin->getU16(); - - totalSpritesCount += totalSprites; - } - - if(sizes.size() > 1) { - // correction for some sprites - for (auto& s : sizes) { - m_size.setWidth(std::max(m_size.width(), s.width())); - m_size.setHeight(std::max(m_size.height(), s.height())); - } - size_t expectedSize = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases; - if (expectedSize != m_spritesIndex.size()) { - std::vector sprites(std::move(m_spritesIndex)); - m_spritesIndex.clear(); - m_spritesIndex.reserve(expectedSize); - for (size_t i = 0, idx = 0; i < sizes.size(); ++i) { - int totalSprites = total_sprites[i]; - if (m_size == sizes[i]) { - for (int j = 0; j < totalSprites; ++j) { - m_spritesIndex.push_back(sprites[idx++]); - } - continue; - } - size_t patterns = (totalSprites / sizes[i].area()); - for (size_t p = 0; p < patterns; ++p) { - for (int x = 0; x < m_size.width(); ++x) { - for (int y = 0; y < m_size.height(); ++y) { - if (x < sizes[i].width() && y < sizes[i].height()) { - m_spritesIndex.push_back(sprites[idx++]); - continue; - } - m_spritesIndex.push_back(0); - } - } - } - } - //if (m_spritesIndex.size() != expectedSize) { - // g_logger.warning(stdext::format("Wrong thingtype: %i - %i - %i", clientId, m_spritesIndex.size(), expectedSize)); - //} - } - } - - if (m_idleAnimator && !m_animator) { - m_animator = m_idleAnimator; - m_idleAnimator = nullptr; - } - - m_textures.resize(m_animationPhases); - m_texturesFramesRects.resize(m_animationPhases); - m_texturesFramesOriginRects.resize(m_animationPhases); - m_texturesFramesOffsets.resize(m_animationPhases); - - m_lastUsage = g_clock.seconds(); -} - -void ThingType::exportImage(std::string fileName) -{ - if (m_null) - stdext::throw_exception("cannot export null thingtype"); - - if (m_spritesIndex.size() == 0) - stdext::throw_exception("cannot export thingtype without sprites"); - - size_t spriteSize = g_sprites.spriteSize(); - - ImagePtr image(new Image(Size(spriteSize * m_size.width() * m_layers * m_numPatternX, spriteSize * m_size.height() * m_animationPhases * m_numPatternY * m_numPatternZ))); - for (int z = 0; z < m_numPatternZ; ++z) { - for (int y = 0; y < m_numPatternY; ++y) { - for (int x = 0; x < m_numPatternX; ++x) { - for (int l = 0; l < m_layers; ++l) { - for (int a = 0; a < m_animationPhases; ++a) { - for (int w = 0; w < m_size.width(); ++w) { - for (int h = 0; h < m_size.height(); ++h) { - image->blit(Point(spriteSize * (m_size.width() - w - 1 + m_size.width() * x + m_size.width() * m_numPatternX * l), - spriteSize * (m_size.height() - h - 1 + m_size.height() * y + m_size.height() * m_numPatternY * a + m_size.height() * m_numPatternY * m_animationPhases * z)), - g_sprites.getSpriteImage(m_spritesIndex[getSpriteIndex(w, h, l, x, y, z, a)])); - } - } - } - } - } - } - } - - image->savePNG(fileName); -} - -void ThingType::replaceSprites(std::map& replacements, std::string fileName) -{ - if (m_null) - stdext::throw_exception("cannot export null thingtype"); - - if (m_spritesIndex.size() == 0) - stdext::throw_exception("cannot export thingtype without sprites"); - - size_t spriteSize = g_sprites.spriteSize(); - - ImagePtr image = Image::loadPNG(fileName); - if (!image) - stdext::throw_exception(stdext::format("can't load image from %s", fileName)); - - for (int z = 0; z < m_numPatternZ; ++z) { - for (int y = 0; y < m_numPatternY; ++y) { - for (int x = 0; x < m_numPatternX; ++x) { - for (int l = 0; l < m_layers; ++l) { - for (int a = 0; a < m_animationPhases; ++a) { - for (int w = 0; w < m_size.width(); ++w) { - for (int h = 0; h < m_size.height(); ++h) { - uint32_t sprite = m_spritesIndex[getSpriteIndex(w, h, l, x, y, z, a)]; - ImagePtr orgSprite = g_sprites.getSpriteImage(m_spritesIndex[getSpriteIndex(w, h, l, x, y, z, a)]); - if (!orgSprite) continue; - Point src(spriteSize * (m_size.width() - w - 1 + m_size.width() * x + m_size.width() * m_numPatternX * l), - spriteSize * (m_size.height() - h - 1 + m_size.height() * y + m_size.height() * m_numPatternY * a + m_size.height() * m_numPatternY * m_animationPhases * z)); - src = src * 2; - ImagePtr newSprite(new Image(Size(orgSprite->getSize() * 2))); - for (int x = 0; x < newSprite->getSize().width(); ++x) { - for (int y = 0; y < newSprite->getSize().height(); ++y) { - newSprite->setPixel(x, y, image->getPixel(src.x + x, src.y + y)); - } - } - replacements[sprite] = newSprite; - } - } - } - } - } - } - } -} - -void ThingType::unserializeOtml(const OTMLNodePtr& node) -{ - for(const OTMLNodePtr& node2 : node->children()) { - if(node2->tag() == "opacity") - m_opacity = node2->value(); - else if(node2->tag() == "notprewalkable") - m_attribs.set(ThingAttrNotPreWalkable, node2->value()); - else if(node2->tag() == "image") - m_customImage = node2->value(); - else if(node2->tag() == "full-ground") { - if(node2->value()) - m_attribs.set(ThingAttrFullGround, true); - else - m_attribs.remove(ThingAttrFullGround); - } - } -} - -void ThingType::unload() -{ - m_textures.clear(); - m_texturesFramesRects.clear(); - m_texturesFramesOriginRects.clear(); - m_texturesFramesOffsets.clear(); - - m_textures.resize(m_animationPhases); - m_texturesFramesRects.resize(m_animationPhases); - m_texturesFramesOriginRects.resize(m_animationPhases); - m_texturesFramesOffsets.resize(m_animationPhases); - - m_loaded = false; -} - - -DrawQueueItem* ThingType::draw(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, Color color, LightView* lightView) -{ - if (m_null) - return nullptr; - - if (animationPhase < 0 || animationPhase >= m_animationPhases) - return nullptr; - - const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects. - if (!texture) - return nullptr; - - uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern); - if (frameIndex >= m_texturesFramesRects[animationPhase].size()) - return nullptr; - - Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex]; - Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex]; - - Rect screenRect(dest + (textureOffset - m_displacement - (m_size.toPoint() - Point(1, 1)) * Otc::TILE_PIXELS), textureRect.size()); - - bool useOpacity = m_opacity < 1.0f; - if (useOpacity) - color.setAlpha(m_opacity); - - if (lightView && hasLight()) - lightView->addLight(screenRect.center(), getLight()); - - return g_drawQueue->addTexturedRect(screenRect, texture, textureRect, color); -} - -DrawQueueItem* ThingType::draw(const Rect& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, Color color) -{ - if (m_null) - return nullptr; - - if (animationPhase < 0 || animationPhase >= m_animationPhases) - return nullptr; - - const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects. - if (!texture) - return nullptr; - - uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern); - if (frameIndex >= m_texturesFramesRects[animationPhase].size()) - return nullptr; - - Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex]; - Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex]; - - bool useOpacity = m_opacity < 1.0f; - if (useOpacity) - color.setAlpha(m_opacity); - - Size size = m_size * Otc::TILE_PIXELS; - if (!size.isValid()) - return nullptr; - - // size correction for some too big items - if ((size.width() > 1 || size.height() > 1) && - textureRect.width() <= Otc::TILE_PIXELS && textureRect.height() <= Otc::TILE_PIXELS) { - size = Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS); - textureOffset = Point((Otc::TILE_PIXELS - textureRect.width()) / 2, - (Otc::TILE_PIXELS - textureRect.height()) / 2); - } - - float scale = std::min((float)dest.width() / size.width(), (float)dest.height() / size.height()); - return g_drawQueue->addTexturedRect(Rect(dest.topLeft() + (textureOffset * scale), textureRect.size() * scale), texture, textureRect, color); -} - -void ThingType::drawOutfit(const Point& dest, int xPattern, int yPattern, int zPattern, int animationPhase, int colors, Color color, LightView* lightView) -{ - if (m_null) - return; - - if (animationPhase < 0 || animationPhase >= m_animationPhases) - return; - - const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects. - if (!texture) - return; - - uint frameIndex = getTextureIndex(0, xPattern, yPattern, zPattern); - uint frameIndex2 = getTextureIndex(1, xPattern, yPattern, zPattern); - if (frameIndex >= m_texturesFramesRects[animationPhase].size() || frameIndex2 >= m_texturesFramesRects[animationPhase].size()) - return; - - Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex]; - Point textureOffset2 = m_texturesFramesOffsets[animationPhase][frameIndex2]; - Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex]; - Rect textureRect2 = m_texturesFramesRects[animationPhase][frameIndex2]; - Size size = textureRect.size(); - if (!size.isValid()) - return; - Rect screenRect(dest + (textureOffset - m_displacement - (m_size.toPoint() - Point(1, 1)) * Otc::TILE_PIXELS), textureRect.size()); - - bool useOpacity = m_opacity < 1.0f; - if (useOpacity) - color.setAlpha(m_opacity); - - if (lightView && hasLight()) - lightView->addLight(screenRect.center(), getLight()); - - Point offset = textureOffset - textureOffset2; - offset += textureRect2.topLeft() - textureRect.topLeft(); - g_drawQueue->addOutfit(screenRect, texture, textureRect, offset, colors, color); -} - -Rect ThingType::getDrawSize(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase) -{ - if (m_null) - return Rect(0, 0, 1, 1); - - if (animationPhase < 0 || animationPhase >= m_animationPhases) - return Rect(0, 0, 1, 1); - - const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects. - if (!texture) - return Rect(0, 0, 1, 1); - - uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern); - if (frameIndex >= m_texturesFramesRects[animationPhase].size()) - return Rect(0, 0, 1, 1); - - Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex]; - Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex]; - return Rect(dest + textureOffset - m_displacement - (m_size.toPoint() - Point(1, 1)) * Otc::TILE_PIXELS, textureRect.size()); -} - - -const TexturePtr& ThingType::getTexture(int animationPhase) -{ - m_lastUsage = g_clock.seconds(); - - int spriteSize = g_sprites.spriteSize(); - TexturePtr& animationPhaseTexture = m_textures[animationPhase]; - if(!animationPhaseTexture) { - bool useCustomImage = false; - if(animationPhase == 0 && !m_customImage.empty()) - useCustomImage = true; - - // we don't need layers in common items, they will be pre-drawn - int textureLayers = 1; - int numLayers = m_layers; - if(m_category == ThingCategoryCreature && numLayers >= 2) { - // otcv8 optimization from 5 to 2 layers - textureLayers = 2; - numLayers = 2; - } - - int indexSize = textureLayers * m_numPatternX * m_numPatternY * m_numPatternZ; - Size textureSize = getBestTextureDimension(m_size.width(), m_size.height(), indexSize); - ImagePtr fullImage; - - if(useCustomImage) - fullImage = Image::load(m_customImage); - else - fullImage = ImagePtr(new Image(textureSize * spriteSize)); - - m_texturesFramesRects[animationPhase].resize(indexSize); - m_texturesFramesOriginRects[animationPhase].resize(indexSize); - m_texturesFramesOffsets[animationPhase].resize(indexSize); - - for(int z = 0; z < m_numPatternZ; ++z) { - for(int y = 0; y < m_numPatternY; ++y) { - for(int x = 0; x < m_numPatternX; ++x) { - for(int l = 0; l < numLayers; ++l) { - bool spriteMask = (m_category == ThingCategoryCreature && l > 0); - int frameIndex = getTextureIndex(l % textureLayers, x, y, z); - Point framePos = Point(frameIndex % (textureSize.width() / m_size.width()) * m_size.width(), - frameIndex / (textureSize.width() / m_size.width()) * m_size.height()) * spriteSize; - - if (!useCustomImage) { - for (int h = 0; h < m_size.height(); ++h) { - for (int w = 0; w < m_size.width(); ++w) { - uint spriteIndex = getSpriteIndex(w, h, spriteMask ? 1 : l, x, y, z, animationPhase); - ImagePtr spriteImage = g_sprites.getSpriteImage(m_spritesIndex[spriteIndex]); - if (!spriteImage) { - continue; - } - Point spritePos = Point(m_size.width() - w - 1, - m_size.height() - h - 1) * spriteSize; - fullImage->blit(framePos + spritePos, spriteImage); - } - } - } - - Rect drawRect(framePos + Point(m_size.width(), m_size.height()) * spriteSize - Point(1,1), framePos); - for(int x = framePos.x; x < framePos.x + m_size.width() * spriteSize; ++x) { - for(int y = framePos.y; y < framePos.y + m_size.height() * spriteSize; ++y) { - uint8 *p = fullImage->getPixel(x,y); - if(p[3] != 0x00) { - drawRect.setTop (std::min(y, (int)drawRect.top())); - drawRect.setLeft (std::min(x, (int)drawRect.left())); - drawRect.setBottom(std::max(y, (int)drawRect.bottom())); - drawRect.setRight (std::max(x, (int)drawRect.right())); - } - } - } - - m_texturesFramesRects[animationPhase][frameIndex] = drawRect; - m_texturesFramesOriginRects[animationPhase][frameIndex] = Rect(framePos, Size(m_size.width(), m_size.height()) * spriteSize);// *0.5; - m_texturesFramesOffsets[animationPhase][frameIndex] = (drawRect.topLeft() - framePos); - } - } - } - } - animationPhaseTexture = TexturePtr(new Texture(fullImage, true, false, true)); - m_loaded = true; - } - return animationPhaseTexture; -} - -Size ThingType::getBestTextureDimension(int w, int h, int count) -{ - const int MAX = 32; - - int k = 1; - while(k < w) - k<<=1; - w = k; - - k = 1; - while(k < h) - k<<=1; - h = k; - - int numSprites = w*h*count; - VALIDATE(numSprites <= MAX*MAX); - VALIDATE(w <= MAX); - VALIDATE(h <= MAX); - - Size bestDimension = Size(MAX, MAX); - for(int i=w;i<=MAX;i<<=1) { - for(int j=h;j<=MAX;j<<=1) { - Size candidateDimension = Size(i, j); - if(candidateDimension.area() < numSprites) - continue; - if((candidateDimension.area() < bestDimension.area()) || - (candidateDimension.area() == bestDimension.area() && candidateDimension.width() + candidateDimension.height() < bestDimension.width() + bestDimension.height())) - bestDimension = candidateDimension; - } - } - - return bestDimension; -} - -uint ThingType::getSpriteIndex(int w, int h, int l, int x, int y, int z, int a) { - uint index = - ((((((a % m_animationPhases) - * m_numPatternZ + z) - * m_numPatternY + y) - * m_numPatternX + x) - * m_layers + l) - * m_size.height() + h) - * m_size.width() + w; - VALIDATE(index < m_spritesIndex.size()); - return index; -} - -uint ThingType::getTextureIndex(int l, int x, int y, int z) { - return ((l * m_numPatternZ + z) - * m_numPatternY + y) - * m_numPatternX + x; -} - -int ThingType::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase) -{ - if(m_null) - return 0; - - getTexture(animationPhase); // we must calculate it anyway. - int frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern); - Size size = m_texturesFramesOriginRects[animationPhase][frameIndex].size() - m_texturesFramesOffsets[animationPhase][frameIndex].toSize(); - return std::max(size.width(), size.height()); -} - -void ThingType::setPathable(bool var) -{ - if(var == true) - m_attribs.remove(ThingAttrNotPathable); - else - m_attribs.set(ThingAttrNotPathable, true); -} \ No newline at end of file diff --git a/src/client/thingtype.h b/src/client/thingtype.h deleted file mode 100644 index 0edd4ef..0000000 --- a/src/client/thingtype.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef THINGTYPE_H -#define THINGTYPE_H - -#include "declarations.h" -#include "animator.h" - -#include -#include -#include -#include -#include -#include -#include - -enum NewDrawType : uint8 { - NewDrawNormal = 0, - NewDrawMount = 5, - NewDrawOutfit = 6, - NewDrawOutfitLayers = 7, - NewDrawMissle = 10 -}; - -enum FrameGroupType : uint8 { - FrameGroupDefault = 0, - FrameGroupIdle = FrameGroupDefault, - FrameGroupMoving -}; - -enum ThingCategory : uint8 { - ThingCategoryItem = 0, - ThingCategoryCreature, - ThingCategoryEffect, - ThingCategoryMissile, - ThingInvalidCategory, - ThingLastCategory = ThingInvalidCategory -}; - -enum ThingAttr : uint8 { - ThingAttrGround = 0, - ThingAttrGroundBorder = 1, - ThingAttrOnBottom = 2, - ThingAttrOnTop = 3, - ThingAttrContainer = 4, - ThingAttrStackable = 5, - ThingAttrForceUse = 6, - ThingAttrMultiUse = 7, - ThingAttrWritable = 8, - ThingAttrWritableOnce = 9, - ThingAttrFluidContainer = 10, - ThingAttrSplash = 11, - ThingAttrNotWalkable = 12, - ThingAttrNotMoveable = 13, - ThingAttrBlockProjectile = 14, - ThingAttrNotPathable = 15, - ThingAttrPickupable = 16, - ThingAttrHangable = 17, - ThingAttrHookSouth = 18, - ThingAttrHookEast = 19, - ThingAttrRotateable = 20, - ThingAttrLight = 21, - ThingAttrDontHide = 22, - ThingAttrTranslucent = 23, - ThingAttrDisplacement = 24, - ThingAttrElevation = 25, - ThingAttrLyingCorpse = 26, - ThingAttrAnimateAlways = 27, - ThingAttrMinimapColor = 28, - ThingAttrLensHelp = 29, - ThingAttrFullGround = 30, - ThingAttrLook = 31, - ThingAttrCloth = 32, - ThingAttrMarket = 33, - ThingAttrUsable = 34, - ThingAttrWrapable = 35, - ThingAttrUnwrapable = 36, - ThingAttrTopEffect = 37, - - // additional - ThingAttrOpacity = 100, - ThingAttrNotPreWalkable = 101, - - ThingAttrFloorChange = 252, - ThingAttrNoMoveAnimation = 253, // 10.10: real value is 16, but we need to do this for backwards compatibility - ThingAttrChargeable = 254, // deprecated - ThingLastAttr = 255 -}; - -enum SpriteMask { - SpriteMask = 1, -}; - -struct MarketData { - std::string name; - int category; - uint16 requiredLevel; - uint16 restrictVocation; - uint16 showAs; - uint16 tradeAs; -}; - -struct StoreCategory { - std::string name; - std::string description; - int state; - std::string icon; - std::string parent; -}; - -struct StoreOffer { - int id; - std::string name; - std::string description; - int price; - int state; - std::string icon; -}; - -struct Imbuement { - int id; - std::string name; - std::string description; - std::string group; - int imageId; - int duration; - bool premiumOnly; - std::vector> sources; - int cost; - int successRate; - int protectionCost; -}; - -struct Light { - Point pos; - uint8_t color = 215; - uint8_t intensity = 0; -}; - -class ThingType : public LuaObject -{ -public: - ThingType(); - - void unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin); - void unserializeOtml(const OTMLNodePtr& node); - void unload(); - - void serialize(const FileStreamPtr& fin); - void exportImage(std::string fileName); - void replaceSprites(std::map& replacements, std::string fileName); - - DrawQueueItem* draw(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, Color color = Color::white, LightView* lightView = nullptr); - DrawQueueItem* draw(const Rect& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, Color color = Color::white); - void drawOutfit(const Point& dest, int xPattern, int yPattern, int zPattern, int animationPhase, int colors, Color color = Color::white, LightView* lightView = nullptr); - Rect getDrawSize(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase); - - uint16 getId() { return m_id; } - ThingCategory getCategory() { return m_category; } - bool isNull() { return m_null; } - bool hasAttr(ThingAttr attr) { return m_attribs.has(attr); } - bool isLoaded() { return m_loaded; } - ticks_t getLastUsage() { return m_lastUsage; } - - Size getSize() { return m_size; } - int getWidth() { return m_size.width(); } - int getHeight() { return m_size.height(); } - int getExactSize(int layer = 0, int xPattern = 0, int yPattern = 0, int zPattern = 0, int animationPhase = 0); - int getRealSize() { return m_realSize; } - int getLayers() { return m_layers; } - int getNumPatternX() { return m_numPatternX; } - int getNumPatternY() { return m_numPatternY; } - int getNumPatternZ() { return m_numPatternZ; } - int getAnimationPhases() { return m_animationPhases; } - AnimatorPtr getAnimator() { return m_animator; } - AnimatorPtr getIdleAnimator() { return m_idleAnimator; } - Point getDisplacement() { return m_displacement; } - int getDisplacementX() { return getDisplacement().x; } - int getDisplacementY() { return getDisplacement().y; } - int getElevation() { return m_elevation; } - - int getGroundSpeed() { return m_attribs.get(ThingAttrGround); } - int getMaxTextLength() { return m_attribs.has(ThingAttrWritableOnce) ? m_attribs.get(ThingAttrWritableOnce) : m_attribs.get(ThingAttrWritable); } - Light getLight() { return m_attribs.get(ThingAttrLight); } - int getMinimapColor() { return m_attribs.get(ThingAttrMinimapColor); } - int getLensHelp() { return m_attribs.get(ThingAttrLensHelp); } - int getClothSlot() { return m_attribs.get(ThingAttrCloth); } - MarketData getMarketData() { return m_attribs.get(ThingAttrMarket); } - bool isGround() { return m_attribs.has(ThingAttrGround); } - bool isGroundBorder() { return m_attribs.has(ThingAttrGroundBorder); } - bool isOnBottom() { return m_attribs.has(ThingAttrOnBottom); } - bool isOnTop() { return m_attribs.has(ThingAttrOnTop); } - bool isContainer() { return m_attribs.has(ThingAttrContainer); } - bool isStackable() { return m_attribs.has(ThingAttrStackable); } - bool isForceUse() { return m_attribs.has(ThingAttrForceUse); } - bool isMultiUse() { return m_attribs.has(ThingAttrMultiUse); } - bool isWritable() { return m_attribs.has(ThingAttrWritable); } - bool isChargeable() { return m_attribs.has(ThingAttrChargeable); } - bool isWritableOnce() { return m_attribs.has(ThingAttrWritableOnce); } - bool isFluidContainer() { return m_attribs.has(ThingAttrFluidContainer); } - bool isSplash() { return m_attribs.has(ThingAttrSplash); } - bool isNotWalkable() { return m_attribs.has(ThingAttrNotWalkable); } - bool isNotMoveable() { return m_attribs.has(ThingAttrNotMoveable); } - bool blockProjectile() { return m_attribs.has(ThingAttrBlockProjectile); } - bool isNotPathable() { return m_attribs.has(ThingAttrNotPathable); } - bool isPickupable() { return m_attribs.has(ThingAttrPickupable); } - bool isHangable() { return m_attribs.has(ThingAttrHangable); } - bool isHookSouth() { return m_attribs.has(ThingAttrHookSouth); } - bool isHookEast() { return m_attribs.has(ThingAttrHookEast); } - bool isRotateable() { return m_attribs.has(ThingAttrRotateable); } - bool hasLight() { return m_attribs.has(ThingAttrLight); } - bool isDontHide() { return m_attribs.has(ThingAttrDontHide); } - bool isTranslucent() { return m_attribs.has(ThingAttrTranslucent); } - bool hasDisplacement() { return m_attribs.has(ThingAttrDisplacement); } - bool hasElevation() { return m_attribs.has(ThingAttrElevation); } - bool isLyingCorpse() { return m_attribs.has(ThingAttrLyingCorpse); } - bool isAnimateAlways() { return m_attribs.has(ThingAttrAnimateAlways); } - bool hasMiniMapColor() { return m_attribs.has(ThingAttrMinimapColor); } - bool hasLensHelp() { return m_attribs.has(ThingAttrLensHelp); } - bool isFullGround() { return m_attribs.has(ThingAttrFullGround); } - bool isIgnoreLook() { return m_attribs.has(ThingAttrLook); } - bool isCloth() { return m_attribs.has(ThingAttrCloth); } - bool isMarketable() { return m_attribs.has(ThingAttrMarket); } - bool isUsable() { return m_attribs.has(ThingAttrUsable); } - bool isWrapable() { return m_attribs.has(ThingAttrWrapable); } - bool isUnwrapable() { return m_attribs.has(ThingAttrUnwrapable); } - bool isTopEffect() { return m_attribs.has(ThingAttrTopEffect); } - - std::vector getSprites() { return m_spritesIndex; } - - // additional - float getOpacity() { return m_opacity; } - bool isNotPreWalkable() { return m_attribs.has(ThingAttrNotPreWalkable); } - void setPathable(bool var); - -private: - const TexturePtr& getTexture(int animationPhase); - Size getBestTextureDimension(int w, int h, int count); - uint getSpriteIndex(int w, int h, int l, int x, int y, int z, int a); - uint getTextureIndex(int l, int x, int y, int z); - - ThingCategory m_category; - uint16 m_id; - bool m_null; - stdext::dynamic_storage m_attribs; - - Size m_size; - Point m_displacement; - AnimatorPtr m_animator; - AnimatorPtr m_idleAnimator; - int m_animationPhases; - int m_exactSize; - int m_realSize; - int m_numPatternX, m_numPatternY, m_numPatternZ; - int m_layers; - int m_elevation; - float m_opacity; - std::string m_customImage; - - std::vector m_spritesIndex; - std::vector m_textures; - std::vector> m_texturesFramesRects; - std::vector> m_texturesFramesOriginRects; - std::vector> m_texturesFramesOffsets; - - bool m_loaded = false; - time_t m_lastUsage; -}; - -#endif diff --git a/src/client/thingtypemanager.cpp b/src/client/thingtypemanager.cpp deleted file mode 100644 index 9ce64cf..0000000 --- a/src/client/thingtypemanager.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "thingtypemanager.h" -#include "spritemanager.h" -#include "thing.h" -#include "thingtype.h" -#include "itemtype.h" -#include "creature.h" -#include "creatures.h" -#include "game.h" - -#include -#include -#include -#include -#include -#include - -ThingTypeManager g_things; - -void ThingTypeManager::init() -{ - m_nullThingType = ThingTypePtr(new ThingType); - m_nullItemType = ItemTypePtr(new ItemType); - m_datSignature = 0; - m_contentRevision = 0; - m_otbMinorVersion = 0; - m_otbMajorVersion = 0; - m_datLoaded = false; - m_xmlLoaded = false; - m_otbLoaded = false; - for (int i = 0; i < ThingLastCategory; ++i) { - m_thingTypes[i].resize(1, m_nullThingType); - m_checkIndex[i] = 0; - } - m_itemTypes.resize(1, m_nullItemType); - - check(); -} - -void ThingTypeManager::terminate() -{ - for(int i = 0; i < ThingLastCategory; ++i) - m_thingTypes[i].clear(); - m_itemTypes.clear(); - m_reverseItemTypes.clear(); - m_marketCategories.clear(); - m_nullThingType = nullptr; - m_nullItemType = nullptr; - - if (m_checkEvent) { - m_checkEvent->cancel(); - m_checkEvent = nullptr; - } -} - -void ThingTypeManager::check() -{ - // removes unused textures from memory after 60s, 500 checks / s - m_checkEvent = g_dispatcher.scheduleEvent(std::bind(&ThingTypeManager::check, &g_things), 1000); - - for (size_t i = 0; i < ThingLastCategory; ++i) { - size_t limit = std::min(m_checkIndex[i] + 100, m_thingTypes[i].size()); - for (size_t j = m_checkIndex[i]; j < limit; ++j) { - if (m_thingTypes[i][j]->isLoaded() && m_thingTypes[i][j]->getLastUsage() + 60 < g_clock.seconds()) { - m_thingTypes[i][j]->unload(); - } - } - m_checkIndex[i] = limit; - if (m_checkIndex[i] >= m_thingTypes[i].size()) { - m_checkIndex[i] = 0; - } - } -} - -#ifdef WITH_ENCRYPTION -void ThingTypeManager::saveDat(std::string fileName) -{ - if(!m_datLoaded) - stdext::throw_exception("failed to save, dat is not loaded"); - - try { - FileStreamPtr fin = g_resources.createFile(fileName); - if(!fin) - stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName)); - - fin->addU32(m_datSignature); - - for(int category = 0; category < ThingLastCategory; ++category) - fin->addU16(m_thingTypes[category].size() - 1); - - for(int category = 0; category < ThingLastCategory; ++category) { - uint16 firstId = 1; - if(category == ThingCategoryItem) - firstId = 100; - - for(uint16 id = firstId; id < m_thingTypes[category].size(); ++id) - m_thingTypes[category][id]->serialize(fin); - } - - - fin->flush(); - fin->close(); - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what())); - } -} - -void ThingTypeManager::dumpTextures(std::string dir) -{ - if (dir.empty()) { - g_logger.error("Empty dir for sprites dump"); - return; - } - g_resources.makeDir(dir); - for (int category = 0; category < ThingLastCategory; ++category) { - g_resources.makeDir(dir + "/" + std::to_string((int)category)); - - uint16 firstId = 1; - if (category == ThingCategoryItem) - firstId = 100; - - for (uint16 id = firstId; id < m_thingTypes[category].size(); ++id) - m_thingTypes[category][id]->exportImage(dir + "/" + std::to_string((int)category) + "/" + std::to_string(id) + ".png"); - } -} - -void ThingTypeManager::replaceTextures(std::string dir) { - if (dir.empty()) { - g_logger.error("Empty dir for sprites dump"); - return; - } - - std::map replacements; - for (int category = 0; category < ThingLastCategory; ++category) { - uint16 firstId = 1; - if (category == ThingCategoryItem) - firstId = 100; - - for (uint16 id = firstId; id < m_thingTypes[category].size(); ++id) { - std::string fileName = dir + "/" + std::to_string((int)category) + "/" + std::to_string(id) + "_[][x2.000000].png"; - m_thingTypes[category][id]->replaceSprites(replacements, fileName); - } - } - //g_sprites.saveReplacedSpr(dir + "/sprites.spr", replacements); -} - -#endif - -bool ThingTypeManager::loadDat(std::string file) -{ - m_datLoaded = false; - m_datSignature = 0; - m_contentRevision = 0; - try { - file = g_resources.guessFilePath(file, "dat"); - - FileStreamPtr fin = g_resources.openFile(file); - - m_datSignature = fin->getU32(); - m_contentRevision = static_cast(m_datSignature); - - for(int category = 0; category < ThingLastCategory; ++category) { - int count = fin->getU16() + 1; - m_thingTypes[category].clear(); - m_thingTypes[category].resize(count, m_nullThingType); - } - - m_marketCategories.clear(); - for(int category = 0; category < ThingLastCategory; ++category) { - uint16 firstId = 1; - if(category == ThingCategoryItem) - firstId = 100; - for(uint16 id = firstId; id < m_thingTypes[category].size(); ++id) { - ThingTypePtr type(new ThingType); - type->unserialize(id, (ThingCategory)category, fin); - m_thingTypes[category][id] = type; - if (type->isMarketable()) { - auto marketData = type->getMarketData(); - m_marketCategories.insert(marketData.category); - } - } - } - - m_datLoaded = true; - g_lua.callGlobalField("g_things", "onLoadDat", file); - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Failed to read dat '%s': %s'", file, e.what())); - return false; - } -} - -bool ThingTypeManager::loadOtml(std::string file) -{ - try { - file = g_resources.guessFilePath(file, "otml"); - - OTMLDocumentPtr doc = OTMLDocument::parse(file); - for(const OTMLNodePtr& node : doc->children()) { - ThingCategory category; - if(node->tag() == "creatures") - category = ThingCategoryCreature; - else if(node->tag() == "items") - category = ThingCategoryItem; - else if(node->tag() == "effects") - category = ThingCategoryEffect; - else if(node->tag() == "missiles") - category = ThingCategoryMissile; - else { - throw OTMLException(node, "not a valid thing category"); - } - - for(const OTMLNodePtr& node2 : node->children()) { - uint16 id = stdext::safe_cast(node2->tag()); - ThingTypePtr type = getThingType(id, category); - if(!type) - throw OTMLException(node2, "thing not found"); - type->unserializeOtml(node2); - } - } - return true; - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to read dat otml '%s': %s'", file, e.what())); - return false; - } -} - -void ThingTypeManager::loadOtb(const std::string& file) -{ - try { - FileStreamPtr fin = g_resources.openFile(file); - - uint signature = fin->getU32(); - if (signature != 0) - stdext::throw_exception("invalid otb file"); - - BinaryTreePtr root = fin->getBinaryTree(); - root->skip(1); // otb first byte is always 0 - - signature = root->getU32(); - if (signature != 0) - stdext::throw_exception("invalid otb file"); - - uint8 rootAttr = root->getU8(); - if (rootAttr == 0x01) { // OTB_ROOT_ATTR_VERSION - uint16 size = root->getU16(); - if (size != 4 + 4 + 4 + 128) - stdext::throw_exception("invalid otb root attr version size"); - - m_otbMajorVersion = root->getU32(); - m_otbMinorVersion = root->getU32(); - root->skip(4); // buildNumber - root->skip(128); // description - } - - BinaryTreeVec children = root->getChildren(); - m_reverseItemTypes.clear(); - m_itemTypes.resize(children.size() + 1, m_nullItemType); - m_reverseItemTypes.resize(children.size() + 1, m_nullItemType); - - for (const BinaryTreePtr& node : children) { - ItemTypePtr itemType(new ItemType); - itemType->unserialize(node); - addItemType(itemType); - - uint16 clientId = itemType->getClientId(); - if (unlikely(clientId >= m_reverseItemTypes.size())) - m_reverseItemTypes.resize(clientId + 1); - m_reverseItemTypes[clientId] = itemType; - } - - m_otbLoaded = true; - g_lua.callGlobalField("g_things", "onLoadOtb", file); - } catch (std::exception& e) { - g_logger.error(stdext::format("Failed to load '%s' (OTB file): %s", file, e.what())); - } -} - - -void ThingTypeManager::loadXml(const std::string& file) -{ - try { - if(!isOtbLoaded()) - stdext::throw_exception("OTB must be loaded before XML"); - - TiXmlDocument doc; - doc.Parse(g_resources.readFileContents(file).c_str()); - if(doc.Error()) - stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc())); - - TiXmlElement* root = doc.FirstChildElement(); - if(!root || root->ValueTStr() != "items") - stdext::throw_exception("invalid root tag name"); - - for(TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) { - if(unlikely(element->ValueTStr() != "item")) - continue; - - uint16 id = element->readType("id"); - if(id != 0) { - std::vector s_ids = stdext::split(element->Attribute("id"), ";"); - for(const std::string& s : s_ids) { - std::vector ids = stdext::split(s, "-"); - if(ids.size() > 1) { - int32 i = ids[0]; - while(i <= ids[1]) - parseItemType(i++, element); - } else - parseItemType(atoi(s.c_str()), element); - } - } else { - std::vector begin = stdext::split(element->Attribute("fromid"), ";"); - std::vector end = stdext::split(element->Attribute("toid"), ";"); - if(begin[0] && begin.size() == end.size()) { - size_t size = begin.size(); - for(size_t i = 0; i < size; ++i) - while(begin[i] <= end[i]) - parseItemType(begin[i]++, element); - } - } - } - - doc.Clear(); - m_xmlLoaded = true; - g_logger.debug("items.xml read successfully."); - } catch(std::exception& e) { - g_logger.error(stdext::format("Failed to load '%s' (XML file): %s", file, e.what())); - } -} - -void ThingTypeManager::parseItemType(uint16 serverId, TiXmlElement* elem) -{ - ItemTypePtr itemType = nullptr; - - bool s; - int d; - - if(g_game.getClientVersion() < 960) { - s = serverId > 20000 && serverId < 20100; - d = 20000; - } else { - s = serverId > 30000 && serverId < 30100; - d = 30000; - } - - if(s) { - serverId -= d; - itemType = ItemTypePtr(new ItemType); - itemType->setServerId(serverId); - addItemType(itemType); - } else - itemType = getItemType(serverId); - - itemType->setName(elem->Attribute("name")); - for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) { - std::string key = attrib->Attribute("key"); - if(key.empty()) - continue; - - stdext::tolower(key); - if(key == "description") - itemType->setDesc(attrib->Attribute("value")); - else if(key == "weapontype") - itemType->setCategory(ItemCategoryWeapon); - else if(key == "ammotype") - itemType->setCategory(ItemCategoryAmmunition); - else if(key == "armor") - itemType->setCategory(ItemCategoryArmor); - else if(key == "charges") - itemType->setCategory(ItemCategoryCharges); - else if(key == "type") { - std::string value = attrib->Attribute("value"); - stdext::tolower(value); - - if(value == "key") - itemType->setCategory(ItemCategoryKey); - else if(value == "magicfield") - itemType->setCategory(ItemCategoryMagicField); - else if(value == "teleport") - itemType->setCategory(ItemCategoryTeleport); - else if(value == "door") - itemType->setCategory(ItemCategoryDoor); - } - } -} - -void ThingTypeManager::addItemType(const ItemTypePtr& itemType) -{ - uint16 id = itemType->getServerId(); - if(unlikely(id >= m_itemTypes.size())) - m_itemTypes.resize(id + 1, m_nullItemType); - m_itemTypes[id] = itemType; -} - -const ItemTypePtr& ThingTypeManager::findItemTypeByClientId(uint16 id) -{ - if(id == 0 || id >= m_reverseItemTypes.size()) - return m_nullItemType; - - if(m_reverseItemTypes[id]) - return m_reverseItemTypes[id]; - else - return m_nullItemType; -} - -const ItemTypePtr& ThingTypeManager::findItemTypeByName(std::string name) -{ - for(const ItemTypePtr& it : m_itemTypes) - if(it->getName() == name) - return it; - return m_nullItemType; -} - -ItemTypeList ThingTypeManager::findItemTypesByName(std::string name) -{ - ItemTypeList ret; - for(const ItemTypePtr& it : m_itemTypes) - if(it->getName() == name) - ret.push_back(it); - return ret; -} - -ItemTypeList ThingTypeManager::findItemTypesByString(std::string name) -{ - ItemTypeList ret; - for(const ItemTypePtr& it : m_itemTypes) - if(it->getName().find(name) != std::string::npos) - ret.push_back(it); - return ret; -} - -const ThingTypePtr& ThingTypeManager::getThingType(uint16 id, ThingCategory category) -{ - if(category >= ThingLastCategory || id >= m_thingTypes[category].size()) { - g_logger.error(stdext::format("invalid thing type client id %d in category %d", id, category)); - return m_nullThingType; - } - return m_thingTypes[category][id]; -} - -const ItemTypePtr& ThingTypeManager::getItemType(uint16 id) -{ - if(id >= m_itemTypes.size() || m_itemTypes[id] == m_nullItemType) { - g_logger.error(stdext::format("invalid thing type, server id: %d", id)); - return m_nullItemType; - } - return m_itemTypes[id]; -} - -ThingTypeList ThingTypeManager::findThingTypeByAttr(ThingAttr attr, ThingCategory category) -{ - ThingTypeList ret; - for(const ThingTypePtr& type : m_thingTypes[category]) - if(type->hasAttr(attr)) - ret.push_back(type); - return ret; -} - -ItemTypeList ThingTypeManager::findItemTypeByCategory(ItemCategory category) -{ - ItemTypeList ret; - for(const ItemTypePtr& type : m_itemTypes) - if(type->getCategory() == category) - ret.push_back(type); - return ret; -} - -const ThingTypeList& ThingTypeManager::getThingTypes(ThingCategory category) -{ - ThingTypeList ret; - if(category >= ThingLastCategory) - stdext::throw_exception(stdext::format("invalid thing type category %d", category)); - return m_thingTypes[category]; -} - -/* vim: set ts=4 sw=4 et: */ diff --git a/src/client/thingtypemanager.h b/src/client/thingtypemanager.h deleted file mode 100644 index 2892383..0000000 --- a/src/client/thingtypemanager.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef THINGTYPEMANAGER_H -#define THINGTYPEMANAGER_H - -#include -#include -#include - -#include "thingtype.h" -#include "itemtype.h" - -class ThingTypeManager -{ -public: - void init(); - void terminate(); - void check(); - - bool loadDat(std::string file); - bool loadOtml(std::string file); - void loadOtb(const std::string& file); - void loadXml(const std::string& file); - void parseItemType(uint16 id, TiXmlElement *elem); - -#ifdef WITH_ENCRYPTION - void saveDat(std::string fileName); - void dumpTextures(std::string dir); - void replaceTextures(std::string dir); -#endif - - void addItemType(const ItemTypePtr& itemType); - const ItemTypePtr& findItemTypeByClientId(uint16 id); - const ItemTypePtr& findItemTypeByName(std::string name); - ItemTypeList findItemTypesByName(std::string name); - ItemTypeList findItemTypesByString(std::string str); - - std::set getMarketCategories() - { - return m_marketCategories; - } - - const ThingTypePtr& getNullThingType() { return m_nullThingType; } - const ItemTypePtr& getNullItemType() { return m_nullItemType; } - - const ThingTypePtr& getThingType(uint16 id, ThingCategory category); - const ItemTypePtr& getItemType(uint16 id); - ThingType* rawGetThingType(uint16 id, ThingCategory category) { - VALIDATE(id < m_thingTypes[category].size()); - return m_thingTypes[category][id].get(); - } - ItemType* rawGetItemType(uint16 id) { - VALIDATE(id < m_itemTypes.size()); - return m_itemTypes[id].get(); - } - - ThingTypeList findThingTypeByAttr(ThingAttr attr, ThingCategory category); - ItemTypeList findItemTypeByCategory(ItemCategory category); - - const ThingTypeList& getThingTypes(ThingCategory category); - const ItemTypeList& getItemTypes() { return m_itemTypes; } - - uint32 getDatSignature() { return m_datSignature; } - uint32 getOtbMajorVersion() { return m_otbMajorVersion; } - uint32 getOtbMinorVersion() { return m_otbMinorVersion; } - uint16 getContentRevision() { return m_contentRevision; } - - bool isDatLoaded() { return m_datLoaded; } - bool isXmlLoaded() { return m_xmlLoaded; } - bool isOtbLoaded() { return m_otbLoaded; } - - bool isValidDatId(uint16 id, ThingCategory category) { return id >= 1 && id < m_thingTypes[category].size(); } - bool isValidOtbId(uint16 id) { return id >= 1 && id < m_itemTypes.size(); } - -private: - ThingTypeList m_thingTypes[ThingLastCategory]; - ItemTypeList m_reverseItemTypes; - ItemTypeList m_itemTypes; - std::set m_marketCategories; - - ThingTypePtr m_nullThingType; - ItemTypePtr m_nullItemType; - - bool m_datLoaded; - bool m_xmlLoaded; - bool m_otbLoaded; - - uint32 m_otbMinorVersion; - uint32 m_otbMajorVersion; - uint32 m_datSignature; - uint16 m_contentRevision; - - ScheduledEventPtr m_checkEvent; - size_t m_checkIndex[ThingLastCategory]; -}; - -extern ThingTypeManager g_things; - -#endif diff --git a/src/client/tile.cpp b/src/client/tile.cpp deleted file mode 100644 index 9d6ed15..0000000 --- a/src/client/tile.cpp +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "tile.h" -#include "item.h" -#include "thingtypemanager.h" -#include "map.h" -#include "game.h" -#include "localplayer.h" -#include "effect.h" -#include "protocolgame.h" -#include "lightview.h" -#include "spritemanager.h" -#include -#include -#include - -Tile::Tile(const Position& position) : - m_position(position), - m_drawElevation(0), - m_minimapColor(0), - m_flags(0) -{ -} - -void Tile::drawBottom(const Point& dest, LightView* lightView) -{ - m_topDraws = 0; - m_drawElevation = 0; - if (m_fill != Color::alpha) { - g_drawQueue->addFilledRect(Rect(dest, Otc::TILE_PIXELS, Otc::TILE_PIXELS), m_fill); - return; - } - - // bottom things - for (const ThingPtr& thing : m_things) { - if (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom()) - break; - if (thing->isHidden()) - continue; - - thing->draw(dest - m_drawElevation, true, lightView); - m_drawElevation = std::min(m_drawElevation + thing->getElevation(), Otc::MAX_ELEVATION); - } - - // common items, reverse order - int redrawPreviousTopW = 0, redrawPreviousTopH = 0; - for (auto it = m_things.rbegin(); it != m_things.rend(); ++it) { - const ThingPtr& thing = *it; - if (thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->isCreature()) - break; - if (thing->isHidden()) - continue; - - thing->draw(dest - m_drawElevation, true, lightView); - m_drawElevation = std::min(m_drawElevation + thing->getElevation(), Otc::MAX_ELEVATION); - - if (thing->isLyingCorpse()) { - redrawPreviousTopW = std::max(thing->getWidth() - 1, redrawPreviousTopW); - redrawPreviousTopH = std::max(thing->getHeight() - 1, redrawPreviousTopH); - } - } - - for (int x = -redrawPreviousTopW; x <= 0; ++x) { - for (int y = -redrawPreviousTopH; y <= 0; ++y) { - if (x == 0 && y == 0) - continue; - if(const TilePtr& tile = g_map.getTile(m_position.translated(x, y))) - tile->drawTop(dest + Point(x * Otc::TILE_PIXELS, y * Otc::TILE_PIXELS), lightView); - } - } - - if (lightView && hasTranslucentLight()) { - lightView->addLight(dest + Point(16, 16), 215, 1); - } -} - -void Tile::drawTop(const Point& dest, LightView* lightView) -{ - if (m_fill != Color::alpha) - return; - if (m_topDraws++ < m_topCorrection) - return; - - // walking creatures - for (const CreaturePtr& creature : m_walkingCreatures) { - if (creature->isHidden()) - continue; - Point creatureDest(dest.x + ((creature->getPrewalkingPosition().x - m_position.x) * Otc::TILE_PIXELS - m_drawElevation), - dest.y + ((creature->getPrewalkingPosition().y - m_position.y) * Otc::TILE_PIXELS - m_drawElevation)); - creature->draw(creatureDest, true, lightView); - } - - // creatures - std::vector creaturesToDraw; - int limit = g_adaptiveRenderer.creaturesLimit(); - for (auto& thing : m_things) { - if (!thing->isCreature() || thing->isHidden()) - continue; - if (limit-- <= 0) - break; - CreaturePtr creature = thing->static_self_cast(); - if (!creature || creature->isWalking()) - continue; - creature->draw(dest - m_drawElevation, true, lightView); - } - - // effects - limit = std::min((int)m_effects.size() - 1, g_adaptiveRenderer.effetsLimit()); - for (int i = limit; i >= 0; --i) { - if (m_effects[i]->isHidden()) - continue; - m_effects[i]->draw(dest - m_drawElevation, m_position.x - g_map.getCentralPosition().x, m_position.y - g_map.getCentralPosition().y, true, lightView); - } - - // top - for (const ThingPtr& thing : m_things) { - if (!thing->isOnTop() || thing->isHidden()) - continue; - thing->draw(dest - m_drawElevation, true, lightView); - m_drawElevation = std::min(m_drawElevation + thing->getElevation(), Otc::MAX_ELEVATION); - } -} - - -void Tile::calculateCorpseCorrection() { - m_topCorrection = 0; - int redrawPreviousTopW = 0, redrawPreviousTopH = 0; - for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) { - const ThingPtr& thing = *it; - if(!thing->isLyingCorpse()) { - continue; - } - if (thing->isHidden()) - continue; - redrawPreviousTopW = std::max(thing->getWidth() - 1, redrawPreviousTopW); - redrawPreviousTopH = std::max(thing->getHeight() - 1, redrawPreviousTopH); - } - - for (int x = -redrawPreviousTopW; x <= 0; ++x) { - for (int y = -redrawPreviousTopH; y <= 0; ++y) { - if (x == 0 && y == 0) - continue; - if (const TilePtr& tile = g_map.getTile(m_position.translated(x, y))) - tile->m_topCorrection += 1; - } - } -} - -void Tile::drawTexts(Point dest) -{ - if (m_timerText && g_clock.millis() < m_timer) { - if (m_text && m_text->hasText()) - dest.y -= 8; - m_timerText->setText(stdext::format("%.01f", (m_timer - g_clock.millis()) / 1000.)); - m_timerText->drawText(dest, Rect(dest.x - 64, dest.y - 64, 128, 128)); - dest.y += 16; - } - - if (m_text && m_text->hasText()) { - m_text->drawText(dest, Rect(dest.x - 64, dest.y - 64, 128, 128)); - } -} - -void Tile::clean() -{ - while(!m_things.empty()) - removeThing(m_things.front()); -} - -void Tile::addWalkingCreature(const CreaturePtr& creature) -{ - m_walkingCreatures.push_back(creature); -} - -void Tile::removeWalkingCreature(const CreaturePtr& creature) -{ - auto it = std::find(m_walkingCreatures.begin(), m_walkingCreatures.end(), creature); - if(it != m_walkingCreatures.end()) - m_walkingCreatures.erase(it); -} - -void Tile::addThing(const ThingPtr& thing, int stackPos) -{ - if(!thing) - return; - - if(thing->isEffect()) { - if(thing->isTopEffect()) - m_effects.insert(m_effects.begin(), thing->static_self_cast()); - else - m_effects.push_back(thing->static_self_cast()); - } else { - // priority 854 - // 0 - ground, --> --> - // 1 - ground borders --> --> - // 2 - bottom (walls), --> --> - // 3 - on top (doors) --> --> - // 4 - creatures, from top to bottom <-- --> - // 5 - items, from top to bottom <-- <-- - if(stackPos < 0 || stackPos == 255) { - int priority = thing->getStackPriority(); - - // -1 or 255 => auto detect position - // -2 => append - - bool append; - if(stackPos == -2) - append = true; - else { - append = (priority <= 3); - - // newer protocols does not store creatures in reverse order - if(g_game.getClientVersion() >= 854 && priority == 4) - append = !append; - } - - for(stackPos = 0; stackPos < (int)m_things.size(); ++stackPos) { - int otherPriority = m_things[stackPos]->getStackPriority(); - if((append && otherPriority > priority) || (!append && otherPriority >= priority)) - break; - } - } else if(stackPos > (int)m_things.size()) - stackPos = m_things.size(); - - m_things.insert(m_things.begin() + stackPos, thing); - - if(m_things.size() > MAX_THINGS) - removeThing(m_things[MAX_THINGS]); - - /* - // check stack priorities - // this code exists to find stackpos bugs faster - int lastPriority = 0; - for(const ThingPtr& thing : m_things) { - int priority = thing->getStackPriority(); - VALIDATE(lastPriority <= priority); - lastPriority = priority; - } - */ - } - - thing->setPosition(m_position); - thing->onAppear(); - - if(thing->isTranslucent()) - checkTranslucentLight(); - - if(g_game.isTileThingLuaCallbackEnabled()) - callLuaField("onAddThing", thing); -} - -bool Tile::removeThing(ThingPtr thing) -{ - if(!thing) - return false; - - bool removed = false; - - if(thing->isEffect()) { - EffectPtr effect = thing->static_self_cast(); - auto it = std::find(m_effects.begin(), m_effects.end(), effect); - if(it != m_effects.end()) { - m_effects.erase(it); - removed = true; - } - } else { - auto it = std::find(m_things.begin(), m_things.end(), thing); - if(it != m_things.end()) { - m_things.erase(it); - removed = true; - } - } - - if (thing->isCreature()) { - m_lastCreature = thing->getId(); - } - - thing->onDisappear(); - - if(thing->isTranslucent()) - checkTranslucentLight(); - - if (g_game.isTileThingLuaCallbackEnabled() && removed) { - callLuaField("onRemoveThing", thing); - } - - return removed; -} - -ThingPtr Tile::getThing(int stackPos) -{ - if(stackPos >= 0 && stackPos < (int)m_things.size()) - return m_things[stackPos]; - return nullptr; -} - -EffectPtr Tile::getEffect(uint16 id) -{ - for(const EffectPtr& effect : m_effects) - if(effect->getId() == id) - return effect; - return nullptr; -} - -bool Tile::hasThing(const ThingPtr& thing) -{ - return std::find(m_things.begin(), m_things.end(), thing) != m_things.end(); -} - -int Tile::getThingStackPos(const ThingPtr& thing) -{ - for(uint stackpos = 0; stackpos < m_things.size(); ++stackpos) - if(thing == m_things[stackpos]) - return stackpos; - return -1; -} - -ThingPtr Tile::getTopThing() -{ - if(isEmpty()) - return nullptr; - for(const ThingPtr& thing : m_things) - if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature()) - return thing; - return m_things[m_things.size() - 1]; -} - -std::vector Tile::getItems() -{ - std::vector items; - for(const ThingPtr& thing : m_things) { - if(!thing->isItem()) - continue; - ItemPtr item = thing->static_self_cast(); - items.push_back(item); - } - return items; -} - -std::vector Tile::getCreatures() -{ - std::vector creatures; - for(const ThingPtr& thing : m_things) { - if(thing->isCreature()) - creatures.push_back(thing->static_self_cast()); - } - return creatures; -} - -ItemPtr Tile::getGround() -{ - ThingPtr firstObject = getThing(0); - if(!firstObject) - return nullptr; - if(firstObject->isGround() && firstObject->isItem()) - return firstObject->static_self_cast(); - return nullptr; -} - -int Tile::getGroundSpeed() -{ - if (m_speed) - return m_speed; - int groundSpeed = 100; - if(ItemPtr ground = getGround()) - groundSpeed = ground->getGroundSpeed(); - return groundSpeed; -} - -uint8 Tile::getMinimapColorByte() -{ - uint8 color = 255; // alpha - if(m_minimapColor != 0) - return m_minimapColor; - - for(const ThingPtr& thing : m_things) { - if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()) - break; - uint8 c = thing->getMinimapColor(); - if(c != 0) - color = c; - } - return color; -} - -ThingPtr Tile::getTopLookThing() -{ - if(isEmpty()) - return nullptr; - - for(uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if(!thing->isIgnoreLook() && (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop())) - return thing; - } - - return m_things[0]; -} - -ThingPtr Tile::getTopLookThingEx(Point offset) -{ - auto creature = getTopCreatureEx(offset); - if (creature) - return creature; - - if (isEmpty()) - return nullptr; - - for (uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if (!thing->isIgnoreLook() && (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature())) - return thing; - } - - return m_things[0]; -} - -ThingPtr Tile::getTopUseThing() -{ - if(isEmpty()) - return nullptr; - - for(uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if (thing->isForceUse() || (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature() && !thing->isSplash())) - return thing; - } - - for (uint i = m_things.size() - 1; i > 0; --i) { - ThingPtr thing = m_things[i]; - if (!thing->isSplash() && !thing->isCreature()) - return thing; - } - - return m_things[0]; -} - -CreaturePtr Tile::getTopCreature() -{ - CreaturePtr creature; - for(uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if(thing->isLocalPlayer()) // return local player if there is no other creature - creature = thing->static_self_cast(); - else if(thing->isCreature() && !thing->isLocalPlayer()) - return thing->static_self_cast(); - } - if(!creature && !m_walkingCreatures.empty()) - creature = m_walkingCreatures.back(); - - // check for walking creatures in tiles around - if(!creature) { - for(int xi=-1;xi<=1;++xi) { - for(int yi=-1;yi<=1;++yi) { - Position pos = m_position.translated(xi, yi); - if(pos == m_position) - continue; - - const TilePtr& tile = g_map.getTile(pos); - if(tile) { - for(const CreaturePtr& c : tile->getCreatures()) { - if(c->isWalking() && c->getLastStepFromPosition() == m_position && c->getStepProgress() < 0.75f) { - creature = c; - } - } - } - } - } - } - return creature; -} - -CreaturePtr Tile::getTopCreatureEx(Point offset) -{ - // hidden - return nullptr; -} - -ThingPtr Tile::getTopMoveThing() -{ - if(isEmpty()) - return nullptr; - - for(uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature()) { - if(i > 0 && thing->isNotMoveable()) - return m_things[i-1]; - return thing; - } - } - - for(const ThingPtr& thing : m_things) { - if(thing->isCreature()) - return thing; - } - - return m_things[0]; -} - -ThingPtr Tile::getTopMultiUseThing() -{ - if (isEmpty()) - return nullptr; - - if (CreaturePtr topCreature = getTopCreature()) - return topCreature; - - for (uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if (thing->isForceUse()) - return thing; - } - - for (uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()) { - if (i > 0 && thing->isSplash()) - return m_things[i - 1]; - return thing; - } - } - - return m_things.back(); -} - -ThingPtr Tile::getTopMultiUseThingEx(Point offset) -{ - if (CreaturePtr topCreature = getTopCreatureEx(offset)) - return topCreature; - - if (isEmpty()) - return nullptr; - - for (uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if (thing->isForceUse() && !thing->isCreature()) - return thing; - } - - for (uint i = 0; i < m_things.size(); ++i) { - ThingPtr thing = m_things[i]; - if (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature()) { - if (i > 0 && thing->isSplash()) - return m_things[i - 1]; - return thing; - } - } - - for (uint i = m_things.size() - 1; i > 0; --i) { - ThingPtr thing = m_things[i]; - if (!thing->isCreature()) - return thing; - } - - return m_things[0]; -} - -bool Tile::isWalkable(bool ignoreCreatures) -{ - if(!getGround()) - return false; - - for(const ThingPtr& thing : m_things) { - if(thing->isNotWalkable()) - return false; - - if(!ignoreCreatures) { - if(thing->isCreature()) { - CreaturePtr creature = thing->static_self_cast(); - if(!creature->isPassable() && creature->canBeSeen() && !creature->isLocalPlayer()) - return false; - } - } - } - return true; -} - -bool Tile::isPathable() -{ - for(const ThingPtr& thing : m_things) - if(thing->isNotPathable()) - return false; - return true; -} - -bool Tile::isFullGround() -{ - ItemPtr ground = getGround(); - if(ground && ground->isFullGround()) - return true; - return false; -} - -bool Tile::isFullyOpaque() -{ - ThingPtr firstObject = getThing(0); - return firstObject && firstObject->isFullGround(); -} - -bool Tile::isSingleDimension() -{ - if(!m_walkingCreatures.empty()) - return false; - for(const ThingPtr& thing : m_things) - if(thing->getHeight() != 1 || thing->getWidth() != 1) - return false; - return true; -} - -bool Tile::isLookPossible() -{ - for(const ThingPtr& thing : m_things) - if(thing->blockProjectile()) - return false; - return true; -} - -bool Tile::isClickable() -{ - bool hasGround = false; - bool hasOnBottom = false; - bool hasIgnoreLook = false; - for(const ThingPtr& thing : m_things) { - if(thing->isGround()) - hasGround = true; - if(thing->isOnBottom()) - hasOnBottom = true; - if((hasGround || hasOnBottom) && !hasIgnoreLook) - return true; - } - return false; -} - -bool Tile::isEmpty() -{ - return m_things.size() == 0; -} - -bool Tile::isDrawable() -{ - return !m_things.empty() || !m_walkingCreatures.empty() || !m_effects.empty(); -} - -bool Tile::mustHookEast() -{ - for(const ThingPtr& thing : m_things) - if(thing->isHookEast()) - return true; - return false; -} - -bool Tile::mustHookSouth() -{ - for(const ThingPtr& thing : m_things) - if(thing->isHookSouth()) - return true; - return false; -} - -bool Tile::hasCreature() -{ - for(const ThingPtr& thing : m_things) - if(thing->isCreature()) - return true; - return false; -} - -bool Tile::hasBlockingCreature() -{ - for (const ThingPtr& thing : m_things) - if (thing->isCreature() && !thing->static_self_cast()->isPassable() && !thing->isLocalPlayer()) - return true; - return false; -} - -bool Tile::limitsFloorsView(bool isFreeView) -{ - // ground and walls limits the view - ThingPtr firstThing = getThing(0); - - if(isFreeView) { - if(firstThing && !firstThing->isDontHide() && (firstThing->isGround() || firstThing->isOnBottom())) - return true; - } else if(firstThing && !firstThing->isDontHide() && (firstThing->isGround() || (firstThing->isOnBottom() && firstThing->blockProjectile()))) - return true; - return false; -} - - -bool Tile::canErase() -{ - return m_walkingCreatures.empty() && m_effects.empty() && m_things.empty() && m_flags == 0 && m_minimapColor == 0; -} - -int Tile::getElevation() -{ - int elevation = 0; - for(const ThingPtr& thing : m_things) - if(thing->getElevation() > 0) - elevation++; - return elevation; -} - -bool Tile::hasElevation(int elevation) -{ - return getElevation() >= elevation; -} - -void Tile::checkTranslucentLight() -{ - if(m_position.z != Otc::SEA_FLOOR) - return; - - Position downPos = m_position; - if(!downPos.down()) - return; - - TilePtr tile = g_map.getOrCreateTile(downPos); - if(!tile) - return; - - bool translucent = false; - for(const ThingPtr& thing : m_things) { - if(thing->isTranslucent() || thing->hasLensHelp()) { - translucent = true; - break; - } - } - - if(translucent) - tile->m_flags |= TILESTATE_TRANSLUECENT_LIGHT; - else - tile->m_flags &= ~TILESTATE_TRANSLUECENT_LIGHT; -} - -void Tile::setText(const std::string& text, Color color) -{ - if (!m_text) { - m_text = StaticTextPtr(new StaticText()); - } - m_text->setText(text); - m_text->setColor(color); -} - -std::string Tile::getText() -{ - return m_text ? m_text->getCachedText().getText() : ""; -} - -void Tile::setTimer(int time, Color color) -{ - if (time > 60000) { - g_logger.warning("Max tile timer value is 300000 (300s)!"); - return; - } - m_timer = time + g_clock.millis(); - if (!m_timerText) { - m_timerText = StaticTextPtr(new StaticText()); - } - m_timerText->setColor(color); -} - -int Tile::getTimer() -{ - return m_timerText ? std::max(0, m_timer - g_clock.millis()) : 0; -} - -void Tile::setFill(Color color) -{ - m_fill = color; -} diff --git a/src/client/tile.h b/src/client/tile.h deleted file mode 100644 index 9c7198e..0000000 --- a/src/client/tile.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef TILE_H -#define TILE_H - -#include "declarations.h" -#include "mapview.h" -#include "effect.h" -#include "creature.h" -#include "item.h" -#include -#include - -enum tileflags_t -{ - TILESTATE_NONE = 0, - TILESTATE_PROTECTIONZONE = 1 << 0, - TILESTATE_TRASHED = 1 << 1, - TILESTATE_OPTIONALZONE = 1 << 2, - TILESTATE_NOLOGOUT = 1 << 3, - TILESTATE_HARDCOREZONE = 1 << 4, - TILESTATE_REFRESH = 1 << 5, - - // internal usage - TILESTATE_HOUSE = 1 << 6, - TILESTATE_TELEPORT = 1 << 17, - TILESTATE_MAGICFIELD = 1 << 18, - TILESTATE_MAILBOX = 1 << 19, - TILESTATE_TRASHHOLDER = 1 << 20, - TILESTATE_BED = 1 << 21, - TILESTATE_DEPOT = 1 << 22, - TILESTATE_TRANSLUECENT_LIGHT = 1 << 23, - - TILESTATE_LAST = 1 << 24 -}; - -class Tile : public LuaObject -{ -public: - enum { - MAX_THINGS = 10 - }; - - Tile(const Position& position); - - void calculateCorpseCorrection(); - - void drawBottom(const Point& dest, LightView* lightView = nullptr); - void drawTop(const Point& dest, LightView* lightView = nullptr); - void drawTexts(Point dest); - -public: - void clean(); - - void addWalkingCreature(const CreaturePtr& creature); - void removeWalkingCreature(const CreaturePtr& creature); - - void addThing(const ThingPtr& thing, int stackPos); - bool removeThing(ThingPtr thing); - ThingPtr getThing(int stackPos); - EffectPtr getEffect(uint16 id); - bool hasThing(const ThingPtr& thing); - int getThingStackPos(const ThingPtr& thing); - ThingPtr getTopThing(); - - ThingPtr getTopLookThing(); - ThingPtr getTopLookThingEx(Point offset); - ThingPtr getTopUseThing(); - CreaturePtr getTopCreature(); - CreaturePtr getTopCreatureEx(Point offset); - ThingPtr getTopMoveThing(); - ThingPtr getTopMultiUseThing(); - ThingPtr getTopMultiUseThingEx(Point offset); - - const Position& getPosition() { return m_position; } - int getDrawElevation() { return m_drawElevation; } - std::vector getItems(); - std::vector getCreatures(); - std::vector getWalkingCreatures() { return m_walkingCreatures; } - std::vector getThings() { return m_things; } - std::vector getEffects() { return m_effects; } - ItemPtr getGround(); - int getGroundSpeed(); - bool isBlocking() { return m_blocking != 0; } - uint8 getMinimapColorByte(); - int getThingCount() { return m_things.size() + m_effects.size(); } - bool isPathable(); - bool isWalkable(bool ignoreCreatures = false); - bool isFullGround(); - bool isFullyOpaque(); - bool isSingleDimension(); - bool isLookPossible(); - bool isClickable(); - bool isEmpty(); - bool isDrawable(); - bool hasTranslucentLight() { return m_flags & TILESTATE_TRANSLUECENT_LIGHT; } - bool mustHookSouth(); - bool mustHookEast(); - bool hasCreature(); - bool hasBlockingCreature(); - bool limitsFloorsView(bool isFreeView = false); - bool canErase(); - int getElevation(); - bool hasElevation(int elevation = 1); - void overwriteMinimapColor(uint8 color) { m_minimapColor = color; } - - void remFlag(uint32 flag) { m_flags &= ~flag; } - void setFlag(uint32 flag) { m_flags |= flag; } - void setFlags(uint32 flags) { m_flags = flags; } - bool hasFlag(uint32 flag) { return (m_flags & flag) == flag; } - uint32 getFlags() { return m_flags; } - - void setHouseId(uint32 hid) { m_houseId = hid; } - uint32 getHouseId() { return m_houseId; } - bool isHouseTile() { return m_houseId != 0 && (m_flags & TILESTATE_HOUSE) == TILESTATE_HOUSE; } - - void select() { m_selected = true; } - void unselect() { m_selected = false; } - bool isSelected() { return m_selected; } - - TilePtr asTile() { return static_self_cast(); } - - void setSpeed(uint16_t speed, uint8_t blocking) { - m_speed = speed; - m_blocking = blocking; - } - - void setText(const std::string& text, Color color); - std::string getText(); - void setTimer(int time, Color color); - int getTimer(); - void setFill(Color color); - void resetFill() { m_fill = Color::alpha; } - -private: - void checkTranslucentLight(); - - std::vector m_walkingCreatures; - std::vector m_effects; // leave this outside m_things because it has no stackpos. - std::vector m_things; - Position m_position; - uint8 m_drawElevation; - uint8 m_minimapColor; - uint32 m_flags, m_houseId; - uint16 m_speed = 0; - uint8 m_blocking = 0; - - uint32_t m_lastCreature = 0; - int m_topCorrection = 0; - int m_topDraws = 0; - - stdext::boolean m_selected; - - ticks_t m_timer = 0; - StaticTextPtr m_timerText; - StaticTextPtr m_text; - Color m_fill = Color::alpha; -}; - -#endif diff --git a/src/client/towns.cpp b/src/client/towns.cpp deleted file mode 100644 index 4c129ee..0000000 --- a/src/client/towns.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "towns.h" - -TownManager g_towns; - -Town::Town(uint32 tid, const std::string& name, const Position& pos) - : m_id(tid), m_name(name) -{ - if(pos.isValid()) - m_pos = pos; -} - -TownManager::TownManager() -{ - m_nullTown = TownPtr(new Town); -} - -void TownManager::addTown(const TownPtr &town) -{ - if(findTown(town->getId()) == m_towns.end()) - m_towns.push_back(town); -} - -void TownManager::removeTown(uint32 townId) -{ - auto it = findTown(townId); - if(it != m_towns.end()) - m_towns.erase(it); -} - -const TownPtr& TownManager::getTown(uint32 townId) -{ - auto it = std::find_if(m_towns.begin(), m_towns.end(), - [=] (const TownPtr& town) -> bool { return town->getId() == townId; }); - if(it != m_towns.end()) - return *it; - return m_nullTown; -} - -const TownPtr& TownManager::getTownByName(std::string name) -{ - auto it = std::find_if(m_towns.begin(), m_towns.end(), - [=] (const TownPtr& town) -> bool { return town->getName() == name; } ); - if(it != m_towns.end()) - return *it; - return m_nullTown; -} - -TownList::iterator TownManager::findTown(uint32 townId) -{ - return std::find_if(m_towns.begin(), m_towns.end(), - [=] (const TownPtr& town) -> bool { return town->getId() == townId; }); -} - -void TownManager::sort() -{ - m_towns.sort([] (const TownPtr& lhs, const TownPtr& rhs) { return lhs->getName() < rhs->getName(); }); -} - diff --git a/src/client/towns.h b/src/client/towns.h deleted file mode 100644 index 34ccd4b..0000000 --- a/src/client/towns.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef TOWNS_H -#define TOWNS_H - -#include "declarations.h" -#include - -class Town : public LuaObject -{ -public: - Town() { } - Town(uint32 tid, const std::string& name, const Position& pos=Position()); - - void setId(uint32 tid) { m_id = tid; } - void setName(const std::string& name) { m_name = name; } - void setPos(const Position& pos) { m_pos = pos; } - - uint32 getId() { return m_id; } - std::string getName() { return m_name; } - Position getPos() { return m_pos; } - -private: - uint32 m_id; - std::string m_name; - Position m_pos; // temple pos -}; - -class TownManager -{ -public: - TownManager(); - - void addTown(const TownPtr& town); - void removeTown(uint32 townId); - const TownPtr& getTown(uint32 townId); - const TownPtr& getTownByName(std::string name); - - void sort(); - TownList getTowns() { return m_towns; } - void clear() { m_towns.clear(); m_nullTown = nullptr; } - -private: - TownList m_towns; - TownPtr m_nullTown; - -protected: - TownList::iterator findTown(uint32 townId); -}; - -extern TownManager g_towns; - -#endif diff --git a/src/client/uicreature.cpp b/src/client/uicreature.cpp deleted file mode 100644 index caf5b99..0000000 --- a/src/client/uicreature.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uicreature.h" -#include -#include - -void UICreature::drawSelf(Fw::DrawPane drawPane) -{ - if(drawPane != Fw::ForegroundPane) - return; - - UIWidget::drawSelf(drawPane); - - if(m_creature) { - if (m_autoRotating) { - auto ticks = (g_clock.millis() % 4000) / 4; - Otc::Direction new_dir; - if (ticks < 250) - { - new_dir = Otc::South; - } - else if (ticks < 500) - { - new_dir = Otc::East; - } - else if (ticks < 750) - { - new_dir = Otc::North; - } - else - { - new_dir = Otc::West; - } - if (new_dir != m_direction) { - m_direction = new_dir; - m_redraw = true; - } - } - - if (m_creature->getOutfitNumber() != m_outfitNumber) { - m_outfitNumber = m_creature->getOutfitNumber(); - m_redraw = true; - } - - m_creature->drawOutfit(getPaddingRect(), m_direction, m_imageColor); - } -} - -void UICreature::setOutfit(const Outfit& outfit) -{ - if(!m_creature) - m_creature = CreaturePtr(new Creature); - m_direction = Otc::South; - m_creature->setOutfit(outfit); - m_redraw = true; -} - -void UICreature::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "fixed-creature-size") - setFixedCreatureSize(node->value()); - else if(node->tag() == "outfit-id") { - Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit()); - outfit.setId(node->value()); - setOutfit(outfit); - } - else if(node->tag() == "outfit-head") { - Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit()); - outfit.setHead(node->value()); - setOutfit(outfit); - } - else if(node->tag() == "outfit-body") { - Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit()); - outfit.setBody(node->value()); - setOutfit(outfit); - } - else if(node->tag() == "outfit-legs") { - Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit()); - outfit.setLegs(node->value()); - setOutfit(outfit); - } - else if(node->tag() == "outfit-feet") { - Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit()); - outfit.setFeet(node->value()); - setOutfit(outfit); - } - else if (node->tag() == "scale") { - setScale(node->value()); - } - else if (node->tag() == "optimized") { - setOptimized(node->value()); - } - } -} - -void UICreature::onGeometryChange(const Rect& oldRect, const Rect& newRect) -{ - UIWidget::onGeometryChange(oldRect, newRect); - m_redraw = true; -} \ No newline at end of file diff --git a/src/client/uicreature.h b/src/client/uicreature.h deleted file mode 100644 index 619d0e8..0000000 --- a/src/client/uicreature.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UICREATURE_H -#define UICREATURE_H - -#include "declarations.h" -#include -#include "creature.h" - -class UICreature : public UIWidget -{ -public: - void drawSelf(Fw::DrawPane drawPane); - - void setCreature(const CreaturePtr& creature) { m_creature = creature; m_redraw = true; } - void setFixedCreatureSize(bool fixed) { m_scale = fixed ? 1.0 : 0; m_redraw = true; } - void setOutfit(const Outfit& outfit); - - CreaturePtr getCreature() { return m_creature; } - bool isFixedCreatureSize() { return m_scale > 0; } - - void setAutoRotating(bool value) { m_autoRotating = value; } - void setDirection(Otc::Direction direction) { m_direction = direction; m_redraw = true; } - - void setScale(float scale) { m_scale = scale; m_redraw = true; } - float getScale() { return m_scale; } - - void setOptimized(bool value) { m_optimized = value; m_redraw = true; } - -protected: - void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - void onGeometryChange(const Rect& oldRect, const Rect& newRect) override; - - CreaturePtr m_creature; - stdext::boolean m_autoRotating; - stdext::boolean m_redraw; - int m_outfitNumber = 0; - Otc::Direction m_direction = Otc::South; - float m_scale = 1.0; - bool m_optimized = false; -}; - -#endif diff --git a/src/client/uiitem.cpp b/src/client/uiitem.cpp deleted file mode 100644 index da41830..0000000 --- a/src/client/uiitem.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiitem.h" -#include -#include -#include - -UIItem::UIItem() -{ - m_draggable = true; -} - -void UIItem::drawSelf(Fw::DrawPane drawPane) -{ - if(drawPane != Fw::ForegroundPane) - return; - // draw style components in order - if(m_backgroundColor.aF() > Fw::MIN_ALPHA) { - Rect backgroundDestRect = m_rect; - backgroundDestRect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left); - drawBackground(m_rect); - } - - drawImage(m_rect); - - if(m_itemVisible && m_item) { - Rect drawRect = getPaddingRect(); - - int exactSize = std::max(32, m_item->getExactSize()); - if(exactSize == 0) - return; - - m_item->setColor(m_color); - m_item->draw(drawRect); - - if(m_font && m_showCount && (m_item->isStackable() || m_item->isChargeable()) && m_item->getCountOrSubType() > 1) { - g_drawQueue->addText(m_font, std::to_string(m_item->getCountOrSubType()), Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight, Color(231, 231, 231)); - } - - if (m_showId) { - g_drawQueue->addText(m_font, std::to_string(m_item->getServerId()), m_rect, Fw::AlignBottomRight, Color(231, 231, 231)); - } - } - - drawBorder(m_rect); - drawIcon(m_rect); - drawText(m_rect); -} - -void UIItem::setItemId(int id) -{ - if (!m_item && id != 0) - m_item = Item::create(id); - else { - // remove item - if (id == 0) - m_item = nullptr; - else - m_item->setId(id); - } - - callLuaField("onItemChange"); -} - -void UIItem::setItemCount(int count) -{ - if (m_item) - m_item->setCount(count); - callLuaField("onItemChange"); -} -void UIItem::setItemSubType(int subType) -{ - if (m_item) - m_item->setSubType(subType); - callLuaField("onItemChange"); -} - -void UIItem::setItem(const ItemPtr& item) -{ - m_item = item; - callLuaField("onItemChange"); -} - -void UIItem::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "item-id") - setItemId(node->value()); - else if(node->tag() == "item-count") - setItemCount(node->value()); - else if(node->tag() == "item-visible") - setItemVisible(node->value()); - else if(node->tag() == "virtual") - setVirtual(node->value()); - else if(node->tag() == "show-id") - m_showId = node->value(); - } -} diff --git a/src/client/uiitem.h b/src/client/uiitem.h deleted file mode 100644 index 3b31a99..0000000 --- a/src/client/uiitem.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIITEM_H -#define UIITEM_H - -#include "declarations.h" -#include -#include "item.h" - -class UIItem : public UIWidget -{ -public: - UIItem(); - void drawSelf(Fw::DrawPane drawPane); - - void setItemId(int id); - void setItemCount(int count); - void setItemSubType(int subType); - void setItemVisible(bool visible) { m_itemVisible = visible; } - void setItem(const ItemPtr& item); - void setVirtual(bool virt) { m_virtual = virt; } - void clearItem() { setItemId(0); } - void setShowCount(bool value) { m_showCount = value; } - - int getItemId() { return m_item ? m_item->getId() : 0; } - int getItemCount() { return m_item ? m_item->getCount() : 0; } - int getItemSubType() { return m_item ? m_item->getSubType() : 0; } - int getItemCountOrSubType() { return m_item ? m_item->getCountOrSubType() : 0; } - ItemPtr getItem() { return m_item; } - bool isVirtual() { return m_virtual; } - bool isItemVisible() { return m_itemVisible; } - -protected: - void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - - ItemPtr m_item; - stdext::boolean m_virtual; - stdext::boolean m_itemVisible; - stdext::boolean m_showId; - stdext::boolean m_showCount; -}; - -#endif diff --git a/src/client/uimap.cpp b/src/client/uimap.cpp deleted file mode 100644 index eddd6a6..0000000 --- a/src/client/uimap.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uimap.h" -#include "game.h" -#include "map.h" -#include "mapview.h" -#include -#include -#include -#include "localplayer.h" - -UIMap::UIMap() -{ - m_draggable = true; - m_mapView = MapViewPtr(new MapView); - m_zoom = m_mapView->getVisibleDimension().height(); - m_keepAspectRatio = true; - m_limitVisibleRange = false; - m_aspectRatio = m_mapView->getVisibleDimension().ratio(); - m_maxZoomIn = 3; - m_maxZoomOut = 513; - m_mapRect.resize(1,1); - g_map.addMapView(m_mapView); -} - -UIMap::~UIMap() -{ - g_map.removeMapView(m_mapView); -} - -bool UIMap::onMouseMove(const Point& mousePos, const Point& mouseMoved) -{ - m_mousePosition = mousePos; - return UIWidget::onMouseMove(mousePos, mouseMoved); -} - -void UIMap::drawSelf(Fw::DrawPane drawPane) -{ - UIWidget::drawSelf(drawPane); - - if(drawPane == Fw::ForegroundPane) { - g_drawQueue->addBoundingRect(m_mapRect.expanded(1), 1, Color::black); - g_drawQueue->markMapPosition(); - } else if(drawPane == Fw::MapBackgroundPane) { - m_mapView->drawBackground(m_mapRect, getTile(m_mousePosition)); - } else if (drawPane == Fw::MapForegroundPane) { - m_mapView->drawForeground(m_mapRect); - } -} - -void UIMap::movePixels(int x, int y) -{ - m_mapView->move(x, y); -} - -bool UIMap::setZoom(int zoom) -{ - m_zoom = stdext::clamp(zoom, m_maxZoomIn, m_maxZoomOut); - updateVisibleDimension(); - return false; -} - -bool UIMap::zoomIn() -{ - int delta = 2; - if(m_zoom - delta < m_maxZoomIn) - delta--; - - if(m_zoom - delta < m_maxZoomIn) - return false; - - m_zoom -= delta; - updateVisibleDimension(); - return true; -} - -bool UIMap::zoomOut() -{ - int delta = 2; - if(m_zoom + delta > m_maxZoomOut) - delta--; - - if(m_zoom + delta > m_maxZoomOut) - return false; - - m_zoom += 2; - updateVisibleDimension(); - return true; -} - -void UIMap::setVisibleDimension(const Size& visibleDimension) -{ - m_mapView->setVisibleDimension(visibleDimension); - m_aspectRatio = visibleDimension.ratio(); - - if(m_keepAspectRatio) - updateMapSize(); -} - -void UIMap::setKeepAspectRatio(bool enable) -{ - m_keepAspectRatio = enable; - if(enable) - m_aspectRatio = getVisibleDimension().ratio(); - updateMapSize(); -} - -Position UIMap::getPosition(const Point& mousePos) -{ - if (!m_mapRect.contains(mousePos)) - return Position(); - - Point relativeMousePos = mousePos - m_mapRect.topLeft(); - return m_mapView->getPosition(relativeMousePos, m_mapRect.size()); -} - -Point UIMap::getPositionOffset(const Point& mousePos) -{ - if (!m_mapRect.contains(mousePos)) - return Point(0, 0); - - Point relativeMousePos = mousePos - m_mapRect.topLeft(); - return m_mapView->getPositionOffset(relativeMousePos, m_mapRect.size()); -} - -TilePtr UIMap::getTile(const Point& mousePos) -{ - Position tilePos = getPosition(mousePos); - if(!tilePos.isValid()) - return nullptr; - - // we must check every floor, from top to bottom to check for a clickable tile - TilePtr tile; - tilePos.coveredUp(tilePos.z - m_mapView->getCachedFirstVisibleFloor()); - for(int i = m_mapView->getCachedFirstVisibleFloor(); i <= m_mapView->getCachedLastVisibleFloor(); i++) { - tile = g_map.getTile(tilePos); - if(tile && tile->isClickable()) - break; - tilePos.coveredDown(); - } - - if(!tile || !tile->isClickable()) - return nullptr; - - return tile; -} - -void UIMap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "multifloor") - setMultifloor(node->value()); - else if(node->tag() == "draw-texts") - setDrawTexts(node->value()); - else if(node->tag() == "draw-lights") - setDrawLights(node->value()); - else if(node->tag() == "animated") - setAnimated(node->value()); - } -} - -void UIMap::onGeometryChange(const Rect& oldRect, const Rect& newRect) -{ - UIWidget::onGeometryChange(oldRect, newRect); - updateMapSize(); -} - -void UIMap::updateVisibleDimension() -{ - int dimensionHeight = m_zoom; - - float ratio = m_aspectRatio; - if(!m_limitVisibleRange && !m_mapRect.isEmpty() && !m_keepAspectRatio) - ratio = m_mapRect.size().ratio(); - - if(dimensionHeight % 2 == 0) - dimensionHeight += 1; - int dimensionWidth = m_zoom * ratio; - if(dimensionWidth % 2 == 0) - dimensionWidth += 1; - - m_mapView->setVisibleDimension(Size(dimensionWidth, dimensionHeight)); - - if(m_keepAspectRatio) - updateMapSize(); - - callLuaField("onVisibleDimensionChange", dimensionWidth, dimensionHeight); -} - -void UIMap::updateMapSize() -{ - Rect clippingRect = getPaddingRect(); - Size mapSize; - if(m_keepAspectRatio) { - Rect mapRect = clippingRect.expanded(-1); - mapSize = Size(m_aspectRatio*m_zoom, m_zoom); - mapSize.scale(mapRect.size(), Fw::KeepAspectRatio); - } else { - mapSize = clippingRect.expanded(-1).size(); - } - - m_mapRect.resize(mapSize); - m_mapRect.moveCenter(clippingRect.center()); - m_mapView->optimizeForSize(mapSize); - - if(!m_keepAspectRatio) - updateVisibleDimension(); -} - -/* vim: set ts=4 sw=4 et: */ diff --git a/src/client/uimap.h b/src/client/uimap.h deleted file mode 100644 index 8993243..0000000 --- a/src/client/uimap.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIMAP_H -#define UIMAP_H - -#include "declarations.h" -#include -#include "tile.h" - -#include "mapview.h" - -class UIMap : public UIWidget -{ -public: - UIMap(); - ~UIMap(); - - bool onMouseMove(const Point& mousePos, const Point& mouseMoved); - - void drawSelf(Fw::DrawPane drawPane); - - void movePixels(int x, int y); - bool setZoom(int zoom); - bool zoomIn(); - bool zoomOut(); - void followCreature(const CreaturePtr& creature) { m_mapView->followCreature(creature); } - - void setCameraPosition(const Position& pos) { m_mapView->setCameraPosition(pos); } - void setMaxZoomIn(int maxZoomIn) { m_maxZoomIn = maxZoomIn; } - void setMaxZoomOut(int maxZoomOut) { m_maxZoomOut = maxZoomOut; } - void setMultifloor(bool enable) { m_mapView->setMultifloor(enable); } - void lockVisibleFloor(int floor) { m_mapView->lockFirstVisibleFloor(floor); } - void unlockVisibleFloor() { m_mapView->unlockFirstVisibleFloor(); } - void setVisibleDimension(const Size& visibleDimension); - void setDrawFlags(Otc::DrawFlags drawFlags) { m_mapView->setDrawFlags(drawFlags); } - void setDrawTexts(bool enable) { m_mapView->setDrawTexts(enable); } - void setDrawNames(bool enable) { m_mapView->setDrawNames(enable); } - void setDrawHealthBars(bool enable) { m_mapView->setDrawHealthBars(enable); } - void setDrawHealthBarsOnTop(bool enable) { m_mapView->setDrawHealthBarsOnTop(enable); } - void setDrawLights(bool enable) { m_mapView->setDrawLights(enable); } - void setDrawManaBar(bool enable) { m_mapView->setDrawManaBar(enable); } - void setDrawPlayerBars(bool enable) { m_mapView->setDrawPlayerBars(enable); } - void setAnimated(bool enable) { m_mapView->setAnimated(enable); } - void setKeepAspectRatio(bool enable); - void setMinimumAmbientLight(float intensity) { m_mapView->setMinimumAmbientLight(intensity); } - void setLimitVisibleRange(bool limitVisibleRange) { m_limitVisibleRange = limitVisibleRange; updateVisibleDimension(); } - void setFloorFading(int value) { m_mapView->setFloorFading(value); } - void setCrosshair(const std::string& type) { m_mapView->setCrosshair(type); } - bool isMultifloor() { return m_mapView->isMultifloor(); } - bool isDrawingTexts() { return m_mapView->isDrawingTexts(); } - bool isDrawingNames() { return m_mapView->isDrawingNames(); } - bool isDrawingHealthBars() { return m_mapView->isDrawingHealthBars(); } - bool isDrawingHealthBarsOnTop() { return m_mapView->isDrawingHealthBarsOnTop(); } - bool isDrawingLights() { return m_mapView->isDrawingLights(); } - bool isDrawingManaBar() { return m_mapView->isDrawingManaBar(); } - bool isAnimating() { return m_mapView->isAnimating(); } - bool isKeepAspectRatioEnabled() { return m_keepAspectRatio; } - bool isLimitVisibleRangeEnabled() { return m_limitVisibleRange; } - - Size getVisibleDimension() { return m_mapView->getVisibleDimension(); } - CreaturePtr getFollowingCreature() { return m_mapView->getFollowingCreature(); } - Otc::DrawFlags getDrawFlags() { return m_mapView->getDrawFlags(); } - Position getCameraPosition() { return m_mapView->getCameraPosition(); } - Position getPosition(const Point& mousePos); - Point getPositionOffset(const Point& mousePos); - TilePtr getTile(const Point& mousePos); - int getMaxZoomIn() { return m_maxZoomIn; } - int getMaxZoomOut() { return m_maxZoomOut; } - int getZoom() { return m_zoom; } - float getMinimumAmbientLight() { return m_mapView->getMinimumAmbientLight(); } - -protected: - virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect); - -private: - void updateVisibleDimension(); - void updateMapSize(); - - int m_zoom; - MapViewPtr m_mapView; - Rect m_mapRect; - Point m_mousePosition; - float m_aspectRatio; - bool m_keepAspectRatio; - bool m_limitVisibleRange; - int m_maxZoomIn; - int m_maxZoomOut; -}; - -#endif diff --git a/src/client/uimapanchorlayout.cpp b/src/client/uimapanchorlayout.cpp deleted file mode 100644 index 25f991e..0000000 --- a/src/client/uimapanchorlayout.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "declarations.h" -#include "uimapanchorlayout.h" -#include "uiminimap.h" -#include - -int UIPositionAnchor::getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget) -{ - UIMinimapPtr minimap = hookedWidget->static_self_cast(); - Rect hookedRect = minimap->getTileRect(m_hookedPosition); - int point = 0; - if(hookedRect.isValid()) { - switch(m_hookedEdge) { - case Fw::AnchorLeft: - point = hookedRect.left(); - break; - case Fw::AnchorRight: - point = hookedRect.right(); - break; - case Fw::AnchorTop: - point = hookedRect.top(); - break; - case Fw::AnchorBottom: - point = hookedRect.bottom(); - break; - case Fw::AnchorHorizontalCenter: - point = hookedRect.horizontalCenter(); - break; - case Fw::AnchorVerticalCenter: - point = hookedRect.verticalCenter(); - break; - default: - // must never happens - VALIDATE(false); - break; - } - } - return point; -} - -void UIMapAnchorLayout::addPositionAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge) -{ - if(!anchoredWidget) - return; - - VALIDATE(anchoredWidget != getParentWidget()); - - UIPositionAnchorPtr anchor(new UIPositionAnchor(anchoredEdge, hookedPosition, hookedEdge)); - UIAnchorGroupPtr& anchorGroup = m_anchorsGroups[anchoredWidget]; - if(!anchorGroup) - anchorGroup = UIAnchorGroupPtr(new UIAnchorGroup); - - anchorGroup->addAnchor(anchor); - - // layout must be updated because a new anchor got in - update(); -} - -void UIMapAnchorLayout::centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition) -{ - addPositionAnchor(anchoredWidget, Fw::AnchorHorizontalCenter, hookedPosition, Fw::AnchorHorizontalCenter); - addPositionAnchor(anchoredWidget, Fw::AnchorVerticalCenter, hookedPosition, Fw::AnchorVerticalCenter); -} - -void UIMapAnchorLayout::fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition) -{ - addPositionAnchor(anchoredWidget, Fw::AnchorLeft, hookedPosition, Fw::AnchorLeft); - addPositionAnchor(anchoredWidget, Fw::AnchorRight, hookedPosition, Fw::AnchorRight); - addPositionAnchor(anchoredWidget, Fw::AnchorTop, hookedPosition, Fw::AnchorTop); - addPositionAnchor(anchoredWidget, Fw::AnchorBottom, hookedPosition, Fw::AnchorBottom); -} diff --git a/src/client/uimapanchorlayout.h b/src/client/uimapanchorlayout.h deleted file mode 100644 index 177ce75..0000000 --- a/src/client/uimapanchorlayout.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIMAPANCHORLAYOUT_H -#define UIMAPANCHORLAYOUT_H - -#include "declarations.h" -#include - -class UIPositionAnchor : public UIAnchor -{ -public: - UIPositionAnchor(Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge) : - UIAnchor(anchoredEdge, std::string(), hookedEdge), m_hookedPosition(hookedPosition) { } - - UIWidgetPtr getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget) { return parentWidget; } - int getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget); - -private: - Position m_hookedPosition; -}; - -class UIMapAnchorLayout : public UIAnchorLayout -{ -public: - UIMapAnchorLayout(UIWidgetPtr parentWidget) : UIAnchorLayout(parentWidget) { } - - void addPositionAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, - const Position& hookedPosition, Fw::AnchorEdge hookedEdge); - void centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition); - void fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition); - -protected: -}; - -#endif diff --git a/src/client/uiminimap.cpp b/src/client/uiminimap.cpp deleted file mode 100644 index d63c967..0000000 --- a/src/client/uiminimap.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiminimap.h" -#include "minimap.h" -#include "game.h" -#include "uimapanchorlayout.h" -#include "luavaluecasts_client.h" - -#include -#include "uimapanchorlayout.h" - -UIMinimap::UIMinimap() -{ - m_zoom = 0; - m_scale = 1.0f; - m_minZoom = -5; - m_maxZoom = 5; - m_layout = UIMapAnchorLayoutPtr(new UIMapAnchorLayout(static_self_cast())); -} - -void UIMinimap::drawSelf(Fw::DrawPane drawPane) -{ - UIWidget::drawSelf(drawPane); - - if(drawPane != Fw::ForegroundPane) - return; - - g_minimap.draw(getPaddingRect(), getCameraPosition(), m_scale, m_color); -} - -bool UIMinimap::setZoom(int zoom) -{ - if(zoom == m_zoom) - return true; - - if(zoom < m_minZoom || zoom > m_maxZoom) - return false; - - int oldZoom = m_zoom; - m_zoom = zoom; - if(m_zoom < 0) - m_scale = 1.0f / (1 << std::abs(zoom)); - else if(m_zoom > 0) - m_scale = 1.0f * (1 << std::abs(zoom)); - else - m_scale = 1; - m_layout->update(); - - onZoomChange(zoom, oldZoom); - return true; -} - -void UIMinimap::setCameraPosition(const Position& pos) -{ - Position oldPos = m_cameraPosition; - m_cameraPosition = pos; - m_layout->update(); - - onCameraPositionChange(pos, oldPos); -} - -bool UIMinimap::floorUp() -{ - Position pos = getCameraPosition(); - if(!pos.up()) - return false; - setCameraPosition(pos); - return true; -} - -bool UIMinimap::floorDown() -{ - Position pos = getCameraPosition(); - if(!pos.down()) - return false; - setCameraPosition(pos); - return true; -} - -Point UIMinimap::getTilePoint(const Position& pos) -{ - return g_minimap.getTilePoint(pos, getPaddingRect(), getCameraPosition(), m_scale); -} - -Rect UIMinimap::getTileRect(const Position& pos) -{ - return g_minimap.getTileRect(pos, getPaddingRect(), getCameraPosition(), m_scale); -} - -Position UIMinimap::getTilePosition(const Point& mousePos) -{ - return g_minimap.getTilePosition(mousePos, getPaddingRect(), getCameraPosition(), m_scale); -} - -void UIMinimap::anchorPosition(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge) -{ - UIMapAnchorLayoutPtr layout = m_layout->static_self_cast(); - VALIDATE(layout); - layout->addPositionAnchor(anchoredWidget, anchoredEdge, hookedPosition, hookedEdge); -} - -void UIMinimap::fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition) -{ - UIMapAnchorLayoutPtr layout = m_layout->static_self_cast(); - VALIDATE(layout); - layout->fillPosition(anchoredWidget, hookedPosition); -} - -void UIMinimap::centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition) -{ - UIMapAnchorLayoutPtr layout = m_layout->static_self_cast(); - VALIDATE(layout); - layout->centerInPosition(anchoredWidget, hookedPosition); -} - -void UIMinimap::onZoomChange(int zoom, int oldZoom) -{ - callLuaField("onZoomChange", zoom, oldZoom); -} - -void UIMinimap::onCameraPositionChange(const Position& position, const Position& oldPosition) -{ - callLuaField("onCameraPositionChange", position, oldPosition); -} - -void UIMinimap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "zoom") - setZoom(node->value()); - else if(node->tag() == "max-zoom") - setMaxZoom(node->value()); - else if(node->tag() == "min-zoom") - setMinZoom(node->value()); - } -} diff --git a/src/client/uiminimap.h b/src/client/uiminimap.h deleted file mode 100644 index dfb1f8f..0000000 --- a/src/client/uiminimap.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIMINIMAP_H -#define UIMINIMAP_H - -#include "declarations.h" -#include - -class UIMinimap : public UIWidget -{ -public: - UIMinimap(); - - void drawSelf(Fw::DrawPane drawPane); - - bool zoomIn() { return setZoom(m_zoom+1); } - bool zoomOut() { return setZoom(m_zoom-1); } - - bool setZoom(int zoom); - void setMinZoom(int minZoom) { m_minZoom = minZoom; } - void setMaxZoom(int maxZoom) { m_maxZoom = maxZoom; } - void setCameraPosition(const Position& pos); - bool floorUp(); - bool floorDown(); - - Point getTilePoint(const Position& pos); - Rect getTileRect(const Position& pos); - Position getTilePosition(const Point& mousePos); - - Position getCameraPosition() { return m_cameraPosition; } - int getMinZoom() { return m_minZoom; } - int getMaxZoom() { return m_maxZoom; } - int getZoom() { return m_zoom; } - float getScale() { return m_scale; } - - void anchorPosition(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge); - void fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition); - void centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition); - -protected: - virtual void onZoomChange(int zoom, int oldZoom); - virtual void onCameraPositionChange(const Position& position, const Position& oldPosition); - virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - -private: - void update(); - - Rect m_mapArea; - Position m_cameraPosition; - float m_scale; - int m_zoom; - int m_minZoom; - int m_maxZoom; -}; - -#endif diff --git a/src/client/uiprogressrect.cpp b/src/client/uiprogressrect.cpp deleted file mode 100644 index 855ac3b..0000000 --- a/src/client/uiprogressrect.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiprogressrect.h" -#include -#include -#include - -UIProgressRect::UIProgressRect() -{ - m_percent = 0; -} - -void UIProgressRect::drawSelf(Fw::DrawPane drawPane) -{ - if(drawPane != Fw::ForegroundPane) - return; - - // todo: check +1 to right/bottom - // todo: add smooth - Rect drawRect = getPaddingRect(); - - // 0% - 12.5% (12.5) - // triangle from top center, to top right (var x) - if(m_percent < 12.5) { - Point var = Point(std::max(m_percent - 0.0, 0.0) * (drawRect.right() - drawRect.horizontalCenter()) / 12.5, 0); - g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.topRight() + Point(1,0), drawRect.topCenter() + var, m_backgroundColor); - } - - // 12.5% - 37.5% (25) - // triangle from top right to bottom right (var y) - if(m_percent < 37.5) { - Point var = Point(0, std::max(m_percent - 12.5, 0.0) * (drawRect.bottom() - drawRect.top()) / 25.0); - g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.bottomRight() + Point(1,1), drawRect.topRight() + var + Point(1,0), m_backgroundColor); - } - - // 37.5% - 62.5% (25) - // triangle from bottom right to bottom left (var x) - if(m_percent < 62.5) { - Point var = Point(std::max(m_percent - 37.5, 0.0) * (drawRect.right() - drawRect.left()) / 25.0, 0); - g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.bottomLeft() + Point(0,1), drawRect.bottomRight() - var + Point(1,1), m_backgroundColor); - } - - // 62.5% - 87.5% (25) - // triangle from bottom left to top left - if(m_percent < 87.5) { - Point var = Point(0, std::max(m_percent - 62.5, 0.0) * (drawRect.bottom() - drawRect.top()) / 25.0); - g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.topLeft(), drawRect.bottomLeft() - var + Point(0,1), m_backgroundColor); - } - - // 87.5% - 100% (12.5) - // triangle from top left to top center - if(m_percent < 100) { - Point var = Point(std::max(m_percent - 87.5, 0.0) * (drawRect.horizontalCenter() - drawRect.left()) / 12.5, 0); - g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.topCenter(), drawRect.topLeft() + var, m_backgroundColor); - } - - drawImage(m_rect); - drawBorder(m_rect); - drawIcon(m_rect); - drawText(m_rect); -} - -void UIProgressRect::setPercent(float percent) -{ - m_percent = stdext::clamp((double)percent, 0.0, 100.0); -} - -void UIProgressRect::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "percent") - setPercent(node->value()); - } -} diff --git a/src/client/uiprogressrect.h b/src/client/uiprogressrect.h deleted file mode 100644 index 2382266..0000000 --- a/src/client/uiprogressrect.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIPROGRESSRECT_H -#define UIPROGRESSRECT_H - -#include "declarations.h" -#include -#include "item.h" - -class UIProgressRect : public UIWidget -{ -public: - UIProgressRect(); - void drawSelf(Fw::DrawPane drawPane); - - void setPercent(float percent); - float getPercent() { return m_percent; } - -protected: - void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - - float m_percent; -}; - -#endif diff --git a/src/client/uisprite.cpp b/src/client/uisprite.cpp deleted file mode 100644 index 896b91f..0000000 --- a/src/client/uisprite.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uisprite.h" -#include -#include -#include -#include - -UISprite::UISprite() : - m_spriteId(0), - m_spriteColor(Color::white) -{ } - -void UISprite::drawSelf(Fw::DrawPane drawPane) -{ - if(drawPane != Fw::ForegroundPane) - return; - - // draw style components in order - if(m_backgroundColor.aF() > Fw::MIN_ALPHA) { - Rect backgroundDestRect = m_rect; - backgroundDestRect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left); - drawBackground(m_rect); - } - - drawImage(m_rect); - - if(m_spriteVisible && m_sprite) { - g_drawQueue->addTexturedRect(getPaddingRect(), m_sprite, Rect(Point(0, 0), m_sprite->getSize()), m_spriteColor); - } - - drawBorder(m_rect); - drawIcon(m_rect); - drawText(m_rect); -} - -void UISprite::setSpriteId(int id) -{ - if(!g_sprites.isLoaded()) - return; - - m_spriteId = id; - if(id == 0) - m_sprite = nullptr; - else { - ImagePtr image = g_sprites.getSpriteImage(id); - if(image) - m_sprite = new Texture(image); - else - m_sprite = nullptr; - } -} - -void UISprite::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "sprite-id") - setSpriteId(node->value()); - else if(node->tag() == "sprite-visible") - setSpriteVisible(node->value()); - else if(node->tag() == "sprite-color") - setSpriteColor(node->value()); - } -} diff --git a/src/client/uisprite.h b/src/client/uisprite.h deleted file mode 100644 index 9585734..0000000 --- a/src/client/uisprite.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UISPRITE_H -#define UISPRITE_H - -#include "declarations.h" -#include - -class UISprite : public UIWidget -{ -public: - UISprite(); - void drawSelf(Fw::DrawPane drawPane); - - void setSpriteId(int id); - int getSpriteId() { return m_spriteId; } - void clearSprite() { setSpriteId(0); } - - void setSpriteColor(Color color) { m_spriteColor = color; } - - bool isSpriteVisible() { return m_spriteVisible; } - void setSpriteVisible(bool visible) { m_spriteVisible = visible; } - - bool hasSprite() { return m_sprite != nullptr; } - -protected: - void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - - TexturePtr m_sprite; - uint16 m_spriteId; - Color m_spriteColor; - - stdext::boolean m_spriteVisible; -}; - -#endif diff --git a/src/framework/const.h b/src/framework/const.h deleted file mode 100644 index 25be990..0000000 --- a/src/framework/const.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FRAMEWORK_CONST_H -#define FRAMEWORK_CONST_H - -#include "stdext/compiler.h" - -#define DEG_TO_RAD (acos(-1)/180.0) -#define RAD_TO_DEC (180.0/acos(-1)) - -#ifndef BUILD_COMMIT -#define BUILD_COMMIT "devel" -#endif - -#ifndef BUILD_REVISION -#define BUILD_REVISION "0" -#endif - -#ifndef BUILD_TYPE -#define BUILD_TYPE "unknown" -#endif - -#ifndef BUILD_ARCH -#if defined(__amd64) || defined(_M_X64) -#define BUILD_ARCH "x64" -#elif defined(__i386) || defined(_M_IX86) || defined(_X86_) -#define BUILD_ARCH "x86" -#else -#define BUILD_ARCH "unknown" -#endif -#endif - -namespace Fw -{ - static const float pi = 3.14159265; - static const float MIN_ALPHA = 0.003f; - enum Key : unsigned char { - KeyUnknown = 0, - KeyEscape = 1, - KeyTab = 2, - KeyBackspace = 3, - //KeyReturn = 4, - KeyEnter = 5, - KeyInsert = 6, - KeyDelete = 7, - KeyPause = 8, - KeyPrintScreen = 9, - KeyHome = 10, - KeyEnd = 11, - KeyPageUp = 12, - KeyPageDown = 13, - KeyUp = 14, - KeyDown = 15, - KeyLeft = 16, - KeyRight = 17, - KeyNumLock = 18, - KeyScrollLock = 19, - KeyCapsLock = 20, - KeyCtrl = 21, - KeyShift = 22, - KeyAlt = 23, - //KeyAltGr = 24, - KeyMeta = 25, - KeyMenu = 26, - KeySpace = 32, // ' ' - KeyExclamation = 33, // ! - KeyQuote = 34, // " - KeyNumberSign = 35, // # - KeyDollar = 36, // $ - KeyPercent = 37, // % - KeyAmpersand = 38, // & - KeyApostrophe = 39, // ' - KeyLeftParen = 40, // ( - KeyRightParen = 41, // ) - KeyAsterisk = 42, // * - KeyPlus = 43, // + - KeyComma = 44, // , - KeyMinus = 45, // - - KeyPeriod = 46, // . - KeySlash = 47, // / - Key0 = 48, // 0 - Key1 = 49, // 1 - Key2 = 50, // 2 - Key3 = 51, // 3 - Key4 = 52, // 4 - Key5 = 53, // 5 - Key6 = 54, // 6 - Key7 = 55, // 7 - Key8 = 56, // 8 - Key9 = 57, // 9 - KeyColon = 58, // : - KeySemicolon = 59, // ; - KeyLess = 60, // < - KeyEqual = 61, // = - KeyGreater = 62, // > - KeyQuestion = 63, // ? - KeyAtSign = 64, // @ - KeyA = 65, // a - KeyB = 66, // b - KeyC = 67, // c - KeyD = 68, // d - KeyE = 69, // e - KeyF = 70, // f - KeyG = 71, // g - KeyH = 72, // h - KeyI = 73, // i - KeyJ = 74, // j - KeyK = 75, // k - KeyL = 76, // l - KeyM = 77, // m - KeyN = 78, // n - KeyO = 79, // o - KeyP = 80, // p - KeyQ = 81, // q - KeyR = 82, // r - KeyS = 83, // s - KeyT = 84, // t - KeyU = 85, // u - KeyV = 86, // v - KeyW = 87, // w - KeyX = 88, // x - KeyY = 89, // y - KeyZ = 90, // z - KeyLeftBracket = 91, // [ - KeyBackslash = 92, // '\' - KeyRightBracket = 93, // ] - KeyCaret = 94, // ^ - KeyUnderscore = 95, // _ - KeyGrave = 96, // ` - KeyLeftCurly = 123, // { - KeyBar = 124, // | - KeyRightCurly = 125, // } - KeyTilde = 126, // ~ - KeyF1 = 128, - KeyF2 = 129, - KeyF3 = 130, - KeyF4 = 131, - KeyF5 = 132, - KeyF6 = 134, - KeyF7 = 135, - KeyF8 = 136, - KeyF9 = 137, - KeyF10 = 138, - KeyF11 = 139, - KeyF12 = 140, - KeyNumpad0 = 141, - KeyNumpad1 = 142, - KeyNumpad2 = 143, - KeyNumpad3 = 144, - KeyNumpad4 = 145, - KeyNumpad5 = 146, - KeyNumpad6 = 147, - KeyNumpad7 = 148, - KeyNumpad8 = 149, - KeyNumpad9 = 150 - }; - - enum LogLevel { - LogDebug = 0, - LogInfo, - LogWarning, - LogError, - LogFatal - }; - - enum AspectRatioMode { - IgnoreAspectRatio, - KeepAspectRatio, - KeepAspectRatioByExpanding - }; - - enum AlignmentFlag { - AlignNone = 0, - AlignLeft = 1, - AlignRight = 2, - AlignTop = 4, - AlignBottom = 8, - AlignHorizontalCenter = 16, - AlignVerticalCenter = 32, - AlignTopLeft = AlignTop | AlignLeft, // 5 - AlignTopRight = AlignTop | AlignRight, // 6 - AlignBottomLeft = AlignBottom | AlignLeft, // 9 - AlignBottomRight = AlignBottom | AlignRight, // 10 - AlignLeftCenter = AlignLeft | AlignVerticalCenter, // 33 - AlignRightCenter = AlignRight | AlignVerticalCenter, // 34 - AlignTopCenter = AlignTop | AlignHorizontalCenter, // 20 - AlignBottomCenter = AlignBottom | AlignHorizontalCenter, // 24 - AlignCenter = AlignVerticalCenter | AlignHorizontalCenter // 48 - }; - - enum AnchorEdge { - AnchorNone = 0, - AnchorTop, - AnchorBottom, - AnchorLeft, - AnchorRight, - AnchorVerticalCenter, - AnchorHorizontalCenter - }; - - enum FocusReason { - MouseFocusReason = 0, - KeyboardFocusReason, - ActiveFocusReason, - OtherFocusReason - }; - - enum AutoFocusPolicy { - AutoFocusNone = 0, - AutoFocusFirst, - AutoFocusLast - }; - - enum InputEventType { - NoInputEvent = 0, - KeyTextInputEvent, - KeyDownInputEvent, - KeyPressInputEvent, - KeyUpInputEvent, - MousePressInputEvent, - MouseReleaseInputEvent, - MouseMoveInputEvent, - MouseWheelInputEvent - }; - - enum MouseButton { - MouseNoButton = 0, - MouseLeftButton, - MouseRightButton, - MouseMidButton, - MouseTouch - }; - - enum MouseWheelDirection { - MouseNoWheel = 0, - MouseWheelUp, - MouseWheelDown - }; - - enum KeyboardModifier { - KeyboardNoModifier = 0, - KeyboardCtrlModifier = 1, - KeyboardAltModifier = 2, - KeyboardShiftModifier = 4 - }; - - enum WidgetState { - InvalidState = -1, - DefaultState = 0, - ActiveState = 1, - FocusState = 2, - HoverState = 4, - PressedState = 8, - DisabledState = 16, - CheckedState = 32, - OnState = 64, - FirstState = 128, - MiddleState = 256, - LastState = 512, - AlternateState = 1024, - DraggingState = 2048, - HiddenState = 4096, - MobileState = 8192, - LastWidgetState = 16384 - }; - - enum DrawPane { - ForegroundPane = 1, - MapBackgroundPane = 2, - MapForegroundPane = 3, - }; - -#ifdef FW_SQL - enum DatabaseEngine { - DatabaseNone = 0, - DatabaseMySQL - }; -#endif -} - -#endif diff --git a/src/framework/core/adaptiverenderer.cpp b/src/framework/core/adaptiverenderer.cpp deleted file mode 100644 index 99639e4..0000000 --- a/src/framework/core/adaptiverenderer.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include -#include - -#include "adaptiverenderer.h" - -AdaptiveRenderer g_adaptiveRenderer; - -void AdaptiveRenderer::newFrame() { - auto now = stdext::millis(); - m_frames.push_back(now); - while (m_frames.front() + 5000 < now) { - m_frames.pop_front(); - } - - if (m_forcedSpeed >= 0 && m_forcedSpeed <= 4) { - m_speed = m_forcedSpeed; - return; - } - - if (m_update + 5000 > now) - return; - - m_update = stdext::millis(); - - if (m_speed < 1) - m_speed = 1; - - int maxFps = std::min(100, std::max(10, g_app.getMaxFps() < 10 ? 100 : g_app.getMaxFps())); - if (m_speed >= 2 && maxFps > 60) { // fix for forced vsync - maxFps = 60; - } - - if (m_frames.size() < maxFps * (4.0f - m_speed * 0.3f) && m_speed != RenderSpeeds - 1) { - m_speed += 1; - } - if (m_frames.size() > maxFps * (4.5f - m_speed * 0.1f) && m_speed > 1) { - m_speed -= 1; - } -} - -void AdaptiveRenderer::refresh() { - m_update = stdext::millis(); -} - -int AdaptiveRenderer::effetsLimit() { - static int limits[RenderSpeeds] = { 20, 10, 7, 4, 2 }; - return limits[m_speed]; -} - -int AdaptiveRenderer::creaturesLimit() { - static int limits[RenderSpeeds] = { 20, 10, 7, 5, 3 }; - return limits[m_speed]; -} - -int AdaptiveRenderer::itemsLimit() { - static int limits[RenderSpeeds] = { 20, 10, 7, 5, 3 }; - return limits[m_speed]; -} - -int AdaptiveRenderer::mapRenderInterval() { - static int limits[RenderSpeeds] = { 0, 10, 20, 50, 100 }; - return limits[m_speed]; -} - -int AdaptiveRenderer::textsLimit() { - static int limits[RenderSpeeds] = { 1000, 50, 30, 15, 5 }; - return limits[m_speed]; -} - -int AdaptiveRenderer::creaturesRenderInterval() { - // not working yet - static int limits[RenderSpeeds] = { 0, 0, 10, 15, 20 }; - return limits[m_speed]; -} - -bool AdaptiveRenderer::allowFading() { - return m_speed <= 2; -} - -int AdaptiveRenderer::foregroundUpdateInterval() { - static int limits[RenderSpeeds] = { 0, 20, 40, 50, 60 }; - return limits[m_speed]; -} - -std::string AdaptiveRenderer::getDebugInfo() { - std::stringstream ss; - ss << "Frames: " << m_frames.size() << "|" << m_speed << "|" << m_forcedSpeed; - return ss.str(); -} \ No newline at end of file diff --git a/src/framework/core/adaptiverenderer.h b/src/framework/core/adaptiverenderer.h deleted file mode 100644 index 0853834..0000000 --- a/src/framework/core/adaptiverenderer.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef ADAPTIVERENDERER_H -#define ADAPTIVERENDERER_H - -#include - -constexpr int RenderSpeeds = 5; - -class AdaptiveRenderer { -public: - void newFrame(); - - void refresh(); - - int effetsLimit(); - - int creaturesLimit(); - - int itemsLimit(); - - int textsLimit(); - - int mapRenderInterval(); - - int creaturesRenderInterval(); - - - bool allowFading(); - - int getLevel() { - return m_speed; - } - - int foregroundUpdateInterval(); - - std::string getDebugInfo(); - - void setForcedLevel(int value) { - m_forcedSpeed = value; - } - -private: - int m_forcedSpeed = -1; - int m_speed = 0; - time_t m_update = 0; - std::list m_frames; -}; - -extern AdaptiveRenderer g_adaptiveRenderer; - -#endif \ No newline at end of file diff --git a/src/framework/core/application.cpp b/src/framework/core/application.cpp deleted file mode 100644 index 5e2417c..0000000 --- a/src/framework/core/application.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "application.h" -#include -#include -#include -#include -#include -#include -#include "asyncdispatcher.h" -#include -#include -#include -#include -#include - -#include - -#ifdef FW_NET -#include -#ifdef FW_PROXY -#include -#endif -#endif - -void exitSignalHandler(int sig) -{ - static bool signaled = false; - switch(sig) { - case SIGTERM: - case SIGINT: - if(!signaled && !g_app.isStopping() && !g_app.isTerminated()) { - signaled = true; - g_dispatcher.addEvent(std::bind(&Application::close, &g_app)); - } - break; - } -} - -Application::Application() -{ - m_appName = "application"; - m_appCompactName = "app"; - m_appVersion = "none"; - m_charset = "cp1252"; - m_stopping = false; -#ifdef ANDROID - m_mobile = true; -#endif -} - -void Application::init(std::vector& args) -{ - // capture exit signals - signal(SIGTERM, exitSignalHandler); - signal(SIGINT, exitSignalHandler); - - // setup locale - std::locale::global(std::locale()); - - // process args encoding - g_platform.processArgs(args); - - g_asyncDispatcher.init(); - - std::string startupOptions; - for(uint i=1;i 0) - g_logger.info(stdext::format("Startup options: %s", startupOptions)); - - m_startupOptions = startupOptions; - - // mobile testing - if (startupOptions.find("-mobile") != std::string::npos) - m_mobile = true; - - // initialize configs - g_configs.init(); - - // initialize lua - g_lua.init(); - registerLuaFunctions(); - -#ifdef FW_PROXY - // initalize proxy - g_proxy.init(); -#endif -} - -void Application::deinit() -{ - g_lua.callGlobalField("g_app", "onTerminate"); - - // run modules unload events - g_modules.unloadModules(); - g_modules.clear(); - - // release remaining lua object references - g_lua.collectGarbage(); - - // poll remaining events - poll(); - - // disable dispatcher events - g_dispatcher.shutdown(); -} - -void Application::terminate() -{ -#ifdef FW_NET - // terminate network - Connection::terminate(); -#endif - - // release configs - g_configs.terminate(); - - // release resources - g_resources.terminate(); - - // terminate script environment - g_lua.terminate(); - -#ifdef FW_PROXY - // terminate proxy - g_proxy.terminate(); -#endif - - m_terminated = true; - - signal(SIGTERM, SIG_DFL); - signal(SIGINT, SIG_DFL); -} - -void Application::poll() -{ -#ifdef FW_NET - Connection::poll(); -#endif - - g_dispatcher.poll(); - - // poll connection again to flush pending write -#ifdef FW_NET - Connection::poll(); -#endif -} - -void Application::exit() -{ - g_lua.callGlobalField("g_app", "onExit"); - m_stopping = true; -} - -void Application::quick_exit() -{ -#ifdef _MSC_VER - ::quick_exit(0); -#else - ::exit(0); -#endif -} - -void Application::close() -{ - if(!g_lua.callGlobalField("g_app", "onClose")) - exit(); -} - -void Application::restart() -{ -#ifndef ANDROID - boost::process::child c(g_resources.getBinaryName()); - std::error_code ec2; - if (c.wait_for(std::chrono::seconds(1), ec2)) { - g_logger.fatal("Updater restart error. Please restart application"); - } - c.detach(); - quick_exit(); -#else - exit(); -#endif -} - -std::string Application::getOs() -{ -#if defined(ANDROID) - return "android"; -#elif defined(WIN32) - return "windows"; -#elif defined(__APPLE__) - return "mac"; -#elif __linux - return "linux"; -#else - return "unknown"; -#endif -} - diff --git a/src/framework/core/application.h b/src/framework/core/application.h deleted file mode 100644 index 2b99151..0000000 --- a/src/framework/core/application.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef APPLICATION_H -#define APPLICATION_H - -#include - -//@bindsingleton g_app -class Application -{ -public: - Application(); - virtual ~Application() {} - - virtual void init(std::vector& args); - virtual void deinit(); - virtual void terminate(); - virtual void run() = 0; - virtual void poll(); - virtual void exit(); - virtual void quick_exit(); - virtual void close(); - void restart(); - - void setName(const std::string& name) { m_appName = name; } - void setCompactName(const std::string& compactName) { m_appCompactName = compactName; } - void setVersion(const std::string& version) { m_appVersion = version; } - - bool isRunning() { return m_running; } - bool isStopping() { return m_stopping; } - bool isTerminated() { return m_terminated; } - const std::string& getName() { return m_appName; } - const std::string& getCompactName() { return m_appCompactName; } - const std::string& getVersion() { return m_appVersion; } - - std::string getCharset() { return m_charset; } - std::string getBuildCompiler() { return BUILD_COMPILER; } - std::string getBuildDate() { return std::string(__DATE__); } - std::string getBuildRevision() { return BUILD_REVISION; } - std::string getBuildCommit() { return BUILD_COMMIT; } - std::string getBuildType() { return BUILD_TYPE; } - std::string getBuildArch() { return BUILD_ARCH; } - std::string getAuthor() { return "otclient.ovh"; } - std::string getOs(); - std::string getStartupOptions() { return m_startupOptions; } - - bool isMobile() - { - return m_mobile; - } - -protected: - void registerLuaFunctions(); - - std::string m_charset; - std::string m_appName; - std::string m_appCompactName; - std::string m_appVersion; - std::string m_startupOptions; - stdext::boolean m_running; - stdext::boolean m_stopping; - stdext::boolean m_terminated; - stdext::boolean m_mobile; -}; - -#ifdef FW_GRAPHICS -#include "graphicalapplication.h" -#else -#include "consoleapplication.h" -#endif - -#endif diff --git a/src/framework/core/asyncdispatcher.cpp b/src/framework/core/asyncdispatcher.cpp deleted file mode 100644 index d1222b6..0000000 --- a/src/framework/core/asyncdispatcher.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "asyncdispatcher.h" - -AsyncDispatcher g_asyncDispatcher; - -void AsyncDispatcher::init() -{ - spawn_thread(); -} - -void AsyncDispatcher::terminate() -{ - stop(); - m_tasks.clear(); -} - -void AsyncDispatcher::spawn_thread() -{ - m_running = true; - m_threads.push_back(std::thread(std::bind(&AsyncDispatcher::exec_loop, this))); -} - -void AsyncDispatcher::stop() -{ - m_mutex.lock(); - m_running = false; - m_condition.notify_all(); - m_mutex.unlock(); - for(std::thread& thread : m_threads) - thread.join(); - m_threads.clear(); -}; - -void AsyncDispatcher::exec_loop() { - std::unique_lock lock(m_mutex); - while(true) { - while(m_tasks.size() == 0 && m_running) - m_condition.wait(lock); - - if(!m_running) - return; - - std::function task = m_tasks.front(); - m_tasks.pop_front(); - - lock.unlock(); - task(); - lock.lock(); - } -} diff --git a/src/framework/core/asyncdispatcher.h b/src/framework/core/asyncdispatcher.h deleted file mode 100644 index 182ef36..0000000 --- a/src/framework/core/asyncdispatcher.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef ASYNCDISPATCHER_H -#define ASYNCDISPATCHER_H - -#include "declarations.h" -#include - -class AsyncDispatcher { -public: - void init(); - void terminate(); - - void spawn_thread(); - void stop(); - - template - std::shared_future::type> schedule(const F& task) { - std::lock_guard lock(m_mutex); - auto prom = std::make_shared::type>>(); - m_tasks.push_back([=]() { prom->set_value(task()); }); - m_condition.notify_all(); - return std::shared_future::type>(prom->get_future()); - } - - void dispatch(std::function f) { - std::lock_guard lock(m_mutex); - m_tasks.push_back(f); - m_condition.notify_all(); - } - -protected: - void exec_loop(); - -private: - std::list> m_tasks; - std::list m_threads; - std::mutex m_mutex; - std::condition_variable m_condition; - stdext::boolean m_running; -}; - -extern AsyncDispatcher g_asyncDispatcher; - -#endif diff --git a/src/framework/core/binarytree.cpp b/src/framework/core/binarytree.cpp deleted file mode 100644 index d0148cb..0000000 --- a/src/framework/core/binarytree.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "binarytree.h" -#include "filestream.h" - -BinaryTree::BinaryTree(const FileStreamPtr& fin) - : m_fin(fin), m_pos(0xFFFFFFFF) { - m_startPos = fin->tell(); -} - -BinaryTree::~BinaryTree() {} - -void BinaryTree::skipNodes() { - while (true) { - uint8 byte = m_fin->getU8(); - switch (byte) { - case BINARYTREE_NODE_START: { - skipNodes(); - break; - } - case BINARYTREE_NODE_END: - return; - case BINARYTREE_ESCAPE_CHAR: - m_fin->getU8(); - break; - default: - break; - } - } -} - -void BinaryTree::unserialize() { - if (m_pos != 0xFFFFFFFF) return; - m_pos = 0; - - m_fin->seek(m_startPos); - while (true) { - uint8 byte = m_fin->getU8(); - switch (byte) { - case BINARYTREE_NODE_START: { - skipNodes(); - break; - } - case BINARYTREE_NODE_END: - return; - case BINARYTREE_ESCAPE_CHAR: - m_buffer.add(m_fin->getU8()); - break; - default: - m_buffer.add(byte); - break; - } - } -} - -BinaryTreeVec BinaryTree::getChildren() { - BinaryTreeVec children; - m_fin->seek(m_startPos); - while (true) { - uint8 byte = m_fin->getU8(); - switch (byte) { - case BINARYTREE_NODE_START: { - BinaryTreePtr node(new BinaryTree(m_fin)); - children.push_back(node); - node->skipNodes(); - break; - } - case BINARYTREE_NODE_END: - return children; - case BINARYTREE_ESCAPE_CHAR: - m_fin->getU8(); - break; - default: - break; - } - } -} - -void BinaryTree::seek(uint pos) { - unserialize(); - if (pos > m_buffer.size()) stdext::throw_exception("BinaryTree: seek failed"); - m_pos = pos; -} - -void BinaryTree::skip(uint len) { - unserialize(); - seek(tell() + len); -} - -uint8 BinaryTree::getU8() { - unserialize(); - if (m_pos + 1 > m_buffer.size()) - stdext::throw_exception("BinaryTree: getU8 failed"); - uint8 v = m_buffer[m_pos]; - m_pos += 1; - return v; -} - -uint16 BinaryTree::getU16() { - unserialize(); - if (m_pos + 2 > m_buffer.size()) - stdext::throw_exception("BinaryTree: getU16 failed"); - uint16 v = stdext::readULE16(&m_buffer[m_pos]); - m_pos += 2; - return v; -} - -uint32 BinaryTree::getU32() { - unserialize(); - if (m_pos + 4 > m_buffer.size()) - stdext::throw_exception("BinaryTree: getU32 failed"); - uint32 v = stdext::readULE32(&m_buffer[m_pos]); - m_pos += 4; - return v; -} - -uint64 BinaryTree::getU64() { - unserialize(); - if (m_pos + 8 > m_buffer.size()) - stdext::throw_exception("BinaryTree: getU64 failed"); - uint64 v = stdext::readULE64(&m_buffer[m_pos]); - m_pos += 8; - return v; -} - -std::string BinaryTree::getString(uint16 len) { - unserialize(); - if (len == 0) len = getU16(); - - if (m_pos + len > m_buffer.size()) - stdext::throw_exception( - "BinaryTree: getString failed: string length exceeded buffer size."); - - std::string ret((char*)&m_buffer[m_pos], len); - m_pos += len; - return ret; -} - -Point BinaryTree::getPoint() { - Point ret; - ret.x = getU8(); - ret.y = getU8(); - return ret; -} - -OutputBinaryTree::OutputBinaryTree(const FileStreamPtr& fin) : m_fin(fin) { - startNode(0); -} - -void OutputBinaryTree::addU8(uint8 v) { write(&v, 1); } - -void OutputBinaryTree::addU16(uint16 v) { - uint8 data[2]; - stdext::writeULE16(data, v); - write(data, 2); -} - -void OutputBinaryTree::addU32(uint32 v) { - uint8 data[4]; - stdext::writeULE32(data, v); - write(data, 4); -} - -void OutputBinaryTree::addString(const std::string& v) { - if (v.size() > 0xFFFF) stdext::throw_exception("too long string"); - - addU16(v.length()); - write((const uint8*)v.c_str(), v.length()); -} - -void OutputBinaryTree::addPos(uint16 x, uint16 y, uint8 z) { - addU16(x); - addU16(y); - addU8(z); -} - -void OutputBinaryTree::addPoint(const Point& point) { - addU8(point.x); - addU8(point.y); -} - -void OutputBinaryTree::startNode(uint8 node) { - m_fin->addU8(BINARYTREE_NODE_START); - write(&node, 1); -} - -void OutputBinaryTree::endNode() { m_fin->addU8(BINARYTREE_NODE_END); } - -void OutputBinaryTree::write(const uint8* data, size_t size) { - for (size_t i = 0; i < size; ++i) { - if (data[i] == BINARYTREE_NODE_START || data[i] == BINARYTREE_NODE_END || - data[i] == BINARYTREE_ESCAPE_CHAR) - m_fin->addU8(BINARYTREE_ESCAPE_CHAR); - m_fin->addU8(data[i]); - } -} \ No newline at end of file diff --git a/src/framework/core/binarytree.h b/src/framework/core/binarytree.h deleted file mode 100644 index 2137fe8..0000000 --- a/src/framework/core/binarytree.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef BINARYTREE_H -#define BINARYTREE_H - -#include "declarations.h" -#include - -enum { - BINARYTREE_ESCAPE_CHAR = 0xFD, - BINARYTREE_NODE_START = 0xFE, - BINARYTREE_NODE_END = 0xFF -}; - -class BinaryTree : public stdext::shared_object -{ -public: - BinaryTree(const FileStreamPtr& fin); - ~BinaryTree(); - - void seek(uint pos); - void skip(uint len); - uint tell() { return m_pos; } - uint size() { unserialize(); return m_buffer.size(); } - - uint8 getU8(); - uint16 getU16(); - uint32 getU32(); - uint64 getU64(); - std::string getString(uint16 len = 0); - Point getPoint(); - - BinaryTreeVec getChildren(); - bool canRead() { unserialize(); return m_pos < m_buffer.size(); } - -private: - void unserialize(); - void skipNodes(); - - FileStreamPtr m_fin; - DataBuffer m_buffer; - uint m_pos; - uint m_startPos; -}; - -class OutputBinaryTree : public stdext::shared_object -{ -public: - OutputBinaryTree(const FileStreamPtr& finish); - - void addU8(uint8 v); - void addU16(uint16 v); - void addU32(uint32 v); - void addString(const std::string& v); - void addPos(uint16 x, uint16 y, uint8 z); - void addPoint(const Point& point); - - void startNode(uint8 node); - void endNode(); - -private: - FileStreamPtr m_fin; - -protected: - void write(const uint8* data, size_t size); -}; - -#endif - diff --git a/src/framework/core/clock.cpp b/src/framework/core/clock.cpp deleted file mode 100644 index 7433824..0000000 --- a/src/framework/core/clock.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "clock.h" - -Clock g_clock; - -Clock::Clock() -{ - m_currentMicros = 0; - m_currentMillis = 0; - m_currentSeconds = 0; -} - -void Clock::update() -{ - m_currentMicros = stdext::micros(); - m_currentMillis = m_currentMicros / 1000; - m_currentSeconds = m_currentMicros / 1000000.0f; -} - -ticks_t Clock::realMicros() -{ - return stdext::micros(); -} - -ticks_t Clock::realMillis() -{ - return stdext::millis(); -} diff --git a/src/framework/core/clock.h b/src/framework/core/clock.h deleted file mode 100644 index 7b316e7..0000000 --- a/src/framework/core/clock.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CLOCK_H -#define CLOCK_H - -#include "declarations.h" - -// @bindsingleton g_clock -class Clock -{ -public: - Clock(); - - void update(); - - ticks_t micros() { return m_currentMicros; } - ticks_t millis() { return m_currentMillis; } - float seconds() { return m_currentSeconds; } - ticks_t realMicros(); - ticks_t realMillis(); - -private: - ticks_t m_currentMicros; - ticks_t m_currentMillis; - float m_currentSeconds; -}; - -extern Clock g_clock; - -#endif - diff --git a/src/framework/core/config.cpp b/src/framework/core/config.cpp deleted file mode 100644 index dfab8cb..0000000 --- a/src/framework/core/config.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "config.h" -#include "resourcemanager.h" -#include "configmanager.h" - -#include - -Config::Config() -{ - m_confsDoc = OTMLDocument::create(); - m_fileName = ""; -} - -bool Config::load(const std::string& file) -{ - m_fileName = file; - - if(!g_resources.fileExists(file)) - return false; - - try { - OTMLDocumentPtr confsDoc = OTMLDocument::parse(file); - if(confsDoc) - m_confsDoc = confsDoc; - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Unable to parse configuration file '%s': ", e.what())); - return false; - } -} - -bool Config::unload() -{ - if(isLoaded()) { - m_confsDoc = nullptr; - m_fileName = ""; - return true; - } - return false; -} - -bool Config::save() -{ - if(m_fileName.length() == 0) - return false; - return m_confsDoc->save(m_fileName); -} - -void Config::clear() -{ - m_confsDoc->clear(); -} - -void Config::setValue(const std::string& key, const std::string& value) -{ - if (key.empty()) { - return; - } - if(value.empty()) { - remove(key); - return; - } - - OTMLNodePtr child = OTMLNode::create(key, value); - m_confsDoc->addChild(child); -} - -void Config::setList(const std::string& key, const std::vector& list) -{ - remove(key); - - if(list.size() == 0) - return; - - OTMLNodePtr child = OTMLNode::create(key, true); - for(const std::string& value : list) - child->writeIn(value); - m_confsDoc->addChild(child); -} - -bool Config::exists(const std::string& key) -{ - return m_confsDoc->hasChildAt(key); -} - -std::string Config::getValue(const std::string& key) -{ - OTMLNodePtr child = m_confsDoc->get(key); - if(child) - return child->value(); - else - return ""; -} - -std::vector Config::getList(const std::string& key) -{ - std::vector list; - OTMLNodePtr child = m_confsDoc->get(key); - if(child) { - for(const OTMLNodePtr& subchild : child->children()) - list.push_back(subchild->value()); - } - return list; -} - -void Config::remove(const std::string& key) -{ - OTMLNodePtr child = m_confsDoc->get(key); - if(child) - m_confsDoc->removeChild(child); -} - -void Config::setNode(const std::string& key, const OTMLNodePtr& node) -{ - remove(key); - mergeNode(key, node); -} - -void Config::mergeNode(const std::string& key, const OTMLNodePtr& node) -{ - OTMLNodePtr clone = node->clone(); - node->setTag(key); - node->setUnique(true); - m_confsDoc->addChild(node); -} - -OTMLNodePtr Config::getNode(const std::string& key) -{ - return m_confsDoc->get(key); -} - -bool Config::isLoaded() -{ - return !m_fileName.empty() && m_confsDoc; -} - -std::string Config::getFileName() -{ - return m_fileName; -} diff --git a/src/framework/core/config.h b/src/framework/core/config.h deleted file mode 100644 index b06f1ce..0000000 --- a/src/framework/core/config.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CONFIG_H -#define CONFIG_H - -#include "declarations.h" - -#include -#include - -// @bindclass -class Config : public LuaObject -{ -public: - Config(); - - bool load(const std::string& file); - bool unload(); - bool save(); - void clear(); - - void setValue(const std::string& key, const std::string& value); - void setList(const std::string& key, const std::vector& list); - std::string getValue(const std::string& key); - std::vector getList(const std::string& key); - - void setNode(const std::string& key, const OTMLNodePtr& node); - void mergeNode(const std::string& key, const OTMLNodePtr& node); - OTMLNodePtr getNode(const std::string& key); - - bool exists(const std::string& key); - void remove(const std::string& key); - - std::string getFileName(); - bool isLoaded(); - - // @dontbind - ConfigPtr asConfig() { return static_self_cast(); } - -private: - std::string m_fileName; - OTMLDocumentPtr m_confsDoc; -}; - -#endif diff --git a/src/framework/core/configmanager.cpp b/src/framework/core/configmanager.cpp deleted file mode 100644 index 4c2c31a..0000000 --- a/src/framework/core/configmanager.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "configmanager.h" - -ConfigManager g_configs; - -void ConfigManager::init() -{ - m_settings = ConfigPtr(new Config()); -} - -void ConfigManager::terminate() -{ - if(m_settings) { - // ensure settings are saved - m_settings->save(); - - m_settings->unload(); - m_settings = nullptr; - } - - for(ConfigPtr config : m_configs) { - config->unload(); - config = nullptr; - } - - m_configs.clear(); -} - -ConfigPtr ConfigManager::getSettings() -{ - return m_settings; -} - -ConfigPtr ConfigManager::get(const std::string& file) -{ - for(const ConfigPtr config : m_configs) { - if(config->getFileName() == file) { - return config; - } - } - return nullptr; -} - -ConfigPtr ConfigManager::loadSettings(const std::string file) -{ - if(file.empty()) { - g_logger.error("Must provide a configuration file to load."); - } - else { - if(m_settings->load(file)) { - return m_settings; - } - } - return nullptr; -} - -ConfigPtr ConfigManager::create(const std::string& file) -{ - ConfigPtr config = load(file); - if(!config) { - config = ConfigPtr(new Config()); - - config->load(file); - config->save(); - - m_configs.push_back(config); - } - return config; -} - -ConfigPtr ConfigManager::load(const std::string& file) -{ - if(file.empty()) { - g_logger.error("Must provide a configuration file to load."); - return nullptr; - } - else { - ConfigPtr config = get(file); - if(!config) { - config = ConfigPtr(new Config()); - - if(config->load(file)) { - m_configs.push_back(config); - } - else { - // cannot load config - config = nullptr; - } - } - return config; - } -} - -bool ConfigManager::unload(const std::string& file) -{ - ConfigPtr config = get(file); - if(config) { - config->unload(); - remove(config); - config = nullptr; - return true; - } - return false; -} - -void ConfigManager::remove(const ConfigPtr config) -{ - m_configs.remove(config); -} diff --git a/src/framework/core/configmanager.h b/src/framework/core/configmanager.h deleted file mode 100644 index 371ed8d..0000000 --- a/src/framework/core/configmanager.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CONFIGMANAGER_H -#define CONFIGMANAGER_H - -#include "config.h" - -// @bindsingleton g_configs -class ConfigManager -{ -public: - void init(); - void terminate(); - - ConfigPtr getSettings(); - ConfigPtr get(const std::string& file); - - ConfigPtr create(const std::string& file); - ConfigPtr loadSettings(const std::string file); - ConfigPtr load(const std::string& file); - - bool unload(const std::string& file); - void remove(const ConfigPtr config); - -protected: - ConfigPtr m_settings; - -private: - std::list m_configs; -}; - -extern ConfigManager g_configs; - -#endif diff --git a/src/framework/core/consoleapplication.cpp b/src/framework/core/consoleapplication.cpp deleted file mode 100644 index a40b0b5..0000000 --- a/src/framework/core/consoleapplication.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010-2013 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#include "consoleapplication.h" -#include -#include - -#ifdef FW_NET -#include -#endif - -ConsoleApplication g_app; - -void ConsoleApplication::run() -{ - m_running = true; - - // run the first poll - poll(); - - // first clock update - g_clock.update(); - - g_lua.callGlobalField("g_app", "onRun"); - - while(!m_stopping) { - poll(); - stdext::millisleep(1); - g_clock.update(); - m_frameCounter.update(); - } - - m_stopping = false; - m_running = false; -} diff --git a/src/framework/core/consoleapplication.h b/src/framework/core/consoleapplication.h deleted file mode 100644 index 56d58fe..0000000 --- a/src/framework/core/consoleapplication.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2010-2013 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef CONSOLEAPPLICATION_H -#define CONSOLEAPPLICATION_H - -#include "application.h" - -class ConsoleApplication : public Application -{ -public: - void run(); - -protected: - -}; - -extern ConsoleApplication g_app; - -#endif diff --git a/src/framework/core/declarations.h b/src/framework/core/declarations.h deleted file mode 100644 index e2e4c50..0000000 --- a/src/framework/core/declarations.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FRAMEWORK_CORE_DECLARATIONS_H -#define FRAMEWORK_CORE_DECLARATIONS_H - -#include - -class ConfigManager; -class ModuleManager; -class ResourceManager; -class Module; -class Config; -class Event; -class ScheduledEvent; -class FileStream; -class BinaryTree; -class OutputBinaryTree; - -typedef stdext::shared_object_ptr ModulePtr; -typedef stdext::shared_object_ptr ConfigPtr; -typedef stdext::shared_object_ptr EventPtr; -typedef stdext::shared_object_ptr ScheduledEventPtr; -typedef stdext::shared_object_ptr FileStreamPtr; -typedef stdext::shared_object_ptr BinaryTreePtr; -typedef stdext::shared_object_ptr OutputBinaryTreePtr; - -typedef std::vector BinaryTreeVec; - -#endif diff --git a/src/framework/core/event.cpp b/src/framework/core/event.cpp deleted file mode 100644 index 137cf3d..0000000 --- a/src/framework/core/event.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "event.h" - -Event::Event(const std::string& function, const std::function& callback, bool botSafe) : - m_function(function), - m_callback(callback), - m_canceled(false), - m_executed(false), - m_botSafe(botSafe) -{ -} - -Event::~Event() -{ - // assure that we lost callback refs - //VALIDATE(m_callback == nullptr); -} - -void Event::execute() -{ - if(!m_canceled && !m_executed && m_callback) { - m_callback(); - m_executed = true; - } - - // reset callback to free object refs - m_callback = nullptr; -} - -void Event::cancel() -{ - m_canceled = true; - m_callback = nullptr; -} diff --git a/src/framework/core/event.h b/src/framework/core/event.h deleted file mode 100644 index db9b21e..0000000 --- a/src/framework/core/event.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef EVENT_H -#define EVENT_H - -#include - -// @bindclass -class Event : public LuaObject -{ -public: - Event(const std::string& function, const std::function& callback, bool botSafe = false); - virtual ~Event(); - - virtual void execute(); - void cancel(); - - bool isCanceled() { return m_canceled; } - bool isExecuted() { return m_executed; } - bool isBotSafe() { return m_botSafe; } - - const std::string& getFunction() { return m_function; } - -protected: - std::string m_function; - std::function m_callback; - bool m_canceled; - bool m_executed; - bool m_botSafe; -}; - -#endif diff --git a/src/framework/core/eventdispatcher.cpp b/src/framework/core/eventdispatcher.cpp deleted file mode 100644 index d066723..0000000 --- a/src/framework/core/eventdispatcher.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "eventdispatcher.h" - -#include -#include -#include -#include "timer.h" - -EventDispatcher g_dispatcher; -EventDispatcher g_graphicsDispatcher; -std::thread::id g_mainThreadId = std::this_thread::get_id(); -std::thread::id g_dispatcherThreadId = std::this_thread::get_id(); - -void EventDispatcher::shutdown() -{ - while(!m_eventList.empty()) - poll(); - - while(!m_scheduledEventList.empty()) { - ScheduledEventPtr scheduledEvent = m_scheduledEventList.top(); - scheduledEvent->cancel(); - m_scheduledEventList.pop(); - } - m_disabled = true; -} - -void EventDispatcher::poll() -{ - AutoStat s(this == &g_dispatcher ? STATS_MAIN : STATS_RENDER, "PollDispatcher"); - std::unique_lock lock(m_mutex); - - int loops = 0; - for(int count = 0, max = m_scheduledEventList.size(); count < max && !m_scheduledEventList.empty(); ++count) { - ScheduledEventPtr scheduledEvent = m_scheduledEventList.top(); - if(scheduledEvent->remainingTicks() > 0) - break; - m_scheduledEventList.pop(); - { - AutoStat s2(STATS_DISPATCHER, scheduledEvent->getFunction()); - m_botSafe = scheduledEvent->isBotSafe(); - m_mutex.unlock(); - scheduledEvent->execute(); - m_mutex.lock(); - } - - if(scheduledEvent->nextCycle()) - m_scheduledEventList.push(scheduledEvent); - } - - // execute events list until all events are out, this is needed because some events can schedule new events that would - // change the UIWidgets layout, in this case we must execute these new events before we continue rendering, - m_pollEventsSize = m_eventList.size(); - loops = 0; - while(m_pollEventsSize > 0) { - if(loops > 50) { - static Timer reportTimer; - if(reportTimer.running() && reportTimer.ticksElapsed() > 100) { - std::stringstream ss; - ss << "ATTENTION the event list is not getting empty, this could be caused by some bad code.\nLog:\n"; - for (auto& event : m_eventList) { - ss << event->getFunction() << "\n"; - if (ss.str().size() > 1024) break; - } - g_logger.error(ss.str()); - reportTimer.restart(); - } - break; - } - - for(int i=0;igetFunction()); - m_botSafe = event->isBotSafe(); - m_mutex.unlock(); - event->execute(); - m_mutex.lock(); - } - } - m_pollEventsSize = m_eventList.size(); - - loops++; - } - - m_botSafe = false; -} - -ScheduledEventPtr EventDispatcher::scheduleEventEx(const std::string& function, const std::function& callback, int delay) -{ - if(m_disabled) - return ScheduledEventPtr(new ScheduledEvent("", nullptr, delay, 1)); - - std::lock_guard lock(m_mutex); - - VALIDATE(delay >= 0); - ScheduledEventPtr scheduledEvent(new ScheduledEvent(function, callback, delay, 1, g_app.isOnInputEvent())); - m_scheduledEventList.push(scheduledEvent); - return scheduledEvent; -} - -ScheduledEventPtr EventDispatcher::cycleEventEx(const std::string& function, const std::function& callback, int delay) -{ - if(m_disabled) - return ScheduledEventPtr(new ScheduledEvent("", nullptr, delay, 0)); - - std::lock_guard lock(m_mutex); - - VALIDATE(delay > 0); - ScheduledEventPtr scheduledEvent(new ScheduledEvent(function, callback, delay, 0, g_app.isOnInputEvent())); - m_scheduledEventList.push(scheduledEvent); - return scheduledEvent; -} - -EventPtr EventDispatcher::addEventEx(const std::string& function, const std::function& callback, bool pushFront) -{ - if(m_disabled) - return EventPtr(new Event("", nullptr)); - - EventPtr event(new Event(function, callback, g_app.isOnInputEvent())); - - std::lock_guard lock(m_mutex); - - // front pushing is a way to execute an event before others - if(pushFront) { - m_eventList.push_front(event); - // the poll event list only grows when pushing into front - m_pollEventsSize++; - } else - m_eventList.push_back(event); - return event; -} - diff --git a/src/framework/core/eventdispatcher.h b/src/framework/core/eventdispatcher.h deleted file mode 100644 index 3ef7d34..0000000 --- a/src/framework/core/eventdispatcher.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef EVENTDISPATCHER_H -#define EVENTDISPATCHER_H - -#include "clock.h" -#include "scheduledevent.h" - -#include - -// @bindsingleton g_dispatcher -class EventDispatcher -{ -public: - void shutdown(); - void poll(); - - EventPtr addEventEx(const std::string& function, const std::function& callback, bool pushFront = false); - ScheduledEventPtr scheduleEventEx(const std::string& function, const std::function& callback, int delay); - ScheduledEventPtr cycleEventEx(const std::string& function, const std::function& callback, int delay); - - bool isBotSafe() { return m_botSafe; } - -private: - std::list m_eventList; - int m_pollEventsSize; - bool m_disabled = false; - bool m_botSafe = false; - std::recursive_mutex m_mutex; - std::priority_queue, lessScheduledEvent> m_scheduledEventList; -}; - -extern EventDispatcher g_dispatcher; -extern EventDispatcher g_graphicsDispatcher; -extern std::thread::id g_mainThreadId; -extern std::thread::id g_dispatcherThreadId; - -#define addEvent(...) addEventEx(__FUNCTION__, __VA_ARGS__) -#define scheduleEvent(...) scheduleEventEx(__FUNCTION__, __VA_ARGS__) -#define cycleEvent(...) cycleEventEx(__FUNCTION__, __VA_ARGS__) - -#endif diff --git a/src/framework/core/filestream.cpp b/src/framework/core/filestream.cpp deleted file mode 100644 index 8cb07e0..0000000 --- a/src/framework/core/filestream.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "filestream.h" -#include "binarytree.h" -#include - -#define PHYSFS_DEPRECATED -#include -#include - -FileStream::FileStream(const std::string& name, PHYSFS_File *fileHandle, bool writeable) : - m_name(name), - m_fileHandle(fileHandle), - m_pos(0), - m_writeable(writeable), - m_caching(false) -{ -} - -FileStream::FileStream(const std::string& name, const std::string& buffer) : - m_name(name), - m_fileHandle(nullptr), - m_pos(0), - m_writeable(false), - m_caching(true) -{ - if (!initFromGzip(buffer)) { - m_data.resize(buffer.length()); - memcpy(&m_data[0], &buffer[0], buffer.length()); - } -} - -bool FileStream::initFromGzip(const std::string& buffer) -{ - if (buffer.size() < 10 || (uint8_t)buffer[0] != 0x1f || - (uint8_t)buffer[1] != 0x8b || (uint8_t)buffer[2] != 0x08) { - return false; - } - z_stream stream; - memset(&stream, 0, sizeof(stream)); - - stream.next_in = (Bytef*)buffer.c_str(); - stream.avail_in = buffer.size(); - if (inflateInit2(&stream, 15 + 32) != Z_OK) - return false; - - std::vector chunk(buffer.size()); - while (true) { - stream.next_out = (Bytef*)(&chunk[0]); - stream.avail_out = chunk.size(); - - // Inflate another chunk. - int err = inflate(&stream, Z_SYNC_FLUSH); - int newData = chunk.size() - stream.avail_out; - if (newData > 0) { - m_data.grow(m_pos + newData, true); - memcpy(&m_data[m_pos], &chunk[0], newData); - m_pos += newData; - } - if (err != Z_OK) { - break; - } - } - inflateEnd(&stream); - m_pos = 0; - return true; -} - - -FileStream::~FileStream() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); -#endif - if(!g_app.isTerminated()) - close(); -} - -void FileStream::close() -{ - if(m_fileHandle && PHYSFS_isInit()) { - if(!PHYSFS_close(m_fileHandle)) - throwError("close failed", true); - m_fileHandle = nullptr; - } - - m_data.clear(); - m_pos = 0; -} - -void FileStream::flush() -{ - if(!m_writeable) - throwError("filestream is not writeable"); - - if(m_fileHandle) { - if(m_caching) { - if(!PHYSFS_seek(m_fileHandle, 0)) - throwError("flush seek failed", true); - uint len = m_data.size(); - if(PHYSFS_writeBytes(m_fileHandle, m_data.data(), len) != len) - throwError("flush write failed", true); - } - - if(PHYSFS_flush(m_fileHandle) == 0) - throwError("flush failed", true); - } -} - -int FileStream::read(void *buffer, uint32 size, uint32 nmemb) -{ - if(!m_caching) { - int res = PHYSFS_readBytes(m_fileHandle, buffer, size * nmemb); - if(res == -1) - throwError("read failed", true); - return res; - } else { - int writePos = 0; - uint8 *outBuffer = (uint8*)buffer; - for(uint i=0;i m_data.size()) - return i; - - for(uint j=0;j m_data.size()) - throwError("seek failed"); - m_pos = pos; - } -} - -void FileStream::skip(uint len) -{ - seek(tell() + len); -} - -uint FileStream::size() -{ - if(!m_caching) - return PHYSFS_fileLength(m_fileHandle); - else - return m_data.size(); -} - -uint FileStream::tell() -{ - if(!m_caching) - return PHYSFS_tell(m_fileHandle); - else - return m_pos; -} - -bool FileStream::eof() -{ - if(!m_caching) - return PHYSFS_eof(m_fileHandle); - else - return m_pos >= m_data.size(); -} - -uint8 FileStream::getU8() -{ - uint8 v = 0; - if(!m_caching) { - if(PHYSFS_readBytes(m_fileHandle, &v, 1) != 1) - throwError("read failed", true); - } else { - if(m_pos+1 > m_data.size()) - throwError("read failed"); - - v = m_data[m_pos]; - m_pos += 1; - } - return v; -} - -uint16 FileStream::getU16() -{ - uint16 v = 0; - if(!m_caching) { - if(PHYSFS_readULE16(m_fileHandle, &v) == 0) - throwError("read failed", true); - } else { - if(m_pos+2 > m_data.size()) - throwError("read failed"); - - v = stdext::readULE16(&m_data[m_pos]); - m_pos += 2; - } - return v; -} - -uint32 FileStream::getU32() -{ - uint32 v = 0; - if(!m_caching) { - if(PHYSFS_readULE32(m_fileHandle, &v) == 0) - throwError("read failed", true); - } else { - if(m_pos+4 > m_data.size()) - throwError("read failed"); - - v = stdext::readULE32(&m_data[m_pos]); - m_pos += 4; - } - return v; -} - -uint64 FileStream::getU64() -{ - uint64 v = 0; - if(!m_caching) { - if(PHYSFS_readULE64(m_fileHandle, (PHYSFS_uint64*)&v) == 0) - throwError("read failed", true); - } else { - if(m_pos+8 > m_data.size()) - throwError("read failed"); - v = stdext::readULE64(&m_data[m_pos]); - m_pos += 8; - } - return v; -} - -int8 FileStream::get8() -{ - int8 v = 0; - if(!m_caching) { - if(PHYSFS_readBytes(m_fileHandle, &v, 1) != 1) - throwError("read failed", true); - } else { - if(m_pos+1 > m_data.size()) - throwError("read failed"); - - v = m_data[m_pos]; - m_pos += 1; - } - return v; -} - -int16 FileStream::get16() -{ - int16 v = 0; - if(!m_caching) { - if(PHYSFS_readSLE16(m_fileHandle, &v) == 0) - throwError("read failed", true); - } else { - if(m_pos+2 > m_data.size()) - throwError("read failed"); - - v = stdext::readSLE16(&m_data[m_pos]); - m_pos += 2; - } - return v; -} - -int32 FileStream::get32() -{ - int32 v = 0; - if(!m_caching) { - if(PHYSFS_readSLE32(m_fileHandle, &v) == 0) - throwError("read failed", true); - } else { - if(m_pos+4 > m_data.size()) - throwError("read failed"); - - v = stdext::readSLE32(&m_data[m_pos]); - m_pos += 4; - } - return v; -} - -int64 FileStream::get64() -{ - int64 v = 0; - if(!m_caching) { - if(PHYSFS_readSLE64(m_fileHandle, (PHYSFS_sint64*)&v) == 0) - throwError("read failed", true); - } else { - if(m_pos+8 > m_data.size()) - throwError("read failed"); - v = stdext::readSLE64(&m_data[m_pos]); - m_pos += 8; - } - return v; -} - -std::string FileStream::getString() -{ - std::string str; - uint16 len = getU16(); - if (len > 0) { - std::vector buffer(len, 0); - if (m_fileHandle) { - if (PHYSFS_read(m_fileHandle, &buffer[0], 1, len) == 0) - throwError("read failed", true); - else - str = std::string(buffer.begin(), buffer.end()); - } else { - if (m_pos + len > m_data.size()) { - throwError("read failed"); - return 0; - } - - str = std::string((char*)&m_data[m_pos], len); - m_pos += len; - } - } else if (len != 0) - throwError("read failed because string is too big"); - return str; -} - -BinaryTreePtr FileStream::getBinaryTree() -{ - uint8 byte = getU8(); - if(byte != BINARYTREE_NODE_START) - stdext::throw_exception(stdext::format("failed to read node start (getBinaryTree): %d", byte)); - - return BinaryTreePtr(new BinaryTree(asFileStream())); -} - -void FileStream::startNode(uint8 n) -{ - addU8(BINARYTREE_NODE_START); - addU8(n); -} - -void FileStream::endNode() -{ - addU8(BINARYTREE_NODE_END); -} - -void FileStream::addU8(uint8 v) -{ - if(!m_caching) { - if(PHYSFS_writeBytes(m_fileHandle, &v, 1) != 1) - throwError("write failed", true); - } else { - m_data.add(v); - m_pos++; - } -} - -void FileStream::addU16(uint16 v) -{ - if(!m_caching) { - if(PHYSFS_writeULE16(m_fileHandle, v) == 0) - throwError("write failed", true); - } else { - m_data.grow(m_pos + 2); - stdext::writeULE16(&m_data[m_pos], v); - m_pos += 2; - } -} - -void FileStream::addU32(uint32 v) -{ - if(!m_caching) { - if(PHYSFS_writeULE32(m_fileHandle, v) == 0) - throwError("write failed", true); - } else { - m_data.grow(m_pos + 4); - stdext::writeULE32(&m_data[m_pos], v); - m_pos += 4; - } -} - -void FileStream::addU64(uint64 v) -{ - if(!m_caching) { - if(PHYSFS_writeULE64(m_fileHandle, v) == 0) - throwError("write failed", true); - } else { - m_data.grow(m_pos + 8); - stdext::writeULE64(&m_data[m_pos], v); - m_pos += 8; - } -} - -void FileStream::add8(int8 v) -{ - if(!m_caching) { - if(PHYSFS_writeBytes(m_fileHandle, &v, 1) != 1) - throwError("write failed", true); - } else { - m_data.add(v); - m_pos++; - } -} - -void FileStream::add16(int16 v) -{ - if(!m_caching) { - if(PHYSFS_writeSLE16(m_fileHandle, v) == 0) - throwError("write failed", true); - } else { - m_data.grow(m_pos + 2); - stdext::writeSLE16(&m_data[m_pos], v); - m_pos += 2; - } -} - -void FileStream::add32(int32 v) -{ - if(!m_caching) { - if(PHYSFS_writeSLE32(m_fileHandle, v) == 0) - throwError("write failed", true); - } else { - m_data.grow(m_pos + 4); - stdext::writeSLE32(&m_data[m_pos], v); - m_pos += 4; - } -} - -void FileStream::add64(int64 v) -{ - if(!m_caching) { - if(PHYSFS_writeSLE64(m_fileHandle, v) == 0) - throwError("write failed", true); - } else { - m_data.grow(m_pos + 8); - stdext::writeSLE64(&m_data[m_pos], v); - m_pos += 8; - } -} - -void FileStream::addString(const std::string& v) -{ - addU16(v.length()); - write(v.c_str(), v.length()); -} - -void FileStream::throwError(const std::string& message, bool physfsError) -{ - std::string completeMessage = stdext::format("in file '%s': %s", m_name, message); - if(physfsError) - completeMessage += std::string(": ") + PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); - stdext::throw_exception(completeMessage); -} - diff --git a/src/framework/core/filestream.h b/src/framework/core/filestream.h deleted file mode 100644 index b150341..0000000 --- a/src/framework/core/filestream.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FILESTREAM_H -#define FILESTREAM_H - -#include "declarations.h" -#include -#include -#include - -struct PHYSFS_File; - -// @bindclass -class FileStream : public LuaObject -{ -public: - FileStream(const std::string& name, PHYSFS_File *fileHandle, bool writeable); - FileStream(const std::string& name, const std::string& buffer); - ~FileStream(); - - void close(); - void flush(); - void write(const void *buffer, uint count); - int read(void *buffer, uint size, uint nmemb = 1); - void seek(uint pos); - void skip(uint len); - uint size(); - uint tell(); - bool eof(); - std::string name() { return m_name; } - - uint8 getU8(); - uint16 getU16(); - uint32 getU32(); - uint64 getU64(); - int8 get8(); - int16 get16(); - int32 get32(); - int64 get64(); - std::string getString(); - BinaryTreePtr getBinaryTree(); - - void startNode(uint8 n); - void endNode(); - void addU8(uint8 v); - void addU16(uint16 v); - void addU32(uint32 v); - void addU64(uint64 v); - void add8(int8 v); - void add16(int16 v); - void add32(int32 v); - void add64(int64 v); - void addString(const std::string& v); - void addPos(uint16 x, uint16 y, uint8 z) { addU16(x); addU16(y); addU8(z); } - void addPoint(const Point& p) { addU8(p.x); addU8(p.y); } - - FileStreamPtr asFileStream() { return static_self_cast(); } - -private: - bool initFromGzip(const std::string& buffer); - void checkWrite(); - void throwError(const std::string& message, bool physfsError = false); - - std::string m_name; - PHYSFS_File *m_fileHandle; - uint m_pos; - bool m_writeable; - bool m_caching; - - DataBuffer m_data; -}; - -#endif diff --git a/src/framework/core/graphicalapplication.cpp b/src/framework/core/graphicalapplication.cpp deleted file mode 100644 index 3b03449..0000000 --- a/src/framework/core/graphicalapplication.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#include "graphicalapplication.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef FW_SOUND -#include -#endif - -GraphicalApplication g_app; - -void GraphicalApplication::init(std::vector& args) -{ - Application::init(args); - - // setup platform window - g_window.init(); - g_window.hide(); - g_window.setOnResize(std::bind(&GraphicalApplication::resize, this, std::placeholders::_1)); - g_window.setOnInputEvent(std::bind(&GraphicalApplication::inputEvent, this, std::placeholders::_1)); - g_window.setOnClose(std::bind(&GraphicalApplication::close, this)); - - g_mouse.init(); - - // initialize ui - g_ui.init(); - - // initialize graphics - g_graphics.init(); - - // fire first resize event - resize(g_window.getSize()); - -#ifdef FW_SOUND - // initialize sound - g_sounds.init(); -#endif -} - -void GraphicalApplication::deinit() -{ - // hide the window because there is no render anymore - g_window.hide(); - g_asyncDispatcher.terminate(); - - Application::deinit(); -} - -void GraphicalApplication::terminate() -{ - // destroy any remaining widget - g_ui.terminate(); - - Application::terminate(); - m_terminated = false; - -#ifdef FW_SOUND - // terminate sound - g_sounds.terminate(); -#endif - - g_mouse.terminate(); - - // terminate graphics - g_graphicsDispatcher.shutdown(); - g_graphics.terminate(); - g_window.terminate(); - - m_terminated = true; -} - -void GraphicalApplication::run() -{ - m_running = true; - - // first clock update - g_clock.update(); - - // run the first poll - poll(); - g_clock.update(); - - // show window - g_window.show(); - - // run the second poll - poll(); - g_clock.update(); - - g_lua.callGlobalField("g_app", "onRun"); - - m_framebuffer = g_framebuffers.createFrameBuffer(); - m_framebuffer->resize(g_painterNew->getResolution()); - m_mapFramebuffer = g_framebuffers.createFrameBuffer(); - m_mapFramebuffer->resize(g_painterNew->getResolution()); - - ticks_t lastRender = stdext::micros(); - - std::shared_ptr drawQueue; - std::shared_ptr drawMapQueue; - std::shared_ptr drawMapForegroundQueue; - - std::mutex mutex; - std::thread worker([&] { - g_dispatcherThreadId = std::this_thread::get_id(); - while (!m_stopping) { - m_processingFrames.addFrame(); - { - g_clock.update(); - poll(); - g_clock.update(); - } - - mutex.lock(); - if (drawQueue && drawMapQueue && m_maxFps > 0) { // old drawQueue not processed yet - mutex.unlock(); - AutoStat s(STATS_MAIN, "Sleep"); - stdext::millisleep(1); - continue; - } - mutex.unlock(); - - { - AutoStat s(STATS_MAIN, "DrawMapBackground"); - g_drawQueue = std::make_shared(); - g_ui.render(Fw::MapBackgroundPane); - } - std::shared_ptr mapBackgroundQueue = g_drawQueue; - { - AutoStat s(STATS_MAIN, "DrawMapForeground"); - g_drawQueue = std::make_shared(); - g_ui.render(Fw::MapForegroundPane); - } - - mutex.lock(); - drawMapQueue = mapBackgroundQueue; - drawMapForegroundQueue = g_drawQueue; - mutex.unlock(); - - { - AutoStat s(STATS_MAIN, "DrawForeground"); - g_drawQueue = std::make_shared(); - g_ui.render(Fw::ForegroundPane); - } - - mutex.lock(); - drawQueue = g_drawQueue; - g_drawQueue = nullptr; - mutex.unlock(); - - if (m_maxFps > 0 || g_window.hasVerticalSync()) { - AutoStat s(STATS_MAIN, "Sleep"); - stdext::millisleep(1); - } - } - g_dispatcher.poll(); // last poll - g_dispatcherThreadId = g_mainThreadId; - }); - - std::shared_ptr toDrawQueue, toDrawMapQueue, toDrawMapForegroundQueue; - int draws = 0, calls = 0; - while (!m_stopping) { - m_iteration += 1; - - pollGraphics(); - - if (!g_window.isVisible()) { - AutoStat s(STATS_RENDER, "Sleep"); - stdext::millisleep(1); - g_adaptiveRenderer.refresh(); - continue; - } - - int frameDelay = m_maxFps <= 0 ? 0 : (1000000 / m_maxFps); - if (lastRender + frameDelay > stdext::micros() && !m_mustRepaint) { - AutoStat s(STATS_RENDER, "Sleep"); - stdext::millisleep(1); - continue; - } - - mutex.lock(); - if ((!drawQueue && !toDrawQueue) || !drawMapQueue || !drawMapForegroundQueue || (m_mustRepaint && !drawQueue)) { - mutex.unlock(); - continue; - } - toDrawQueue = drawQueue ? drawQueue : toDrawQueue; - toDrawMapQueue = drawMapQueue; - toDrawMapForegroundQueue = drawMapForegroundQueue; - drawQueue = drawMapQueue = drawMapForegroundQueue = nullptr; - mutex.unlock(); - - g_adaptiveRenderer.newFrame(); - m_graphicsFrames.addFrame(); - m_mustRepaint = false; - lastRender = stdext::micros() > lastRender + frameDelay * 2 ? stdext::micros() : lastRender + frameDelay; - - g_painterNew->resetDraws(); - if (m_scaling > 1.0f) { - g_painterNew->setResolution(g_graphics.getViewportSize() / m_scaling); - m_framebuffer->resize(g_painterNew->getResolution()); - m_framebuffer->bind(); - } - - if (toDrawMapQueue->hasFrameBuffer()) { - AutoStat s(STATS_RENDER, "UpdateMap"); - m_mapFramebuffer->resize(toDrawMapQueue->getFrameBufferSize()); - m_mapFramebuffer->bind(); - g_painterNew->clear(Color::black); - toDrawMapQueue->draw(DRAW_ALL); - m_mapFramebuffer->release(); - } - - { - AutoStat s(STATS_RENDER, "Clear"); - g_painterNew->clear(Color::alpha); - } - - { - AutoStat s(STATS_RENDER, "DrawFirstForeground"); - if (toDrawQueue) - toDrawQueue->draw(DRAW_BEFORE_MAP); - } - - if(toDrawMapQueue->hasFrameBuffer()) { - AutoStat s(STATS_RENDER, "DrawMapBackground"); - m_mapFramebuffer->draw(toDrawMapQueue->getFrameBufferDest(), toDrawMapQueue->getFrameBufferSrc()); - } - - { - AutoStat s(STATS_RENDER, "DrawMapForeground"); - toDrawMapForegroundQueue->draw(); - } - - { - AutoStat s(STATS_RENDER, "DrawSecondForeground"); - if(g_extras.debugRender) - toDrawQueue->addText(g_fonts.getDefaultFont(), stdext::format("Calls: %i Draws %i", calls, draws), Rect(0, 0, 200, 200), Fw::AlignTopLeft, Color::yellow); - toDrawQueue->draw(DRAW_AFTER_MAP); - } - - if (m_scaling > 1.0f) { - AutoStat s(STATS_RENDER, "DrawScaled"); - m_framebuffer->release(); - g_painterNew->setResolution(g_graphics.getViewportSize()); - g_painterNew->clear(Color::alpha); - m_framebuffer->draw(Rect(0, 0, g_painterNew->getResolution())); - } - - draws = g_painterNew->draws(); - calls = g_painterNew->calls(); - - AutoStat s(STATS_RENDER, "SwapBuffers"); - g_window.swapBuffers(); - g_graphics.checkForError(__FUNCTION__, __FILE__, __LINE__); - } - - worker.join(); - g_graphicsDispatcher.poll(); - - m_framebuffer = nullptr; - m_mapFramebuffer = nullptr; - g_drawQueue = nullptr; - m_stopping = false; - m_running = false; -} - -void GraphicalApplication::poll() { -#ifdef FW_SOUND - g_sounds.poll(); -#endif - Application::poll(); -} - -void GraphicalApplication::pollGraphics() -{ - g_graphicsDispatcher.poll(); - g_textures.poll(); - g_text.poll(); - g_window.poll(); -} - -void GraphicalApplication::close() -{ - VALIDATE(std::this_thread::get_id() == g_dispatcherThreadId); - m_onInputEvent = true; - Application::close(); - m_onInputEvent = false; -} - -void GraphicalApplication::resize(const Size& size) -{ - VALIDATE(std::this_thread::get_id() == g_mainThreadId); - g_graphics.resize(size); // uses painter - scale(m_scaling); // thread safe -} - -void GraphicalApplication::inputEvent(InputEvent event) -{ - VALIDATE(std::this_thread::get_id() == g_dispatcherThreadId); - m_onInputEvent = true; - g_ui.inputEvent(event); - m_onInputEvent = false; -} - -void GraphicalApplication::doScreenshot(std::string file) -{ - if (g_mainThreadId != std::this_thread::get_id()) { - g_graphicsDispatcher.addEvent(std::bind(&GraphicalApplication::doScreenshot, this, file)); - return; - } - - if (file.empty()) { - file = "screenshot.png"; - } - auto resolution = g_graphics.getViewportSize(); - int width = resolution.width(); - int height = resolution.height(); - auto pixels = std::make_shared>(width * height * 4 * sizeof(GLubyte), 0); - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte*)(pixels->data())); - - g_asyncDispatcher.dispatch([resolution, pixels, file] { - for (int line = 0, h = resolution.height(), w = resolution.width(); line != h / 2; ++line) { - std::swap_ranges( - pixels->begin() + 4 * w * line, - pixels->begin() + 4 * w * (line + 1), - pixels->begin() + 4 * w * (h - line - 1)); - } - try { - Image image(resolution, 4, pixels->data()); - image.savePNG(file); - } catch (stdext::exception& e) { - g_logger.error(std::string("Can't do screenshot: ") + e.what()); - } - }); -} - -void GraphicalApplication::scaleUp() -{ - if (g_mainThreadId != std::this_thread::get_id()) { - g_graphicsDispatcher.addEvent(std::bind(&GraphicalApplication::scaleUp, this)); - return; - } - scale(m_scaling + 0.5); -} - -void GraphicalApplication::scaleDown() -{ - if (g_mainThreadId != std::this_thread::get_id()) { - g_graphicsDispatcher.addEvent(std::bind(&GraphicalApplication::scaleDown, this)); - return; - } - scale(m_scaling - 0.5); -} - -void GraphicalApplication::scale(float value) -{ - if (g_mainThreadId != std::this_thread::get_id()) { - g_graphicsDispatcher.addEvent(std::bind(&GraphicalApplication::scale, this, value)); - return; - } - - float maxScale = std::min((g_graphics.getViewportSize().height() / 180), - g_graphics.getViewportSize().width() / 280); - if (maxScale < 2.0) - maxScale = 2.0; - maxScale /= 2; - - if (m_scaling == value) { - value = m_lastScaling; - } else { - m_lastScaling = std::max(1.0, std::min(maxScale, value)); - } - - m_scaling = std::max(1.0, std::min(maxScale, value)); - g_window.setScaling(m_scaling); - - g_dispatcher.addEvent([&] { - m_onInputEvent = true; - g_ui.resize(g_graphics.getViewportSize() / m_scaling); - m_onInputEvent = false; - m_mustRepaint = true; - }); -} \ No newline at end of file diff --git a/src/framework/core/graphicalapplication.h b/src/framework/core/graphicalapplication.h deleted file mode 100644 index e5c425f..0000000 --- a/src/framework/core/graphicalapplication.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef GRAPHICALAPPLICATION_H -#define GRAPHICALAPPLICATION_H - -#include "application.h" -#include -#include -#include -#include -#include - -class GraphicalApplication : public Application -{ -public: - void init(std::vector& args); - void deinit(); - void terminate(); - void run(); - void poll(); - void pollGraphics(); - void close(); - - bool willRepaint() { return m_mustRepaint; } - void repaint() { m_mustRepaint = true; } - - void setMaxFps(int maxFps) { m_maxFps = maxFps; } - int getMaxFps() { return m_maxFps; } - int getFps() { return m_graphicsFrames.getFps(); } - int getGraphicsFps() { return m_graphicsFrames.getFps(); } - int getProcessingFps() { return m_processingFrames.getFps(); } - - bool isOnInputEvent() { return m_onInputEvent; } - - int getIteration() { - return m_iteration; - } - - void doScreenshot(std::string file); - void scaleUp(); - void scaleDown(); - void scale(float value); - -protected: - void resize(const Size& size); - void inputEvent(InputEvent event); - -private: - int m_iteration = 0; - std::atomic m_scaling = 1.0; - std::atomic m_lastScaling = 1.0; - std::atomic_int m_maxFps = 100; - stdext::boolean m_onInputEvent; - stdext::boolean m_mustRepaint; - FrameBufferPtr m_framebuffer, m_mapFramebuffer; - FrameCounter m_graphicsFrames; - FrameCounter m_processingFrames; -}; - -extern GraphicalApplication g_app; - -#endif diff --git a/src/framework/core/inputevent.h b/src/framework/core/inputevent.h deleted file mode 100644 index 4cf461e..0000000 --- a/src/framework/core/inputevent.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef INPUTEVENT_H -#define INPUTEVENT_H - -#include "declarations.h" - -struct InputEvent { - InputEvent() { - reset(); - keyboardModifiers = 0; - } - - void reset(Fw::InputEventType eventType = Fw::NoInputEvent) { - type = eventType; - wheelDirection = Fw::MouseNoWheel; - mouseButton = Fw::MouseNoButton; - keyCode = Fw::KeyUnknown; - keyText = ""; - autoRepeatTicks = 0; - mouseMoved = Point(); - }; - - Fw::InputEventType type; - Fw::MouseWheelDirection wheelDirection; - Fw::MouseButton mouseButton; - Fw::Key keyCode; - std::string keyText; - int keyboardModifiers; - Point mousePos; - Point mouseMoved; - int autoRepeatTicks; -}; - -#endif diff --git a/src/framework/core/logger.cpp b/src/framework/core/logger.cpp deleted file mode 100644 index 92698ce..0000000 --- a/src/framework/core/logger.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "logger.h" -#include "eventdispatcher.h" - -#include -#include - -#ifdef FW_GRAPHICS -#include -#include -#include -#endif - -Logger g_logger; - -void Logger::log(Fw::LogLevel level, const std::string& message) -{ - std::unique_lock lock(m_mutex, std::try_to_lock); - if (!lock.owns_lock()) { - return; - } - -#ifdef NDEBUG - if(level == Fw::LogDebug) - return; -#endif - - static bool ignoreLogs = false; - if(ignoreLogs) - return; - - const static std::string logPrefixes[] = { "", "", "WARNING: ", "ERROR: ", "FATAL ERROR: " }; - std::string outmsg = logPrefixes[level] + message; -#ifdef ANDROID - const static int logPriorities[] = { ANDROID_LOG_INFO, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL }; - __android_log_print(logPriorities[level], "OTCLIENTV8", "%s", outmsg.c_str()); -#else - std::cout << outmsg << std::endl; - - if(m_outFile.good()) { - m_outFile << outmsg << std::endl; - m_outFile.flush(); - } -#endif - - std::size_t now = std::time(NULL); - m_logMessages.push_back(LogMessage(level, outmsg, now)); - if(m_logMessages.size() > MAX_LOG_HISTORY) - m_logMessages.pop_front(); - - if(m_onLog) { - // schedule log callback, because this callback can run lua code that may affect the current state - g_dispatcher.addEvent([=] { - if(m_onLog) - m_onLog(level, outmsg, now); - }); - } - - if(level == Fw::LogFatal) { -#ifdef FW_GRAPHICS - g_window.displayFatalError(message); -#endif - ignoreLogs = true; -#ifdef _MSC_VER - ::quick_exit(0); -#else - exit(0); -#endif - } -} - -void Logger::logFunc(Fw::LogLevel level, const std::string& message, std::string prettyFunction) -{ - std::lock_guard lock(m_mutex); - - prettyFunction = prettyFunction.substr(0, prettyFunction.find_first_of('(')); - if(prettyFunction.find_last_of(' ') != std::string::npos) - prettyFunction = prettyFunction.substr(prettyFunction.find_last_of(' ') + 1); - - - std::stringstream ss; - ss << message; - - if(!prettyFunction.empty()) { - if(g_lua.isInCppCallback()) - ss << g_lua.traceback("", 1); - ss << g_platform.traceback(prettyFunction, 1, 8); - } - - log(level, ss.str()); -} - -void Logger::fireOldMessages() -{ - std::lock_guard lock(m_mutex); - - if(m_onLog) { - auto backup = m_logMessages; - for(const LogMessage& logMessage : backup) { - m_onLog(logMessage.level, logMessage.message, logMessage.when); - } - } -} - -void Logger::setLogFile(const std::string& file) -{ -#ifndef ANDROID - std::lock_guard lock(m_mutex); - m_outFile.open(stdext::utf8_to_latin1(file.c_str()).c_str(), std::ios::in | std::ios::binary); - if (m_outFile.is_open()) { - m_outFile.seekg(0, m_outFile.end); - int length = m_outFile.tellg(); - int offset = std::max(0, length - 100000); - length -= offset; - m_outFile.seekg(offset, m_outFile.beg); - if (length > 0) { - m_lastLog.resize(length); - m_outFile.read(&m_lastLog[0], length); - m_lastLog.resize(m_outFile.gcount()); - } - m_outFile.close(); - } - - m_outFile.open(stdext::utf8_to_latin1(file.c_str()).c_str(), std::ios::out | std::ios::app); - if(!m_outFile.is_open() || !m_outFile.good()) { - g_logger.error(stdext::format("Unable to save log to '%s'", file)); - return; - } - m_outFile.flush(); -#endif -} - -void fatalError(const char* error, const char* file, int line) -{ - g_logger.fatal(stdext::format("Fatal error: %s\nIn: %s:%i", error, file, line)); -} diff --git a/src/framework/core/logger.h b/src/framework/core/logger.h deleted file mode 100644 index 91f83ac..0000000 --- a/src/framework/core/logger.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LOGGER_H -#define LOGGER_H - -#include "../global.h" - -#include -#include - -struct LogMessage { - LogMessage(Fw::LogLevel level, const std::string& message, std::size_t when) : level(level), message(message), when(when) { } - Fw::LogLevel level; - std::string message; - std::size_t when; -}; - -// @bindsingleton g_logger -class Logger -{ - enum { - MAX_LOG_HISTORY = 1000 - }; - - typedef std::function OnLogCallback; - -public: - void log(Fw::LogLevel level, const std::string& message); - void logFunc(Fw::LogLevel level, const std::string& message, std::string prettyFunction); - - void debug(const std::string& what) { log(Fw::LogDebug, what); } - void info(const std::string& what) { log(Fw::LogInfo, what); } - void warning(const std::string& what) { log(Fw::LogWarning, what); } - void error(const std::string& what) { log(Fw::LogError, what); } - void fatal(const std::string& what) { log(Fw::LogFatal, what); } - - void fireOldMessages(); - void setLogFile(const std::string& file); - void setOnLog(const OnLogCallback& onLog) { m_onLog = onLog; } - - std::string getLastLog() { - return m_lastLog; - } - -private: - std::list m_logMessages; - OnLogCallback m_onLog; - std::fstream m_outFile; - std::recursive_mutex m_mutex; - std::string m_lastLog; -}; - -extern Logger g_logger; - -#define trace() logFunc(Fw::LogDebug, "", __PRETTY_FUNCTION__) -#define traceDebug(a) logFunc(Fw::LogDebug, a, __PRETTY_FUNCTION__) -#define traceInfo(a) logFunc(Fw::LogInfo, a, __PRETTY_FUNCTION__) -#define traceWarning(a) logFunc(Fw::LogWarning, a, __PRETTY_FUNCTION__) -#define traceError(a) logFunc(Fw::LogError, a, __PRETTY_FUNCTION__) - -#define logTraceCounter() { \ - static int __count = 0; \ - static Timer __timer; \ - __count++; \ - if(__timer.ticksElapsed() >= 1000) { \ - logTraceDebug(__count); \ - __count = 0; \ - __timer.restart(); \ - } \ -} - -#define logTraceFrameCounter() { \ - static int __count = 0; \ - static Timer __timer; \ - __count++; \ - if(__timer.ticksElapsed() > 0) { \ - logTraceDebug(__count); \ - __count = 0; \ - __timer.restart(); \ - } \ -} - -#endif diff --git a/src/framework/core/module.cpp b/src/framework/core/module.cpp deleted file mode 100644 index 37b2c16..0000000 --- a/src/framework/core/module.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "module.h" -#include "modulemanager.h" -#include "resourcemanager.h" - -#include -#include - -Module::Module(const std::string& name) -{ - m_name = name; - m_sandboxEnv = g_lua.newSandboxEnv(); -} - -bool Module::load() -{ - if(m_loaded) - return true; - - auto errorHandler = [&] (const std::string& error) { - g_lua.getGlobalField("package", "loaded"); - g_lua.pushNil(); - g_lua.setField(m_name); - g_lua.pop(); - - if(m_sandboxed) - g_lua.resetGlobalEnvironment(); - if(m_loadedOnStartup) // just reload, don't exit - g_logger.error(stdext::format("Unable to load module '%s': %s", m_name, error)); - else - g_logger.fatal(stdext::format("Unable to load module '%s': %s", m_name, error)); - }; - - try { - // add to package.loaded - g_lua.getGlobalField("package", "loaded"); - g_lua.getRef(m_sandboxEnv); - g_lua.setField(m_name); - g_lua.pop(); - - for(const std::string& depName : m_dependencies) { - if(depName == m_name) - stdext::throw_exception("cannot depend on itself"); - - ModulePtr dep = g_modules.getModule(depName); - if(!dep) - stdext::throw_exception(stdext::format("dependency '%s' was not found", depName)); - - if(dep->hasDependency(m_name, true)) - stdext::throw_exception(stdext::format("dependency '%s' is recursively depending on itself", depName)); - - if(!dep->isLoaded() && !dep->load()) - stdext::throw_exception(stdext::format("dependency '%s' has failed to load", depName)); - } - - if(m_sandboxed) - g_lua.setGlobalEnvironment(m_sandboxEnv); - - for(const std::string& script : m_scripts) { - g_lua.loadScript(script); - auto error = std::make_shared(); - g_lua.safeCall(0, 0, error); - if (!error->empty()) { - errorHandler(*error); - return false; - } - } - - const std::string& onLoadBuffer = std::get<0>(m_onLoadFunc); - const std::string& onLoadSource = std::get<1>(m_onLoadFunc); - if(!onLoadBuffer.empty()) { - g_lua.loadBuffer(onLoadBuffer, onLoadSource); - if(m_sandboxed) { - g_lua.getRef(m_sandboxEnv); - g_lua.setEnv(); - } - auto error = std::make_shared(); - g_lua.safeCall(0, 0, error); - if (!error->empty()) { - errorHandler(*error); - return false; - } - } - - if(m_sandboxed) - g_lua.resetGlobalEnvironment(); - - m_loaded = true; - g_logger.debug(stdext::format("Loaded module '%s'", m_name)); - } catch(stdext::exception& e) { - // remove from package.loaded - errorHandler(e.what()); - return false; - } - - g_modules.updateModuleLoadOrder(asModule()); - - for(const std::string& modName : m_loadLaterModules) { - ModulePtr dep = g_modules.getModule(modName); - if(!dep) - g_logger.error(stdext::format("Unable to find module '%s' required by '%s'", modName, m_name)); - else if(!dep->isLoaded()) - dep->load(); - } - - m_loadedOnStartup = true; - return true; -} - -void Module::unload() -{ - if(m_loaded) { - try { - if(m_sandboxed) - g_lua.setGlobalEnvironment(m_sandboxEnv); - - const std::string& onUnloadBuffer = std::get<0>(m_onUnloadFunc); - const std::string& onUnloadSource = std::get<1>(m_onUnloadFunc); - if(!onUnloadBuffer.empty()) { - g_lua.loadBuffer(onUnloadBuffer, onUnloadSource); - g_lua.safeCall(0, 0); - } - - if(m_sandboxed) - g_lua.resetGlobalEnvironment(); - } catch(stdext::exception& e) { - if(m_sandboxed) - g_lua.resetGlobalEnvironment(); - g_logger.error(stdext::format("Unable to unload module '%s': %s", m_name, e.what())); - } - - // clear all env references - g_lua.getRef(m_sandboxEnv); - g_lua.clearTable(); - g_lua.pop(); - - // remove from package.loaded - g_lua.getGlobalField("package", "loaded"); - g_lua.pushNil(); - g_lua.setField(m_name); - g_lua.pop(); - - m_loaded = false; - //g_logger.info(stdext::format("Unloaded module '%s'", m_name)); - g_modules.updateModuleLoadOrder(asModule()); - } -} - -bool Module::reload() -{ - unload(); - return load(); -} - -bool Module::isDependent() -{ - for(const ModulePtr& module : g_modules.getModules()) { - if(module->isLoaded() && module->hasDependency(m_name)) - return true; - } - return false; -} - -bool Module::hasDependency(const std::string& name, bool recursive) -{ - if(std::find(m_dependencies.begin(), m_dependencies.end(), name) != m_dependencies.end()) - return true; - - if(recursive) { - for(const std::string& depName : m_dependencies) { - ModulePtr dep = g_modules.getModule(depName); - if(dep && dep->hasDependency(name, true)) - return true; - } - } - - return false; -} - -int Module::getSandbox(LuaInterface* lua) -{ - lua->getRef(m_sandboxEnv); - return 1; -} - -void Module::discover(const OTMLNodePtr& moduleNode) -{ - const static std::string none = "none"; - m_description = moduleNode->valueAt("description", none); - m_author = moduleNode->valueAt("author", none); - m_website = moduleNode->valueAt("website", none); - m_version = moduleNode->valueAt("version", none); - m_autoLoad = moduleNode->valueAt("autoload", false); - m_reloadable = moduleNode->valueAt("reloadable", true); - m_sandboxed = moduleNode->valueAt("sandboxed", false); - m_autoLoadPriority = moduleNode->valueAt("autoload-priority", 9999); - - if(OTMLNodePtr node = moduleNode->get("dependencies")) { - for(const OTMLNodePtr& tmp : node->children()) - m_dependencies.push_back(tmp->value()); - } - - if(OTMLNodePtr node = moduleNode->get("scripts")) { - for(const OTMLNodePtr& tmp : node->children()) - m_scripts.push_back(stdext::resolve_path(tmp->value(), node->source())); - } - - if(OTMLNodePtr node = moduleNode->get("load-later")) { - for(const OTMLNodePtr& tmp : node->children()) - m_loadLaterModules.push_back(tmp->value()); - } - - if(OTMLNodePtr node = moduleNode->get("@onLoad")) - m_onLoadFunc = std::make_tuple(node->value(), "@" + node->source() + ":[" + node->tag() + "]"); - - if(OTMLNodePtr node = moduleNode->get("@onUnload")) - m_onUnloadFunc = std::make_tuple(node->value(), "@" + node->source() + ":[" + node->tag() + "]"); -} diff --git a/src/framework/core/module.h b/src/framework/core/module.h deleted file mode 100644 index de45447..0000000 --- a/src/framework/core/module.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MODULE_H -#define MODULE_H - -#include "declarations.h" - -#include -#include - -// @bindclass -class Module : public LuaObject -{ -public: - Module(const std::string& name); - - bool load(); - void unload(); - bool reload(); - - bool canUnload() { return m_loaded && m_reloadable && !isDependent(); } - bool canReload() { return m_reloadable && !isDependent(); } - bool isLoaded() { return m_loaded; } - bool isReloadable() { return m_reloadable; } - bool isDependent(); - bool isSandboxed() { return m_sandboxed; } - bool hasDependency(const std::string& name, bool recursive = false); - int getSandbox(LuaInterface *lua); - - std::string getDescription() { return m_description; } - std::string getName() { return m_name; } - std::string getAuthor() { return m_author; } - std::string getWebsite() { return m_website; } - std::string getVersion() { return m_version; } - bool isAutoLoad() { return m_autoLoad; } - int getAutoLoadPriority() { return m_autoLoadPriority; } - - // @dontbind - ModulePtr asModule() { return static_self_cast(); } - -protected: - void discover(const OTMLNodePtr& moduleNode); - friend class ModuleManager; - -private: - stdext::boolean m_loaded; - stdext::boolean m_autoLoad; - stdext::boolean m_reloadable; - stdext::boolean m_sandboxed; - bool m_loadedOnStartup = false; - int m_autoLoadPriority; - int m_sandboxEnv; - std::tuple m_onLoadFunc; - std::tuple m_onUnloadFunc; - std::string m_name; - std::string m_description; - std::string m_author; - std::string m_website; - std::string m_version; - std::function m_loadCallback; - std::function m_unloadCallback; - std::list m_dependencies; - std::list m_scripts; - std::list m_loadLaterModules; -}; - -#endif diff --git a/src/framework/core/modulemanager.cpp b/src/framework/core/modulemanager.cpp deleted file mode 100644 index c62425e..0000000 --- a/src/framework/core/modulemanager.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "modulemanager.h" -#include "resourcemanager.h" - -#include -#include -#include - -ModuleManager g_modules; - -void ModuleManager::clear() -{ - m_modules.clear(); - m_autoLoadModules.clear(); -} - -void ModuleManager::discoverModules() -{ - // remove modules that are not loaded - m_autoLoadModules.clear(); - - auto dirs = g_resources.listDirectoryFiles("/modules", true); - std::list modules; - for (auto& dir : dirs) { - auto subFilesAndDirs = g_resources.listDirectoryFiles(dir, true); - modules.insert(modules.end(), subFilesAndDirs.begin(), subFilesAndDirs.end()); - } - - dirs = g_resources.listDirectoryFiles("/mods", true); - for (auto& dir : dirs) { - auto subFilesAndDirs = g_resources.listDirectoryFiles(dir, true); - modules.insert(modules.end(), subFilesAndDirs.begin(), subFilesAndDirs.end()); - } - - for (auto& mod : modules) { - if (g_resources.isFileType(mod, "otmod")) { - ModulePtr module = discoverModule(mod); - if (module && module->isAutoLoad()) - m_autoLoadModules.insert(std::make_pair(module->getAutoLoadPriority(), module)); - } - } -} - -void ModuleManager::autoLoadModules(int maxPriority) -{ - for(auto& pair : m_autoLoadModules) { - int priority = pair.first; - if(priority > maxPriority) - break; - ModulePtr module = pair.second; - module->load(); - } -} - -ModulePtr ModuleManager::discoverModule(const std::string& moduleFile) -{ - ModulePtr module; - try { - OTMLDocumentPtr doc = OTMLDocument::parse(moduleFile); - OTMLNodePtr moduleNode = doc->at("Module"); - - std::string name = moduleNode->valueAt("name"); - - bool push = false; - module = getModule(name); - if(!module) { - module = ModulePtr(new Module(name)); - push = true; - } - module->discover(moduleNode); - - // not loaded modules are always in back - if(push) - m_modules.push_back(module); - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Unable to discover module from file '%s': %s", moduleFile, e.what())); - } - return module; -} - -void ModuleManager::ensureModuleLoaded(const std::string& moduleName) -{ - ModulePtr module = g_modules.getModule(moduleName); - if(!module || !module->load()) - g_logger.fatal(stdext::format("Unable to load '%s' module", moduleName)); -} - -void ModuleManager::unloadModules() -{ - auto modulesBackup = m_modules; - for(const ModulePtr& module : modulesBackup) - module->unload(); -} - -void ModuleManager::reloadModules() -{ - std::deque toLoadList; - - // unload in the reverse direction, try to unload upto 10 times (because of dependencies) - for(int i=0;i<10;++i) { - auto modulesBackup = m_modules; - for(const ModulePtr& module : modulesBackup) { - if(module->isLoaded() && module->canUnload()) { - module->unload(); - toLoadList.push_front(module); - } - } - } - - for(const ModulePtr& module : toLoadList) - module->load(); -} - -ModulePtr ModuleManager::getModule(const std::string& moduleName) -{ - for(const ModulePtr& module : m_modules) - if(module->getName() == moduleName) - return module; - return nullptr; -} - -void ModuleManager::updateModuleLoadOrder(ModulePtr module) -{ - auto it = std::find(m_modules.begin(), m_modules.end(), module); - if(it != m_modules.end()) - m_modules.erase(it); - if(module->isLoaded()) - m_modules.push_front(module); - else - m_modules.push_back(module); -} diff --git a/src/framework/core/modulemanager.h b/src/framework/core/modulemanager.h deleted file mode 100644 index 3651c1d..0000000 --- a/src/framework/core/modulemanager.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MODULEMANAGER_H -#define MODULEMANAGER_H - -#include "module.h" - -// @bindsingleton g_modules -class ModuleManager -{ -public: - void clear(); - - void discoverModules(); - void autoLoadModules(int maxPriority); - ModulePtr discoverModule(const std::string& moduleFile); - void ensureModuleLoaded(const std::string& moduleName); - void unloadModules(); - void reloadModules(); - - ModulePtr getModule(const std::string& moduleName); - std::deque getModules() { return m_modules; } - -protected: - void updateModuleLoadOrder(ModulePtr module); - - friend class Module; - -private: - std::deque m_modules; - std::multimap m_autoLoadModules; -}; - -extern ModuleManager g_modules; - -#endif diff --git a/src/framework/core/scheduledevent.cpp b/src/framework/core/scheduledevent.cpp deleted file mode 100644 index 96c7516..0000000 --- a/src/framework/core/scheduledevent.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "scheduledevent.h" - -ScheduledEvent::ScheduledEvent(const std::string& function, const std::function& callback, int delay, int maxCycles, bool botSafe) : Event(function, callback, botSafe) -{ - m_ticks = g_clock.millis() + delay; - m_delay = delay; - m_maxCycles = maxCycles; - m_cyclesExecuted = 0; -} - -void ScheduledEvent::execute() -{ - if(!m_canceled && m_callback && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) { - m_callback(); - m_executed = true; - // callback may be used in the next cycle - } else { - // reset callback to free object refs - m_callback = nullptr; - } - - m_cyclesExecuted++; -} - -bool ScheduledEvent::nextCycle() -{ - if(m_callback && !m_canceled && (m_maxCycles == 0 || m_cyclesExecuted < m_maxCycles)) { - m_ticks += m_delay; - return true; - } - - // reset callback to free object refs - m_callback = nullptr; - return false; -} diff --git a/src/framework/core/scheduledevent.h b/src/framework/core/scheduledevent.h deleted file mode 100644 index 8111701..0000000 --- a/src/framework/core/scheduledevent.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SCHEDULEDEVENT_H -#define SCHEDULEDEVENT_H - -#include -#include "event.h" -#include "clock.h" - -// @bindclass -class ScheduledEvent : public Event -{ -public: - ScheduledEvent(const std::string& function, const std::function& callback, int delay, int maxCycles, bool botSafe = false); - void execute(); - bool nextCycle(); - - int ticks() { return m_ticks; } - int remainingTicks() { return m_ticks - g_clock.millis(); } - int delay() { return m_delay; } - int cyclesExecuted() { return m_cyclesExecuted; } - int maxCycles() { return m_maxCycles; } - -private: - ticks_t m_ticks; - int m_delay; - int m_maxCycles; - int m_cyclesExecuted; -}; - -struct lessScheduledEvent { - bool operator()(const ScheduledEventPtr& a, const ScheduledEventPtr& b) { - return b->ticks() < a->ticks(); - } -}; - -#endif diff --git a/src/framework/core/timer.cpp b/src/framework/core/timer.cpp deleted file mode 100644 index da7d589..0000000 --- a/src/framework/core/timer.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#include "timer.h" -#include "clock.h" - -void Timer::restart() -{ - m_startTicks = g_clock.millis(); - m_stopped = false; -} - -ticks_t Timer::ticksElapsed() -{ - return g_clock.millis() - m_startTicks; -} diff --git a/src/framework/core/timer.h b/src/framework/core/timer.h deleted file mode 100644 index 28035b3..0000000 --- a/src/framework/core/timer.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef TIMER_H -#define TIMER_H - -#include - -class Timer -{ -public: - Timer() { restart(); } - - void restart(); - void stop() { m_stopped = true; } - void adjust(ticks_t value) { m_startTicks += value; } - - ticks_t startTicks() { return m_startTicks; } - ticks_t ticksElapsed(); - float timeElapsed() { return ticksElapsed()/1000.0f; } - - bool running() { return !m_stopped; } - -private: - ticks_t m_startTicks; - stdext::boolean m_stopped; -}; - -#endif diff --git a/src/framework/global.h b/src/framework/global.h deleted file mode 100644 index 0b5abad..0000000 --- a/src/framework/global.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FRAMEWORK_GLOBAL_H -#define FRAMEWORK_GLOBAL_H - -#include "stdext/compiler.h" - -// common C/C++ headers -#include "pch.h" - -// error handling -#if defined(NDEBUG) -#define VALIDATE(expression) ((void)0) -#else -extern void fatalError(const char* error, const char* file, int line); -#define VALIDATE(expression) { if(!(expression)) fatalError(#expression, __FILE__, __LINE__); }; -#endif - - -// global constants -#include "const.h" - -// stdext which includes additional C++ algorithms -#include "stdext/stdext.h" - -// additional utilities -#include "util/point.h" -#include "util/color.h" -#include "util/rect.h" -#include "util/size.h" -#include "util/matrix.h" - -// logger -#include "core/logger.h" - -#endif diff --git a/src/framework/graphics/animatedtexture.cpp b/src/framework/graphics/animatedtexture.cpp deleted file mode 100644 index fb36c5d..0000000 --- a/src/framework/graphics/animatedtexture.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "animatedtexture.h" -#include "graphics.h" - -#include - -AnimatedTexture::AnimatedTexture(const Size& size, std::vector frames, std::vector framesDelay, bool buildMipmaps, bool compress) : - Texture(size) -{ - for(uint i=0;ibuildHardwareMipmaps(); - m_hasMipmaps = true; - return true; -} - -void AnimatedTexture::setSmooth(bool smooth) -{ - for(const TexturePtr& frame : m_frames) - frame->setSmooth(smooth); - m_smooth = smooth; -} - -void AnimatedTexture::setRepeat(bool repeat) -{ - for(const TexturePtr& frame : m_frames) - frame->setRepeat(repeat); - m_repeat = repeat; -} - -void AnimatedTexture::update() -{ - if (m_animTimer.ticksElapsed() >= m_framesDelay[m_currentFrame]) { - m_animTimer.restart(); - m_currentFrame = (m_currentFrame + 1) % m_frames.size(); - } - - m_frames[m_currentFrame]->update(); - m_id = m_frames[m_currentFrame]->getId(); - m_uniqueId = m_frames[m_currentFrame]->getUniqueId(); -} diff --git a/src/framework/graphics/animatedtexture.h b/src/framework/graphics/animatedtexture.h deleted file mode 100644 index 0bb7cc0..0000000 --- a/src/framework/graphics/animatedtexture.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef ANIMATEDTEXTURE_H -#define ANIMATEDTEXTURE_H - -#include "texture.h" -#include - -class AnimatedTexture : public Texture -{ -public: - AnimatedTexture(const Size& size, std::vector frames, std::vector framesDelay, bool buildMipmaps = false, bool compress = false); - virtual ~AnimatedTexture(); - - void replace(const ImagePtr& image) { } - void update(); - - virtual bool isAnimatedTexture() { return true; } - -protected: - virtual bool buildHardwareMipmaps(); - - virtual void setSmooth(bool smooth); - virtual void setRepeat(bool repeat); - -private: - std::vector m_frames; - std::vector m_framesDelay; - uint m_currentFrame; - Timer m_animTimer; -}; - -#endif diff --git a/src/framework/graphics/apngloader.cpp b/src/framework/graphics/apngloader.cpp deleted file mode 100644 index 3e67fac..0000000 --- a/src/framework/graphics/apngloader.cpp +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * Based on APNG Disassembler 2.3 - * - * Copyright (c) 2009 Max Stepin - * maxst at users.sourceforge.net - * - * GNU LGPL information - * -------------------- - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include "apngloader.h" -#include -#include -#include - -#if defined(_MSC_VER) && _MSC_VER >= 1300 -#define swap16(data) _byteswap_ushort(data) -#define swap32(data) _byteswap_ulong(data) -#elif __linux__ -#include -#define swap16(data) bswap_16(data) -#define swap32(data) bswap_32(data) -#else -#define swap16(data) (((data >> 8) & 255) | ((data & 255) << 8)) -#define swap32(data) ((swap16(data) << 16) | swap16(data >> 16)) -#endif - -#define PNG_ZBUF_SIZE 32768 - -#define PNG_DISPOSE_OP_NONE 0x00 -#define PNG_DISPOSE_OP_BACKGROUND 0x01 -#define PNG_DISPOSE_OP_PREVIOUS 0x02 - -#define PNG_BLEND_OP_SOURCE 0x00 -#define PNG_BLEND_OP_OVER 0x01 - -#define notabc(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) - -#define ROWBYTES(pixel_bits, width) \ -((pixel_bits) >= 8 ? \ -((width) * (((unsigned int)(pixel_bits)) >> 3)) : \ -(( ((width) * ((unsigned int)(pixel_bits))) + 7) >> 3) ) - -unsigned char png_sign[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - -int mask4[2]={240,15}; -int shift4[2]={4,0}; - -int mask2[4]={192,48,12,3}; -int shift2[4]={6,4,2,0}; - -int mask1[8]={128,64,32,16,8,4,2,1}; -int shift1[8]={7,6,5,4,3,2,1,0}; - -unsigned int keep_original = 1; -unsigned char pal[256][3]; -unsigned char trns[256]; -unsigned int palsize, trnssize; -unsigned int hasTRNS; -unsigned short trns1, trns2, trns3; - -unsigned int read32(std::istream& f1) -{ - unsigned char a, b, c, d; - f1.read((char*)&a, 1); - f1.read((char*)&b, 1); - f1.read((char*)&c, 1); - f1.read((char*)&d, 1); - return ((unsigned int)a<<24)+((unsigned int)b<<16)+((unsigned int)c<<8)+(unsigned int)d; -} - -unsigned short read16(std::istream& f1) -{ - unsigned char a, b; - f1.read((char*)&a, 1); - f1.read((char*)&b, 1); - return ((unsigned short)a<<8)+(unsigned short)b; -} - -unsigned short readshort(unsigned char * p) -{ - return ((unsigned short)(*p)<<8)+(unsigned short)(*(p+1)); -} - -void read_sub_row(unsigned char * row, unsigned int rowbytes, unsigned int bpp) -{ - unsigned int i; - - for (i=bpp; i>1; - for (i=bpp; i>1; - } - else - { - for (i=bpp; i>1; - } -} - -void read_paeth_row(unsigned char * row, unsigned char * prev_row, unsigned int rowbytes, unsigned int bpp) -{ - unsigned int i; - int a, b, c, pa, pb, pc, p; - - if (prev_row) - { - for (i=0; i>1] & mask4[i&1]) >> shift4[i&1]; a = 0xFF; if (hasTRNS && g==trns1) a = 0; *dp1++ = g*0x11; *dp2++ = (a<<24) + g*0x111111; } break; - case 2: for (i=0; i>2] & mask2[i&3]) >> shift2[i&3]; a = 0xFF; if (hasTRNS && g==trns1) a = 0; *dp1++ = g*0x55; *dp2++ = (a<<24) + g*0x555555; } break; - case 1: for (i=0; i>3] & mask1[i&7]) >> shift1[i&7]; a = 0xFF; if (hasTRNS && g==trns1) a = 0; *dp1++ = g*0xFF; *dp2++ = (a<<24) + g*0xFFFFFF; } break; - } - } - else /* PNG_BLEND_OP_OVER */ - { - switch (depth) - { - case 16: for (i=0; i>1] & mask4[i&1]) >> shift4[i&1]; if (g != trns1) { *dp1 = g*0x11; *dp2 = 0xFF000000+g*0x111111; } } break; - case 2: for (i=0; i>2] & mask2[i&3]) >> shift2[i&3]; if (g != trns1) { *dp1 = g*0x55; *dp2 = 0xFF000000+g*0x555555; } } break; - case 1: for (i=0; i>3] & mask1[i&7]) >> shift1[i&7]; if (g != trns1) { *dp1 = g*0xFF; *dp2 = 0xFF000000+g*0xFFFFFF; } } break; - } - } - - src += srcbytes; - dst1 += dstbytes1; - dst2 += dstbytes2; - } -} - -void compose2(unsigned char * dst1, unsigned int dstbytes1, unsigned char * dst2, unsigned int dstbytes2, unsigned char * src, unsigned int srcbytes, unsigned int w, unsigned int h, unsigned int bop, unsigned char depth) -{ - unsigned int i, j; - unsigned int r, g, b, a; - unsigned char * sp; - unsigned char * dp1; - unsigned int * dp2; - - for (j=0; j>1] & mask4[i&1]) >> shift4[i&1]; break; - case 2: col = (sp[i>>2] & mask2[i&3]) >> shift2[i&3]; break; - case 1: col = (sp[i>>3] & mask1[i&7]) >> shift1[i&7]; break; - } - - b = pal[col][0]; - g = pal[col][1]; - r = pal[col][2]; - a = trns[col]; - - if (bop == PNG_BLEND_OP_SOURCE) - { - *dp1++ = col; - *dp2++ = (a << 24) + (r << 16) + (g << 8) + b; - } - else /* PNG_BLEND_OP_OVER */ - { - if (a == 255) - { - *dp1++ = col; - *dp2++ = (a << 24) + (r << 16) + (g << 8) + b; - } - else - if (a != 0) - { - if ((a2 = (*dp2)>>24)) - { - keep_original = 0; - u = a*255; - v = (255-a)*a2; - al = 255*255-(255-a)*(255-a2); - b2 = ((*dp2)&255); - g2 = (((*dp2)>>8)&255); - r2 = (((*dp2)>>16)&255); - b = (b*u + b2*v)/al; - g = (g*u + g2*v)/al; - r = (r*u + r2*v)/al; - a = al/255; - } - *dp1++ = col; - *dp2++ = (a << 24) + (r << 16) + (g << 8) + b; - } - else - { - dp1++; - dp2++; - } - } - } - src += srcbytes; - dst1 += dstbytes1; - dst2 += dstbytes2; - } -} - -void compose4(unsigned char * dst, unsigned int dstbytes, unsigned char * src, unsigned int srcbytes, unsigned int w, unsigned int h, unsigned int bop, unsigned char depth) -{ - unsigned int i, j, step; - unsigned int g, a, g2, a2; - int u, v, al; - unsigned char * sp; - unsigned char * dp; - - step = (depth+7)/8; - - for (j=0; j>24)) - { - u = a*255; - v = (255-a)*a2; - al = 255*255-(255-a)*(255-a2); - b2 = ((*dp)&255); - g2 = (((*dp)>>8)&255); - r2 = (((*dp)>>16)&255); - b = (b*u + b2*v)/al; - g = (g*u + g2*v)/al; - r = (r*u + r2*v)/al; - a = al/255; - } - *dp++ = (a << 24) + (r << 16) + (g << 8) + b; - } - else - dp++; - } - } - src += srcbytes; - dst += dstbytes; - } -} - -int load_apng(std::stringstream& file, struct apng_data *apng) -{ - unsigned int i, j; - unsigned int rowbytes; - int imagesize, zbuf_size, zsize, trns_idx; - unsigned int len, chunk/*, crc, seq*/; - unsigned int w, h, w0, h0, x0, y0; - unsigned int frames, loops, first_frame, cur_frame; - unsigned int outrow1, outrow2, outimg1, outimg2; - unsigned short d1, d2; - unsigned char c, dop, bop; - unsigned char channels, depth, pixeldepth, bpp; - unsigned char coltype, compr, filter, interl; - z_stream zstream; - memset(apng, 0, sizeof(struct apng_data)); - - for (i=0; i<256; i++) - { - pal[i][0] = i; - pal[i][1] = i; - pal[i][2] = i; - trns[i] = 255; - } - - zstream.zalloc = Z_NULL; - zstream.zfree = Z_NULL; - zstream.opaque = Z_NULL; - inflateInit(&zstream); - - frames = 1; - first_frame = 0; - cur_frame = 0; - zsize = 0; - hasTRNS = 0; - trns_idx = -1; - x0 = 0; - y0 = 0; - loops = 0; - bop = PNG_BLEND_OP_SOURCE; - - unsigned char sig[8]; - unsigned char * pOut1; - unsigned char * pOut2; - unsigned char * pTemp; - unsigned char * pData; - unsigned char * pImg1; - unsigned char * pImg2; - unsigned char * pDst1; - unsigned char * pDst2; - unsigned short* frames_delay; - - file.read((char*)sig, 8); - if(!file.eof() && memcmp(sig, png_sign, 8) == 0) { - len = read32(file); - chunk = read32(file); - - if ((len == 13) && (chunk == 0x49484452)) /* IHDR */ - { - w = w0 = read32(file); - h = h0 = read32(file); - file.read((char*)&depth, 1); - file.read((char*)&coltype, 1); - file.read((char*)&compr, 1); - file.read((char*)&filter, 1); - file.read((char*)&interl, 1); - /*crc = */read32(file); - - channels = 1; - if (coltype == 2) - channels = 3; - else if (coltype == 4) - channels = 2; - else if (coltype == 6) - channels = 4; - - pixeldepth = depth*channels; - bpp = (pixeldepth + 7) >> 3; - rowbytes = ROWBYTES(pixeldepth, w); - - imagesize = (rowbytes + 1) * h; - zbuf_size = imagesize + ((imagesize + 7) >> 3) + ((imagesize + 63) >> 6) + 11; - - /* - * We'll render into 2 output buffers, first in original coltype, - * second in RGBA. - * - * It's better to try to keep the original coltype, but if dispose/blend - * operations will make it impossible, then we'll save RGBA version instead. - */ - - outrow1 = w*channels; /* output coltype = input coltype */ - outrow2 = w*4; /* output coltype = RGBA */ - outimg1 = h*outrow1; - outimg2 = h*outrow2; - - pOut1=(unsigned char *)malloc(outimg1); - pOut2=(unsigned char *)malloc(outimg2); - pTemp=(unsigned char *)malloc(imagesize); - pData=(unsigned char *)malloc(zbuf_size); - pImg1=pOut1; - pImg2=pOut2; - frames_delay = NULL; - - /* apng decoding - begin */ - memset(pOut1, 0, outimg1); - memset(pOut2, 0, outimg2); - - while (!file.eof()) - { - len = read32(file); - chunk = read32(file); - - if (chunk == 0x504C5445) /* PLTE */ - { - unsigned int col; - for (i=0; i= 0) memset(pDst1, trns_idx, w0); else keep_original = 0; break; - case 4: memset(pDst1, 0, w0*2); break; - case 6: memset(pDst2, 0, w0*4); break; - } - pDst1 += outrow1; - pDst2 += outrow2; - } - } - } - } - - /*seq = */read32(file); - w0 = read32(file); - h0 = read32(file); - x0 = read32(file); - y0 = read32(file); - d1 = read16(file); - d2 = read16(file); - file.read((char*)&dop, 1); - file.read((char*)&bop, 1); - /*crc = */read32(file); - - if(d2 == 0) - d2 = 100; - frames_delay[cur_frame] = (d1 * 1000)/d2; - - if (cur_frame == 0) - { - bop = PNG_BLEND_OP_SOURCE; - if (dop == PNG_DISPOSE_OP_PREVIOUS) - dop = PNG_DISPOSE_OP_BACKGROUND; - } - - if (!(coltype & 4) && !(hasTRNS)) - bop = PNG_BLEND_OP_SOURCE; - - rowbytes = ROWBYTES(pixeldepth, w0); - cur_frame++; - pImg1 += outimg1; - pImg2 += outimg2; - } - else if (chunk == 0x49444154) /* IDAT */ - { - file.read((char*)(pData + zsize), len); - zsize += len; - /*crc = */read32(file); - } - else if (chunk == 0x66644154) /* fdAT */ - { - /*seq = */read32(file); - len -= 4; - file.read((char*)(pData + zsize), len); - zsize += len; - /*crc = */read32(file); - } - else if (chunk == 0x49454E44) /* IEND */ - { - pDst1 = pImg1 + y0*outrow1 + x0*channels; - pDst2 = pImg2 + y0*outrow2 + x0*4; - unpack(zstream, pTemp, imagesize, pData, zsize, h0, rowbytes, bpp); - switch (coltype) - { - case 0: compose0(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break; - case 2: compose2(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break; - case 3: compose3(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break; - case 4: compose4(pDst1, outrow1, pTemp, rowbytes+1, w0, h0, bop, depth); break; - case 6: compose6( pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break; - } - break; - } - else - { - c = (unsigned char)(chunk>>24); - if (notabc(c)) break; - c = (unsigned char)((chunk>>16) & 0xFF); - if (notabc(c)) break; - c = (unsigned char)((chunk>>8) & 0xFF); - if (notabc(c)) break; - c = (unsigned char)(chunk & 0xFF); - if (notabc(c)) break; - - file.seekg(len, std::ios_base::cur); - /*crc = */read32(file); - } - } - /* apng decoding - end */ - - if (coltype == 0) - { - switch (depth) - { - case 4: trns[1] *= 0x11; break; - case 2: trns[1] *= 0x55; break; - case 1: trns[1] *= 0xFF; break; - } - } - - inflateEnd(&zstream); - - apng->bpp = channels; - apng->coltype = coltype; - apng->last_frame = cur_frame; - apng->first_frame = first_frame; - apng->height = h; - apng->width = w; - apng->num_frames = frames; - apng->num_plays = loops; - apng->frames_delay = frames_delay; - apng->pdata = pOut2; - apng->bpp = 4; - apng->coltype = 6; - - if(pData) - free(pData); - if(pTemp) - free(pTemp); - if(pOut1) - free(pOut1); - } else - return -1; - } else - return -1; - - return 0; -} - -void write_chunk(std::ostream& f, const char* name, unsigned char* data, unsigned int length) -{ - unsigned int crc = crc32(0, Z_NULL, 0); - unsigned int len = swap32(length); - - f.write((char*)&len, 4); - f.write(name, 4); - crc = crc32(crc, (const Bytef*)name, 4); - - if(data != NULL && length > 0) { - f.write((char*)data, length); - crc = crc32(crc, data, length); - } - - crc = swap32(crc); - f.write((char*)&crc, 4); -} - -void write_IDATs(std::ostream& f, unsigned char* data, unsigned int length, unsigned int idat_size) -{ - unsigned int z_cmf = data[0]; - - if((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) { - if(length >= 2) { - unsigned int z_cinfo = z_cmf >> 4; - unsigned int half_z_window_size = 1 << (z_cinfo + 7); - - while(idat_size <= half_z_window_size && half_z_window_size >= 256) { - z_cinfo--; - half_z_window_size >>= 1; - } - - z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - - if(data[0] != (unsigned char)z_cmf) { - data[0] = (unsigned char)z_cmf; - data[1] &= 0xe0; - data[1] += (unsigned char)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f); - } - } - } - - while(length > 0) { - unsigned int ds = length; - - if(ds > PNG_ZBUF_SIZE) - ds = PNG_ZBUF_SIZE; - - write_chunk(f, "IDAT", data, ds); - - data += ds; - length -= ds; - } -} - -void save_png(std::stringstream& f, unsigned int width, unsigned int height, int channels, unsigned char *pixels) -{ - unsigned int bpp = 4; - unsigned char coltype = 0; - - if(channels == 3) - coltype = 2; - else if (channels == 2) - coltype = 4; - else if (channels == 4) - coltype = 6; - - struct IHDR { - unsigned int mWidth; - unsigned int mHeight; - unsigned char mDepth; - unsigned char mColorType; - unsigned char mCompression; - unsigned char mFilterMethod; - unsigned char mInterlaceMethod; - } ihdr = { swap32(width), swap32(height), 8, coltype, 0, 0, 0 }; - - z_stream zstream1; - z_stream zstream2; - unsigned int i, j; - - unsigned int rowbytes = width * bpp; - unsigned int idat_size = (rowbytes + 1) * height; - unsigned int zbuf_size = idat_size + ((idat_size + 7) >> 3) + ((idat_size + 63) >> 6) + 11; - - unsigned char* row_buf = (unsigned char*)malloc(rowbytes + 1); - unsigned char* sub_row = (unsigned char*)malloc(rowbytes + 1); - unsigned char* up_row = (unsigned char*)malloc(rowbytes + 1); - unsigned char* avg_row = (unsigned char*)malloc(rowbytes + 1); - unsigned char* paeth_row = (unsigned char*)malloc(rowbytes + 1); - unsigned char* zbuf1 = (unsigned char*)malloc(zbuf_size); - unsigned char* zbuf2 = (unsigned char*)malloc(zbuf_size); - - if(!row_buf || !sub_row || !up_row || !avg_row || !paeth_row || !zbuf1 || !zbuf2) - return; - - row_buf[0] = 0; - sub_row[0] = 1; - up_row[0] = 2; - avg_row[0] = 3; - paeth_row[0] = 4; - - zstream1.data_type = Z_BINARY; - zstream1.zalloc = Z_NULL; - zstream1.zfree = Z_NULL; - zstream1.opaque = Z_NULL; - deflateInit2(&zstream1, 3, 8, 15, 8, Z_DEFAULT_STRATEGY); - - zstream2.data_type = Z_BINARY; - zstream2.zalloc = Z_NULL; - zstream2.zfree = Z_NULL; - zstream2.opaque = Z_NULL; - deflateInit2(&zstream2, 3, 8, 15, 8, Z_FILTERED); - - int a, b, c, pa, pb, pc, p, v; - unsigned char* prev; - unsigned char* row; - - f.write((char*)png_sign, 8); - write_chunk(f, "IHDR", (unsigned char*)(&ihdr), 13); - - if(palsize > 0) - write_chunk(f, "PLTE", (unsigned char*)(&pal), palsize * 3); - - if(trnssize > 0) - write_chunk(f, "tRNS", trns, trnssize); - - zstream1.next_out = zbuf1; - zstream1.avail_out = zbuf_size; - zstream2.next_out = zbuf2; - zstream2.avail_out = zbuf_size; - - prev = NULL; - row = pixels; - - for(j = 0; j < (unsigned int)height; j++) { - unsigned char* out; - unsigned int sum = 0; - unsigned char* best_row = row_buf; - unsigned int mins = ((unsigned int)(-1)) >> 1; - - out = row_buf + 1; - - for(i = 0; i < rowbytes; i++) { - v = out[i] = row[i]; - sum += (v < 128) ? v : 256 - v; - } - - mins = sum; - - sum = 0; - out = sub_row + 1; - - for(i = 0; i < bpp; i++) { - v = out[i] = row[i]; - sum += (v < 128) ? v : 256 - v; - } - - for(i = bpp; i < rowbytes; i++) { - v = out[i] = row[i] - row[i - bpp]; - sum += (v < 128) ? v : 256 - v; - - if(sum > mins) break; - } - - if(sum < mins) { - mins = sum; - best_row = sub_row; - } - - if(prev) { - sum = 0; - out = up_row + 1; - - for(i = 0; i < rowbytes; i++) { - v = out[i] = row[i] - prev[i]; - sum += (v < 128) ? v : 256 - v; - - if(sum > mins) break; - } - - if(sum < mins) { - mins = sum; - best_row = up_row; - } - - sum = 0; - out = avg_row + 1; - - for(i = 0; i < bpp; i++) { - v = out[i] = row[i] - prev[i] / 2; - sum += (v < 128) ? v : 256 - v; - } - - for(i = bpp; i < rowbytes; i++) { - v = out[i] = row[i] - (prev[i] + row[i - bpp]) / 2; - sum += (v < 128) ? v : 256 - v; - - if(sum > mins) break; - } - - if(sum < mins) { - mins = sum; - best_row = avg_row; - } - - sum = 0; - out = paeth_row + 1; - - for(i = 0; i < bpp; i++) { - v = out[i] = row[i] - prev[i]; - sum += (v < 128) ? v : 256 - v; - } - - for(i = bpp; i < rowbytes; i++) { - a = row[i - bpp]; - b = prev[i]; - c = prev[i - bpp]; - p = b - c; - pc = a - c; - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); - p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; - v = out[i] = row[i] - p; - sum += (v < 128) ? v : 256 - v; - - if(sum > mins) break; - } - - if(sum < mins) { - best_row = paeth_row; - } - } - - zstream1.next_in = row_buf; - zstream1.avail_in = rowbytes + 1; - deflate(&zstream1, Z_NO_FLUSH); - - zstream2.next_in = best_row; - zstream2.avail_in = rowbytes + 1; - deflate(&zstream2, Z_NO_FLUSH); - - prev = row; - row += rowbytes; - } - - deflate(&zstream1, Z_FINISH); - deflate(&zstream2, Z_FINISH); - - if(zstream1.total_out <= zstream2.total_out) - write_IDATs(f, zbuf1, zstream1.total_out, idat_size); - else - write_IDATs(f, zbuf2, zstream2.total_out, idat_size); - - deflateReset(&zstream1); - zstream1.data_type = Z_BINARY; - deflateReset(&zstream2); - zstream2.data_type = Z_BINARY; - - write_chunk(f, "IEND", 0, 0); - - deflateEnd(&zstream1); - deflateEnd(&zstream2); - free(zbuf1); - free(zbuf2); - free(row_buf); - free(sub_row); - free(up_row); - free(avg_row); - free(paeth_row); -} - -void free_apng(struct apng_data *apng) -{ - if(apng->pdata) - free(apng->pdata); - if(apng->frames_delay) - free(apng->frames_delay); -} - diff --git a/src/framework/graphics/apngloader.h b/src/framework/graphics/apngloader.h deleted file mode 100644 index 8ce5425..0000000 --- a/src/framework/graphics/apngloader.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef APNGLOADER_H -#define APNGLOADER_H - -#include - -struct apng_data { - unsigned char *pdata; - unsigned int width; - unsigned int height; - unsigned int first_frame; - unsigned int last_frame; - unsigned char bpp; - unsigned char coltype; - unsigned int num_frames; - unsigned int num_plays; - unsigned short *frames_delay; // each frame delay in ms -}; - -// returns -1 on error, 0 on success -int load_apng(std::stringstream& file, struct apng_data *apng); -void save_png(std::stringstream& file, unsigned int width, unsigned int height, int channels, unsigned char *pixels); -void free_apng(struct apng_data *apng); - -#endif diff --git a/src/framework/graphics/bitmapfont.cpp b/src/framework/graphics/bitmapfont.cpp deleted file mode 100644 index 47a422e..0000000 --- a/src/framework/graphics/bitmapfont.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "atlas.h" -#include "bitmapfont.h" -#include "texturemanager.h" -#include "graphics.h" -#include "image.h" - -#include -#include -#include - -void BitmapFont::load(const OTMLNodePtr& fontNode) -{ - OTMLNodePtr textureNode = fontNode->at("texture"); - std::string textureFile = stdext::resolve_path(textureNode->value(), textureNode->source()); - Size glyphSize = fontNode->valueAt("glyph-size"); - m_glyphHeight = fontNode->valueAt("height"); - m_yOffset = fontNode->valueAt("y-offset", 0); - m_firstGlyph = fontNode->valueAt("first-glyph", 32); - m_glyphSpacing = fontNode->valueAt("spacing", Size(0,0)); - int spaceWidth = fontNode->valueAt("space-width", glyphSize.width()); - - if(OTMLNodePtr node = fontNode->get("fixed-glyph-width")) { - for(int glyph = m_firstGlyph; glyph < 256; ++glyph) - m_glyphsSize[glyph] = Size(node->value(), m_glyphHeight); - } else { - calculateGlyphsWidthsAutomatically(Image::load(textureFile), glyphSize); - } - - // 32 is space - m_glyphsSize[32].setWidth(spaceWidth); - - // use 127 as spacer [Width: 1], Important for the current NPC highlighting system - m_glyphsSize[127].setWidth(1); - - // new line actually has a size that will be useful in multiline algorithm - m_glyphsSize[(uchar)'\n'] = Size(1, m_glyphHeight); - - // read custom widths - /* - if(OTMLNodePtr node = fontNode->get("glyph-widths")) { - for(const OTMLNodePtr& child : node->children()) - m_glyphsSize[stdext::safe_cast(child->tag())].setWidth(child->value()); - } - */ - - // load font texture - m_texture = g_textures.getTexture(textureFile); - if (!m_texture) - return; - - Point offset = g_atlas.cacheFont(m_texture); - int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width(); - for (int glyph = m_firstGlyph; glyph < 256; ++glyph) { - m_glyphsTextureCoords[glyph].setRect(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width() + offset.x, - ((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height() + offset.y, - m_glyphsSize[glyph].width(), - m_glyphHeight); - } - m_texture = g_atlas.get(1); -} - -void BitmapFont::drawText(const std::string& text, const Point& startPos, const Color& color) -{ - Size boxSize = g_painterNew->getResolution() - startPos.toSize(); - Rect screenCoords(startPos, boxSize); - drawText(text, screenCoords, Fw::AlignTopLeft); -} - -void BitmapFont::drawText(const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align, const Color& color) -{ - g_drawQueue->addText(static_self_cast(), text, screenCoords, align, color); -} - -void BitmapFont::drawColoredText(const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align, const std::vector>& colors) -{ - g_drawQueue->addColoredText(static_self_cast(), text, screenCoords, align, colors); -} - -void BitmapFont::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align) -{ - // prevent glitches from invalid rects - if (!screenCoords.isValid() || !m_texture) - return; - - int textLenght = text.length(); - - // map glyphs positions - Size textBoxSize; - const std::vector& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize); - - for (int i = 0; i < textLenght; ++i) { - int glyph = (uchar)text[i]; - - // skip invalid glyphs - if (glyph < 32) - continue; - - // calculate initial glyph rect and texture coords - Rect glyphScreenCoords(glyphsPositions[i], m_glyphsSize[glyph]); - Rect glyphTextureCoords = m_glyphsTextureCoords[glyph]; - - // first translate to align position - if (align & Fw::AlignBottom) { - glyphScreenCoords.translate(0, screenCoords.height() - textBoxSize.height()); - } else if (align & Fw::AlignVerticalCenter) { - glyphScreenCoords.translate(0, (screenCoords.height() - textBoxSize.height()) / 2); - } else { // AlignTop - // nothing to do - } - - if (align & Fw::AlignRight) { - glyphScreenCoords.translate(screenCoords.width() - textBoxSize.width(), 0); - } else if (align & Fw::AlignHorizontalCenter) { - glyphScreenCoords.translate((screenCoords.width() - textBoxSize.width()) / 2, 0); - } else { // AlignLeft - // nothing to do - } - - // only render glyphs that are after 0, 0 - if (glyphScreenCoords.bottom() < 0 || glyphScreenCoords.right() < 0) - continue; - - // bound glyph topLeft to 0,0 if needed - if (glyphScreenCoords.top() < 0) { - glyphTextureCoords.setTop(glyphTextureCoords.top() - glyphScreenCoords.top()); - glyphScreenCoords.setTop(0); - } - if (glyphScreenCoords.left() < 0) { - glyphTextureCoords.setLeft(glyphTextureCoords.left() - glyphScreenCoords.left()); - glyphScreenCoords.setLeft(0); - } - - // translate rect to screen coords - glyphScreenCoords.translate(screenCoords.topLeft()); - - // only render if glyph rect is visible on screenCoords - if (!screenCoords.intersects(glyphScreenCoords)) - continue; - - // bound glyph bottomRight to screenCoords bottomRight - if (glyphScreenCoords.bottom() > screenCoords.bottom()) { - glyphTextureCoords.setBottom(glyphTextureCoords.bottom() + (screenCoords.bottom() - glyphScreenCoords.bottom())); - glyphScreenCoords.setBottom(screenCoords.bottom()); - } - if (glyphScreenCoords.right() > screenCoords.right()) { - glyphTextureCoords.setRight(glyphTextureCoords.right() + (screenCoords.right() - glyphScreenCoords.right())); - glyphScreenCoords.setRight(screenCoords.right()); - } - - // render glyph - coordsBuffer.addRect(glyphScreenCoords, glyphTextureCoords); - } -} - -const std::vector& BitmapFont::calculateGlyphsPositions(const std::string& text, - Fw::AlignmentFlag align, - Size *textBoxSize) -{ - // for performance reasons we use statics vectors that are allocated on demand - static std::vector glyphsPositions(1); - static std::vector lineWidths(1); - - int textLength = text.length(); - int maxLineWidth = 0; - int lines = 0; - int glyph; - int i; - - // return if there is no text - if(textLength == 0) { - if(textBoxSize) - textBoxSize->resize(0,m_glyphHeight); - return glyphsPositions; - } - - // resize glyphsPositions vector when needed - if(textLength > (int)glyphsPositions.size()) - glyphsPositions.resize(textLength); - - // calculate lines width - if((align & Fw::AlignRight || align & Fw::AlignHorizontalCenter) || textBoxSize) { - lineWidths[0] = 0; - for(i = 0; i< textLength; ++i) { - glyph = (uchar)text[i]; - - if(glyph == (uchar)'\n') { - lines++; - if(lines+1 > (int)lineWidths.size()) - lineWidths.resize(lines+1); - lineWidths[lines] = 0; - } else if(glyph >= 32) { - lineWidths[lines] += m_glyphsSize[glyph].width() ; - if((i+1 != textLength && text[i+1] != '\n')) // only add space if letter is not the last or before a \n. - lineWidths[lines] += m_glyphSpacing.width(); - maxLineWidth = std::max(maxLineWidth, lineWidths[lines]); - } - } - } - - Point virtualPos(0, m_yOffset); - lines = 0; - for(i = 0; i < textLength; ++i) { - glyph = (uchar)text[i]; - - // new line or first glyph - if(glyph == (uchar)'\n' || i == 0) { - if(glyph == (uchar)'\n') { - virtualPos.y += m_glyphHeight + m_glyphSpacing.height(); - lines++; - } - - // calculate start x pos - if(align & Fw::AlignRight) { - virtualPos.x = (maxLineWidth - lineWidths[lines]); - } else if(align & Fw::AlignHorizontalCenter) { - virtualPos.x = (maxLineWidth - lineWidths[lines]) / 2; - } else { // AlignLeft - virtualPos.x = 0; - } - } - - // store current glyph topLeft - glyphsPositions[i] = virtualPos; - - // render only if the glyph is valid - if(glyph >= 32 && glyph != (uchar)'\n') { - virtualPos.x += m_glyphsSize[glyph].width() + m_glyphSpacing.width(); - } - } - - if(textBoxSize) { - textBoxSize->setWidth(maxLineWidth); - textBoxSize->setHeight(virtualPos.y + m_glyphHeight); - } - - return glyphsPositions; -} - -Size BitmapFont::calculateTextRectSize(const std::string& text) -{ - Size size; - calculateGlyphsPositions(text, Fw::AlignTopLeft, &size); - return size; -} - -std::string BitmapFont::wrapText(const std::string& text, int maxWidth, std::vector>* colors) -{ - std::string outText; - outText.reserve(text.size() * 2); // string append optimization - - int lastSeparator = 0, lineLength = 0, wordLength = 0; - for (size_t i = 0; i < text.size(); ++i) { - uchar glyph = (uchar)text[i]; - if (text[i] == '\n' || text[i] == ' ') { - lineLength += wordLength; - if (lineLength > maxWidth) { // too long line with this word - if (text[lastSeparator] == ' ') { - lastSeparator += 1; - updateColors(colors, outText.size(), -1); - } - outText += '\n'; - lineLength = wordLength; - } - for (size_t j = lastSeparator; j < i; ++j) { // copy word - outText += text[j]; - } - if (text[i] == '\n') { // if new line was added reset line length - outText += '\n'; - wordLength = 0; - lineLength = 0; - lastSeparator = i + 1; - } else { // space - wordLength = m_glyphsSize[glyph].width() + m_glyphSpacing.width(); // space - lastSeparator = i; - } - continue; - } - - if (glyph < 32) // invalid character - continue; - - wordLength += m_glyphsSize[glyph].width() + m_glyphSpacing.width(); - if (wordLength > maxWidth) { // too long word, split it - if (lineLength != 0) { // add new line if current one is not empty - outText += '\n'; - } - if (text[lastSeparator] == ' ') // ignore space if it's first character in new line - lastSeparator += 1; - for (size_t j = lastSeparator; j < i; ++j) { // copy word - outText += text[j]; - } - updateColors(colors, outText.size(), 1); - outText += '-'; // word continuation - outText += '\n'; // new line - - wordLength = m_glyphsSize[glyph].width() + m_glyphSpacing.width(); - lineLength = 0; - lastSeparator = i; - } - } - - lineLength += wordLength; - if (lineLength > maxWidth) { // too long line with this word - updateColors(colors, outText.size(), 1); - outText += '\n'; - lineLength = wordLength; - } - for (size_t j = lastSeparator; j < text.size(); ++j) { // copy word - outText += text[j]; - } - return outText; -} - -void BitmapFont::calculateGlyphsWidthsAutomatically(const ImagePtr& image, const Size& glyphSize) -{ - if (!image) - return; - - int numHorizontalGlyphs = image->getSize().width() / glyphSize.width(); - auto texturePixels = image->getPixels(); - - // small AI to auto calculate pixels widths - for (int glyph = m_firstGlyph; glyph < 256; ++glyph) { - Rect glyphCoords(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(), - ((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(), - glyphSize.width(), - m_glyphHeight); - int width = glyphSize.width(); - for (int x = glyphCoords.left(); x <= glyphCoords.right(); ++x) { - int filledPixels = 0; - // check if all vertical pixels are alpha - for (int y = glyphCoords.top(); y <= glyphCoords.bottom(); ++y) { - if (texturePixels[(y * image->getSize().width() * 4) + (x * 4) + 3] != 0) - filledPixels++; - } - if (filledPixels > 0) - width = x - glyphCoords.left() + 1; - } - // store glyph size - m_glyphsSize[glyph].resize(width, m_glyphHeight); - } -} - -void BitmapFont::updateColors(std::vector>* colors, int pos, int newTextLen) -{ - if (!colors) return; - for (auto& it : *colors) { - if (it.first >= pos) { - it.first += newTextLen; - } - } -} diff --git a/src/framework/graphics/bitmapfont.h b/src/framework/graphics/bitmapfont.h deleted file mode 100644 index ed605c8..0000000 --- a/src/framework/graphics/bitmapfont.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef BITMAPFONT_H -#define BITMAPFONT_H - -#include "declarations.h" -#include "texture.h" - -#include -#include - -class BitmapFont : public stdext::shared_object -{ -public: - BitmapFont(const std::string& name) : m_name(name) { - static int id = 1; - m_id = id++; - } - - /// Load font from otml node - void load(const OTMLNodePtr& fontNode); - - /// Simple text render starting at startPos - void drawText(const std::string& text, const Point& startPos, const Color& color = Color::white); - - /// Advanced text render delimited by a screen region and alignment - void drawText(const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align = Fw::AlignTopLeft, const Color& color = Color::white); - void drawColoredText(const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align, const std::vector>& colors); - - void calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align = Fw::AlignTopLeft); - - /// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted - const std::vector& calculateGlyphsPositions(const std::string& text, - Fw::AlignmentFlag align = Fw::AlignTopLeft, - Size* textBoxSize = NULL); - - /// Simulate render and calculate text size - Size calculateTextRectSize(const std::string& text); - - std::string wrapText(const std::string& text, int maxWidth, std::vector>* colors = nullptr); - - int getId() { return m_id; } - std::string getName() { return m_name; } - int getGlyphHeight() { return m_glyphHeight; } - const Rect* getGlyphsTextureCoords() { return m_glyphsTextureCoords; } - const Size* getGlyphsSize() { return m_glyphsSize; } - const TexturePtr& getTexture() { return m_texture; } - int getYOffset() { return m_yOffset; } - Size getGlyphSpacing() { return m_glyphSpacing; } - -private: - /// Calculates each font character by inspecting font bitmap - void calculateGlyphsWidthsAutomatically(const ImagePtr& image, const Size& glyphSize); - void updateColors(std::vector>* colors, int pos, int newTextLen); - - std::string m_name; - int m_glyphHeight; - int m_firstGlyph; - int m_yOffset; - int m_id; - Size m_glyphSpacing; - TexturePtr m_texture; - Rect m_glyphsTextureCoords[256]; - Size m_glyphsSize[256]; -}; - - -#endif - diff --git a/src/framework/graphics/cachedtext.cpp b/src/framework/graphics/cachedtext.cpp deleted file mode 100644 index 7bb58f5..0000000 --- a/src/framework/graphics/cachedtext.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "cachedtext.h" -#include "painter.h" -#include "fontmanager.h" -#include "bitmapfont.h" - -CachedText::CachedText() -{ - m_font = g_fonts.getDefaultFont(); - m_align = Fw::AlignCenter; -} - -void CachedText::draw(const Rect& rect, const Color& color) -{ - if(!m_font) - return; - - if(m_textMustRecache || m_textCachedScreenCoords != rect) { - m_textMustRecache = false; - m_textCachedScreenCoords = rect; - } - - if (m_textColors.empty()) { - m_font->drawText(m_text, m_textCachedScreenCoords, Fw::AlignCenter, color); - } else { - m_font->drawColoredText(m_text, m_textCachedScreenCoords, Fw::AlignCenter, m_textColors); - } -} - -void CachedText::setColoredText(const std::vector& texts) -{ - m_text = ""; - m_textColors.clear(); - for (size_t i = 0, p = 0; i < texts.size() - 1; i += 2) { - Color c(Color::white); - stdext::cast(texts[i + 1], c); - m_text += texts[i]; - for (auto& c : texts[i]) { - if ((uint8)c >= 32) - p += 1; - } - m_textColors.push_back(std::make_pair(p, c)); - } - update(); -} - -void CachedText::update() -{ - if(m_font) - m_textSize = m_font->calculateTextRectSize(m_text); - m_textMustRecache = true; -} - -void CachedText::wrapText(int maxWidth) -{ - if(m_font) { - m_text = m_font->wrapText(m_text, maxWidth, m_textColors.empty() ? nullptr : &m_textColors); - update(); - } -} diff --git a/src/framework/graphics/cachedtext.h b/src/framework/graphics/cachedtext.h deleted file mode 100644 index e52d4bb..0000000 --- a/src/framework/graphics/cachedtext.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CACHEDTEXT_H -#define CACHEDTEXT_H - -#include "declarations.h" -#include "coordsbuffer.h" -#include "drawqueue.h" - -class CachedText -{ -public: - CachedText(); - - void draw(const Rect& rect, const Color& color); - - void wrapText(int maxWidth); - void setFont(const BitmapFontPtr& font) { m_font = font; update(); } - void setText(const std::string& text) { m_textColors.clear(); m_text = text; update(); } - void setColoredText(const std::vector& texts); - void setAlign(Fw::AlignmentFlag align) { m_align = align; update(); } - - Size getTextSize() { return m_textSize; } - std::string getText() const { return m_text; } - BitmapFontPtr getFont() const { return m_font; } - Fw::AlignmentFlag getAlign() { return m_align; } - - bool hasText() { return !m_text.empty(); } - -private: - void update(); - - std::string m_text; - std::vector> m_textColors; - Size m_textSize; - stdext::boolean m_textMustRecache; - Rect m_textCachedScreenCoords; - BitmapFontPtr m_font; - Fw::AlignmentFlag m_align; -}; - -#endif diff --git a/src/framework/graphics/drawcache.cpp b/src/framework/graphics/drawcache.cpp deleted file mode 100644 index 03432bf..0000000 --- a/src/framework/graphics/drawcache.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "drawcache.h" - -DrawCache g_drawCache; - -void DrawCache::draw() -{ - release(); - if (m_size == 0) return; - g_painterNew->drawCache(m_destCoord, m_srcCoord, m_color, m_size); - m_size = 0; -} - -void DrawCache::bind() -{ - if (m_bound) return; - g_atlas.bind(); - m_bound = true; -} - -void DrawCache::release() -{ - if (!m_bound) return; - g_atlas.release(); - m_bound = false; -} - -void DrawCache::addRect(const Rect& dest, const Color& color) -{ - static Rect emptyRect(Point(-10, -10), Point(-10, -10)); - addRectRaw(m_destCoord.data() + (m_size * 2), dest); - addRectRaw(m_srcCoord.data() + (m_size * 2), emptyRect); - addColorRaw(color, 6); - m_size += 6; -} - -void DrawCache::addTexturedRect(const Rect& dest, const Rect& src, const Color& color) -{ - addRectRaw(m_destCoord.data() + (m_size * 2), dest); - addRectRaw(m_srcCoord.data() + (m_size * 2), src); - addColorRaw(color, 6); - m_size += 6; -} - -void DrawCache::addCoords(CoordsBuffer& coords, const Color& color) -{ - int size = coords.getVertexCount(); - memcpy(m_destCoord.data() + m_size * 2, coords.getVertexArray(), size * 2 * sizeof(float)); - for (int start = m_size * 2, end = (m_size + size) * 2; start < end; ++start) - m_srcCoord[start] = -10; - addColorRaw(color, size); - m_size += size; -} - -void DrawCache::addTexturedCoords(CoordsBuffer& coords, const Point& offset, const Color& color) -{ - int size = coords.getVertexCount(); - float* src = coords.getTextureCoordArray(); - memcpy(m_destCoord.data() + m_size * 2, coords.getVertexArray(), size * 2 * sizeof(float)); - for (int i = m_size * 2, j = 0, end = (m_size + size) * 2; i < end; ) { - m_srcCoord[i++] = src[j++] + offset.x; - m_srcCoord[i++] = src[j++] + offset.y; - } - addColorRaw(color, size); - m_size += size; -} diff --git a/src/framework/graphics/drawcache.h b/src/framework/graphics/drawcache.h deleted file mode 100644 index dbc6ee6..0000000 --- a/src/framework/graphics/drawcache.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef DRAW_CACHE -#define DRAW_CACHE - -#include "atlas.h" -#include "coordsbuffer.h" -#include "graphics.h" -#include "painter.h" - -class DrawCache { -public: - static const int MAX_SIZE = 65536; - static const int HALF_MAX_SIZE = MAX_SIZE / 2; - - void draw(); - void bind(); - void release(); - bool hasSpace(int size) { - return size + m_size < MAX_SIZE; - } - inline int getSize() { return m_size; } - void addRect(const Rect& dest, const Color& color); - void addTexturedRect(const Rect& dest, const Rect& src, const Color& color); - void addCoords(CoordsBuffer& coords, const Color& color); - void addTexturedCoords(CoordsBuffer& coords, const Point& offset, const Color& color); - -private: - inline void addRectRaw(float* dest, const Rect& rect) - { - dest[0] = dest[4] = dest[6] = rect.left(); - dest[1] = dest[3] = dest[9] = rect.top(); - dest[2] = dest[8] = dest[10] = rect.right() + 1; - dest[5] = dest[7] = dest[11] = rect.bottom() + 1; - } - inline void addColorRaw(const Color& color, int count) - { - static float c[4]; - c[0] = color.rF(); - c[1] = color.gF(); - c[2] = color.bF(); - c[3] = color.aF(); - for (int start = m_size * 4, end = (m_size + count) * 4; start < end; start += 4) { - memcpy(m_color.data() + start, c, 4 * sizeof(float)); - } - } - - std::vector m_destCoord = std::vector(MAX_SIZE * 2); - std::vector m_srcCoord = std::vector(MAX_SIZE * 2); - std::vector m_color = std::vector(MAX_SIZE * 4); - bool m_bound = false; - int m_size = 0; -}; - -extern DrawCache g_drawCache; - -#endif diff --git a/src/framework/graphics/drawqueue.h b/src/framework/graphics/drawqueue.h deleted file mode 100644 index b64bec5..0000000 --- a/src/framework/graphics/drawqueue.h +++ /dev/null @@ -1,300 +0,0 @@ -#ifndef DRAWQUEUE_H -#define DRAWQUEUE_H - -#include -#include -#include -#include -#include -#include -#include -#include - -class DrawQueue; -struct DrawQueueItem; - -enum DrawType : uint8_t { - DRAW_ALL = 0, - DRAW_BEFORE_MAP = 1, - DRAW_AFTER_MAP = 2 -}; - -struct DrawQueueItem { - DrawQueueItem(const TexturePtr& texture, const Color& color = Color::white) : - m_texture(texture), m_color(color) {} - virtual ~DrawQueueItem() {}; - virtual void draw() {} - virtual void draw(const Point& pos) {} - virtual bool cache() { return false; } - - TexturePtr m_texture; - Color m_color; -}; - -struct DrawQueueItemTexturedRect : public DrawQueueItem { - DrawQueueItemTexturedRect() : DrawQueueItem(nullptr) {} - DrawQueueItemTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color) : - DrawQueueItem(texture, color), m_dest(dest), m_src(src) {}; - - virtual void draw(); - virtual void draw(const Point& pos); - virtual bool cache(); - - Rect m_dest; - Rect m_src; -}; - -struct DrawQueueItemTextureCoords : public DrawQueueItem { - DrawQueueItemTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture, const Color& color) : - DrawQueueItem(texture, color), m_coordsBuffer(std::move(coordsBuffer)) {}; - - void draw(); - void draw(const Point& pos); - bool cache(); - - CoordsBuffer m_coordsBuffer; -}; - -struct DrawQueueItemFilledRect : public DrawQueueItem { - DrawQueueItemFilledRect(const Rect& rect, const Color& color) : - DrawQueueItem(nullptr, color), m_dest(rect) {}; - bool cache(); - - Rect m_dest; -}; - -struct DrawQueueItemClearRect : public DrawQueueItem { - DrawQueueItemClearRect(const Rect& rect, const Color& color) : - DrawQueueItem(nullptr, color), m_dest(rect) - {}; - void draw(); - - Rect m_dest; -}; - -struct DrawQueueItemFillCoords : public DrawQueueItem { - DrawQueueItemFillCoords(CoordsBuffer& coordsBuffer, const Color& color) : - DrawQueueItem(nullptr, color), m_coordsBuffer(std::move(coordsBuffer)) - {}; - bool cache(); - - CoordsBuffer m_coordsBuffer; -}; - -struct DrawQueueItemText : public DrawQueueItem { - DrawQueueItemText(const Point& point, const TexturePtr& texture, uint64_t hash, const Color& color) : - DrawQueueItem(texture, color), m_point(point), m_hash(hash) - {}; - void draw(); - - Point m_point; - uint64_t m_hash; -}; - -struct DrawQueueItemTextColored : public DrawQueueItem { - DrawQueueItemTextColored(const Point& point, const TexturePtr& texture, uint64_t hash, const std::vector>& colors) : - DrawQueueItem(texture), m_point(point), m_hash(hash), m_colors(colors) - {}; - void draw(); - - Point m_point; - uint64_t m_hash; - std::vector> m_colors; -}; - -struct DrawQueueItemOutfit : public DrawQueueItemTexturedRect { - DrawQueueItemOutfit(const Rect& rect, const TexturePtr& texture, const Rect& src, const Point& offset, int32_t colors, const Color& color) : - DrawQueueItemTexturedRect(rect, texture, src, color), m_offset(offset), m_colors(colors) - { }; - - void draw(const Point& pos) override; - bool cache() override; - - Point m_offset; - int32_t m_colors; -}; - -struct DrawQueueCondition { - DrawQueueCondition(size_t start, size_t end) : - m_start(start), m_end(end) {} - virtual ~DrawQueueCondition() = default; - - virtual void start(DrawQueue*) = 0; - virtual void end(DrawQueue*) = 0; - - size_t m_start; - size_t m_end; -}; - -struct DrawQueueConditionClip : public DrawQueueCondition { - DrawQueueConditionClip(size_t start, size_t end, const Rect& rect) : - DrawQueueCondition(start, end), m_rect(rect) {} - - void start(DrawQueue* queue) override; - void end(DrawQueue* queue) override; - - Rect m_rect; - Rect m_prevClip; -}; - -struct DrawQueueConditionRotation : public DrawQueueCondition { - DrawQueueConditionRotation(size_t start, size_t end, const Point& center, float angle) : - DrawQueueCondition(start, end), m_center(center), m_angle(angle) {} - - void start(DrawQueue* queue) override; - void end(DrawQueue* queue) override; - - Point m_center; - float m_angle; -}; - -struct DrawQueueConditionMark : public DrawQueueCondition { - DrawQueueConditionMark(size_t start, size_t end, const Color& color) : - DrawQueueCondition(start, end), m_color(color) - {} - - void start(DrawQueue* queue) override; - void end(DrawQueue* queue) override; - - Color m_color; -}; - -class DrawQueue { -public: - DrawQueue() = default; - DrawQueue(const DrawQueue&) = delete; - DrawQueue& operator= (const DrawQueue&) = delete; - ~DrawQueue() { - for (auto& item : m_queue) - delete item; - m_queue.clear(); - for (auto& condition : m_conditions) - delete condition; - m_conditions.clear(); - } - - void draw(DrawType drawType = DRAW_ALL); - - void add(DrawQueueItem* item) - { - m_queue.push_back(item); - } - DrawQueueItemTexturedRect* addTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color = Color::white) - { - DrawQueueItemTexturedRect* item(new DrawQueueItemTexturedRect(dest, texture, src, color)); - m_queue.push_back(item); - return item; - } - void addTextureCoords(CoordsBuffer& coords, const TexturePtr& texture, const Color& color = Color::white) - { - m_queue.push_back(new DrawQueueItemTextureCoords(coords, texture, color)); - } - void addFilledRect(const Rect& dest, const Color& color = Color::white) - { - m_queue.push_back(new DrawQueueItemFilledRect(dest, color)); - } - void addFillCoords(CoordsBuffer& coords, const Color& color = Color::white) - { - m_queue.push_back(new DrawQueueItemFillCoords(coords, color)); - } - void addClearRect(const Rect& dest, const Color& color = Color::white) - { - m_queue.push_back(new DrawQueueItemClearRect(dest, color)); - } - void addText(BitmapFontPtr font, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align = Fw::AlignTopLeft, const Color& color = Color::white); - void addColoredText(BitmapFontPtr font, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align, const std::vector>& colors); - DrawQueueItemOutfit* addOutfit(const Rect& dest, const TexturePtr& texture, const Rect& src, const Point& offset, int colors, const Color& color = Color::white) - { - DrawQueueItemOutfit* outfit = new DrawQueueItemOutfit(dest, texture, src, offset, colors, color); - m_queue.push_back(outfit); - return outfit; - } - - void addFilledTriangle(const Point& a, const Point& b, const Point& c, const Color& color = Color::white) - { - if (a == b || a == c || b == c) - return; - - CoordsBuffer coordsBuffer; - coordsBuffer.addTriangle(a, b, c); - addFillCoords(coordsBuffer, color); - } - void addBoundingRect(const Rect& dest, int innerLineWidth, const Color& color = Color::white) - { - if (dest.isEmpty() || innerLineWidth == 0) - return; - - CoordsBuffer coordsBuffer; - coordsBuffer.addBoudingRect(dest, innerLineWidth); - addFillCoords(coordsBuffer, color); - } - - void setFrameBuffer(const Rect& dest, const Size& size, const Rect& src); - bool hasFrameBuffer() - { - return m_useFrameBuffer; - } - Rect getFrameBufferDest() - { - return m_frameBufferDest; - } - Size getFrameBufferSize() - { - return m_frameBufferSize; - } - Rect getFrameBufferSrc() - { - return m_frameBufferSrc; - } - - size_t size() - { - return m_queue.size(); - } - - void setOpacity(size_t start, float opacity) - { - for (size_t i = start; i < m_queue.size(); ++i) { - m_queue[i]->m_color = m_queue[i]->m_color.opacity(opacity); - } - } - - void setClip(size_t start, const Rect& clip) - { - if (start == m_queue.size()) return; - m_conditions.push_back(new DrawQueueConditionClip(start, m_queue.size(), clip)); - } - - void setRotation(size_t start, const Point& center, float angle) - { - if (start == m_queue.size() || angle == 0) return; - m_conditions.push_back(new DrawQueueConditionRotation(start, m_queue.size(), center, angle)); - } - - void setMark(size_t start, const Color& color) - { - if (start == m_queue.size()) return; - m_conditions.push_back(new DrawQueueConditionMark(start, m_queue.size(), color)); - } - - void markMapPosition() - { - mapPosition = m_queue.size(); - } - void correctOutfit(const Rect& dest, int fromPos); - -private: - std::vector m_queue; - std::vector m_conditions; - Size m_frameBufferSize; - Rect m_frameBufferDest, m_frameBufferSrc; - size_t mapPosition = 0; - bool m_useFrameBuffer = false; - float m_scaling = 1.f; - - friend struct DrawQueueConditionMark; -}; - -extern std::shared_ptr g_drawQueue; - -#endif \ No newline at end of file diff --git a/src/framework/graphics/fontmanager.cpp b/src/framework/graphics/fontmanager.cpp deleted file mode 100644 index e7b3189..0000000 --- a/src/framework/graphics/fontmanager.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "atlas.h" -#include "fontmanager.h" -#include "texture.h" - -#include -#include -#include - -FontManager g_fonts; - -FontManager::FontManager() -{ - m_defaultFont = BitmapFontPtr(new BitmapFont("emptyfont")); -} - -void FontManager::terminate() -{ - m_fonts.clear(); - m_defaultFont = nullptr; -} - -void FontManager::clearFonts() -{ - m_fonts.clear(); - m_defaultFont = BitmapFontPtr(new BitmapFont("emptyfont")); -} - -void FontManager::importFont(std::string file) -{ - if (g_mainThreadId != std::this_thread::get_id()) { - g_graphicsDispatcher.addEvent(std::bind(&FontManager::importFont, this, file)); - return; - } - try { - file = g_resources.guessFilePath(file, "otfont"); - - OTMLDocumentPtr doc = OTMLDocument::parse(file); - OTMLNodePtr fontNode = doc->at("Font"); - - std::string name = fontNode->valueAt("name"); - if (fontExists(name)) - return; - - // remove any font with the same name - for(auto it = m_fonts.begin(); it != m_fonts.end(); ++it) { - if((*it)->getName() == name) { - m_fonts.erase(it); - break; - } - } - - BitmapFontPtr font(new BitmapFont(name)); - font->load(fontNode); - m_fonts.push_back(font); - - // set as default if needed - if(!m_defaultFont || fontNode->valueAt("default", false)) - m_defaultFont = font; - - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Unable to load font from file '%s': %s", file, e.what())); - } -} - -bool FontManager::fontExists(const std::string& fontName) -{ - for(const BitmapFontPtr& font : m_fonts) { - if(font->getName() == fontName) - return true; - } - return false; -} - -BitmapFontPtr FontManager::getFont(const std::string& fontName) -{ - // find font by name - for(const BitmapFontPtr& font : m_fonts) { - if(font->getName() == fontName) - return font; - } - - // when not found, fallback to default font - g_logger.error(stdext::format("font '%s' not found", fontName)); - return getDefaultFont(); -} diff --git a/src/framework/graphics/fontmanager.h b/src/framework/graphics/fontmanager.h deleted file mode 100644 index b4d2687..0000000 --- a/src/framework/graphics/fontmanager.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FONTMANAGER_H -#define FONTMANAGER_H - -#include "bitmapfont.h" - -//@bindsingleton g_fonts -class FontManager -{ -public: - FontManager(); - - void terminate(); - void clearFonts(); - - void importFont(std::string file); - - bool fontExists(const std::string& fontName); - BitmapFontPtr getFont(const std::string& fontName); - BitmapFontPtr getDefaultFont() { return m_defaultFont; } - - void setDefaultFont(const std::string& fontName) { m_defaultFont = getFont(fontName); } - -private: - std::vector m_fonts; - BitmapFontPtr m_defaultFont; -}; - -extern FontManager g_fonts; - -#endif diff --git a/src/framework/graphics/paintershaderprogram.cpp b/src/framework/graphics/paintershaderprogram.cpp deleted file mode 100644 index 3fe6bd1..0000000 --- a/src/framework/graphics/paintershaderprogram.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "paintershaderprogram.h" -#include "painter.h" -#include "texture.h" -#include "texturemanager.h" -#include "graphics.h" -#include -#include - -PainterShaderProgram::PainterShaderProgram() -{ - m_startTime = g_clock.seconds(); - m_opacity = 1; - m_depth = 0; - m_color = Color::white; - m_time = 0; -} - -void PainterShaderProgram::setupUniforms() -{ - bindUniformLocation(TRANSFORM_MATRIX_UNIFORM, "u_TransformMatrix"); - bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "u_ProjectionMatrix"); - bindUniformLocation(TEXTURE_MATRIX_UNIFORM, "u_TextureMatrix"); - - bindUniformLocation(COLOR_UNIFORM, "u_Color"); - bindUniformLocation(OPACITY_UNIFORM, "u_Opacity"); - bindUniformLocation(DEPTH_UNIFORM, "u_Depth"); - bindUniformLocation(TIME_UNIFORM, "u_Time"); - - bindUniformLocation(TEX0_UNIFORM, "u_Tex0"); - bindUniformLocation(TEX1_UNIFORM, "u_Tex1"); - bindUniformLocation(TEX2_UNIFORM, "u_Tex2"); - bindUniformLocation(TEX3_UNIFORM, "u_Tex3"); - - bindUniformLocation(ATLAS_TEX0_UNIFORM, "u_Atlas"); - bindUniformLocation(ATLAS_TEX1_UNIFORM, "u_Fonts"); - - bindUniformLocation(RESOLUTION_UNIFORM, "u_Resolution"); - bindUniformLocation(OFFSET_UNIFORM, "u_Offset"); - - // VALUES - setUniformValue(TRANSFORM_MATRIX_UNIFORM, m_transformMatrix); - setUniformValue(PROJECTION_MATRIX_UNIFORM, m_projectionMatrix); - setUniformValue(TEXTURE_MATRIX_UNIFORM, m_textureMatrix); - - if (!m_useColorMatrix) { - setUniformValue(COLOR_UNIFORM, m_color); - } - setUniformValue(OPACITY_UNIFORM, m_opacity); - setUniformValue(TIME_UNIFORM, m_time); - setUniformValue(DEPTH_UNIFORM, m_depth); - - setUniformValue(TEX0_UNIFORM, 0); - setUniformValue(TEX1_UNIFORM, 1); - setUniformValue(TEX2_UNIFORM, 2); - setUniformValue(TEX3_UNIFORM, 3); - - setUniformValue(ATLAS_TEX0_UNIFORM, 6); - setUniformValue(ATLAS_TEX1_UNIFORM, 7); - - setUniformValue(RESOLUTION_UNIFORM, (float)m_resolution.width(), (float)m_resolution.height()); - setUniformValue(OFFSET_UNIFORM, (float)m_offset.x, (float)m_offset.y); -} - -void PainterShaderProgram::link() -{ - m_startTime = g_clock.seconds(); - bindAttributeLocation(VERTEX_ATTR, "a_Vertex"); - bindAttributeLocation(TEXCOORD_ATTR, "a_TexCoord"); - bindAttributeLocation(DEPTH_ATTR, "a_Depth"); - bindAttributeLocation(COLOR_ATTR, "a_Color"); - bindAttributeLocation(DEPTH_TEXCOORD_ATTR, "a_DepthTexCoord"); - ShaderProgram::link(); - bind(); - setupUniforms(); - release(); - g_graphics.checkForError(__FUNCTION__, __FILE__, __LINE__); -} - -void PainterShaderProgram::setTransformMatrix(const Matrix3& transformMatrix) -{ - if (transformMatrix == m_transformMatrix) - return; - - bind(); - setUniformValue(TRANSFORM_MATRIX_UNIFORM, transformMatrix); - m_transformMatrix = transformMatrix; -} - -void PainterShaderProgram::setProjectionMatrix(const Matrix3& projectionMatrix) -{ - if (projectionMatrix == m_projectionMatrix) - return; - - bind(); - setUniformValue(PROJECTION_MATRIX_UNIFORM, projectionMatrix); - m_projectionMatrix = projectionMatrix; -} - -void PainterShaderProgram::setTextureMatrix(const Matrix3& textureMatrix) -{ - if (textureMatrix == m_textureMatrix) - return; - - bind(); - setUniformValue(TEXTURE_MATRIX_UNIFORM, textureMatrix); - m_textureMatrix = textureMatrix; -} - -void PainterShaderProgram::setColor(const Color& color) -{ - if (color == m_color || m_useColorMatrix) - return; - - bind(); - setUniformValue(COLOR_UNIFORM, color); - m_color = color; -} - -void PainterShaderProgram::setMatrixColor(const Matrix4& colors) -{ - bind(); - setUniformValue(COLOR_UNIFORM, colors); -} - - -void PainterShaderProgram::setOpacity(float opacity) -{ - if (m_opacity == opacity) - return; - - bind(); - setUniformValue(OPACITY_UNIFORM, opacity); - m_opacity = opacity; -} - -#ifdef WITH_DEPTH_BUFFER -void PainterShaderProgram::setDepth(float depth) -{ - if (depth < 0.) - depth = 0.; - - if (m_depth == depth) - return; - - bind(); - setUniformValue(DEPTH_UNIFORM, depth); - m_depth = depth; -} -#endif - -void PainterShaderProgram::setResolution(const Size& resolution) -{ - if (m_resolution == resolution) - return; - - bind(); - setUniformValue(RESOLUTION_UNIFORM, (float)resolution.width(), (float)resolution.height()); - m_resolution = resolution; -} - -void PainterShaderProgram::setOffset(const Point& offset) -{ - if (m_offset == offset) - return; - - bind(); - m_offset = offset; - setUniformValue(OFFSET_UNIFORM, (float)m_offset.x, (float)m_offset.y); -} - - -void PainterShaderProgram::updateTime() -{ - float time = g_clock.seconds() - m_startTime; - if (m_time == time) - return; - - bind(); - setUniformValue(TIME_UNIFORM, time); - m_time = time; -} - -void PainterShaderProgram::addMultiTexture(const std::string& file) -{ - if (m_multiTextures.size() > 3) - g_logger.error("cannot add more multi textures to shader, the max is 3"); - - TexturePtr texture = g_textures.getTexture(file); - if (!texture) - return; - - texture->setSmooth(true); - texture->setRepeat(true); - - m_multiTextures.push_back(texture); -} - -void PainterShaderProgram::bindMultiTextures() -{ - if (m_multiTextures.size() == 0) - return; - - int i = 1; - for (const TexturePtr& tex : m_multiTextures) { - glActiveTexture(GL_TEXTURE0 + i++); - glBindTexture(GL_TEXTURE_2D, tex->getId()); - } - - glActiveTexture(GL_TEXTURE0); -} - -void PainterShaderProgram::clearMultiTextures() -{ - m_multiTextures.clear(); -} diff --git a/src/framework/graphics/paintershaderprogram.h b/src/framework/graphics/paintershaderprogram.h deleted file mode 100644 index dc649dd..0000000 --- a/src/framework/graphics/paintershaderprogram.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PAINTERSHADERPROGRAM_H -#define PAINTERSHADERPROGRAM_H - -#include "shaderprogram.h" -#include "coordsbuffer.h" -#include - -class PainterShaderProgram : public ShaderProgram { -protected: - enum { - VERTEX_ATTR = 0, - TEXCOORD_ATTR = 1, - DEPTH_ATTR = 2, - COLOR_ATTR = 3, - DEPTH_TEXCOORD_ATTR = 4, - - PROJECTION_MATRIX_UNIFORM = 0, - TEXTURE_MATRIX_UNIFORM = 1, - TRANSFORM_MATRIX_UNIFORM = 2, - - COLOR_UNIFORM = 3, - OPACITY_UNIFORM = 4, - TIME_UNIFORM = 5, - DEPTH_UNIFORM = 6, - - TEX0_UNIFORM = 7, - TEX1_UNIFORM = 8, - TEX2_UNIFORM = 9, - TEX3_UNIFORM = 10, - ATLAS_TEX0_UNIFORM = 11, - ATLAS_TEX1_UNIFORM = 12, - - RESOLUTION_UNIFORM = 13, - OFFSET_UNIFORM = 14 - }; - - friend class Painter; - - virtual void setupUniforms(); - -public: - PainterShaderProgram(); - - void link(); - - void setTransformMatrix(const Matrix3& transformMatrix); - void setProjectionMatrix(const Matrix3& projectionMatrix); - void setTextureMatrix(const Matrix3& textureMatrix); - void setColor(const Color& color); - void setMatrixColor(const Matrix4& colors); - void setOpacity(float opacity); - void setDepth(float depth); - void setResolution(const Size& resolution); - void setOffset(const Point& offset); - void updateTime(); - - void addMultiTexture(const std::string& file); - void bindMultiTextures(); - void clearMultiTextures(); - - void enableColorMatrix() - { - m_useColorMatrix = true; - } - -private: - float m_startTime; - - Color m_color; - float m_opacity; - float m_depth; - Matrix3 m_transformMatrix; - Matrix3 m_projectionMatrix; - Matrix3 m_textureMatrix; - Size m_resolution; - Point m_offset; - float m_time; - std::vector m_multiTextures; - bool m_useColorMatrix = false; -}; - -#endif diff --git a/src/framework/graphics/shader.cpp b/src/framework/graphics/shader.cpp deleted file mode 100644 index 739cd0c..0000000 --- a/src/framework/graphics/shader.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shader.h" -#include "graphics.h" - -#include -#include - -Shader::Shader(Shader::ShaderType shaderType) -{ - m_shaderType = shaderType; - switch(shaderType) { - case Vertex: - m_shaderId = glCreateShader(GL_VERTEX_SHADER); - break; - case Fragment: - m_shaderId = glCreateShader(GL_FRAGMENT_SHADER); - break; - } - - if(!m_shaderId) - g_logger.fatal("Unable to create GL shader"); -} - -Shader::~Shader() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); -#endif - if(g_graphics.ok()) - glDeleteShader(m_shaderId); -} - -bool Shader::compileSourceCode(const std::string& sourceCode) -{ -#ifdef OPENGL_ES - static const char *qualifierDefines = - "precision mediump float;\n"; - std::string code = qualifierDefines; - code.append(sourceCode); - const char* c_source = code.c_str(); -#else - const char* c_source = sourceCode.c_str(); -#endif - glShaderSource(m_shaderId, 1, &c_source, NULL); - glCompileShader(m_shaderId); - - int res = GL_FALSE; - glGetShaderiv(m_shaderId, GL_COMPILE_STATUS, &res); - return (res == GL_TRUE); -} - -bool Shader::compileSourceFile(const std::string& sourceFile) -{ - try { - std::string sourceCode = g_resources.readFileContents(sourceFile); - return compileSourceCode(sourceCode); - } catch(stdext::exception& e) { - g_logger.error(stdext::format("unable to load shader source form file '%s': %s", sourceFile, e.what())); - } - return false; -} - -std::string Shader::log() -{ - std::string infoLog; - int infoLogLength = 0; - glGetShaderiv(m_shaderId, GL_INFO_LOG_LENGTH, &infoLogLength); - if(infoLogLength > 1) { - std::vector buf(infoLogLength); - glGetShaderInfoLog(m_shaderId, infoLogLength-1, NULL, &buf[0]); - infoLog = &buf[0]; - } - return infoLog; -} diff --git a/src/framework/graphics/shader.h b/src/framework/graphics/shader.h deleted file mode 100644 index b8c7e2b..0000000 --- a/src/framework/graphics/shader.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SHADER_H -#define SHADER_H - -#include "declarations.h" - -class Shader : public stdext::shared_object -{ -public: - enum ShaderType { - Vertex, - Fragment - }; - - Shader(ShaderType shaderType); - ~Shader(); - - bool compileSourceCode(const std::string& sourceCode); - bool compileSourceFile(const std::string& sourceFile); - std::string log(); - - uint getShaderId() { return m_shaderId; } - ShaderType getShaderType() { return m_shaderType; } - -private: - uint m_shaderId; - ShaderType m_shaderType; -}; - -#endif diff --git a/src/framework/graphics/shaderprogram.cpp b/src/framework/graphics/shaderprogram.cpp deleted file mode 100644 index d9643f8..0000000 --- a/src/framework/graphics/shaderprogram.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shaderprogram.h" -#include "graphics.h" - -#include - -uint ShaderProgram::m_currentProgram = 0; - -ShaderProgram::ShaderProgram() -{ - m_linked = false; - m_programId = glCreateProgram(); - m_uniformLocations.fill(-1); - if(!m_programId) - g_logger.fatal("Unable to create GL shader program"); -} - -ShaderProgram::~ShaderProgram() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); -#endif - if(g_graphics.ok()) - glDeleteProgram(m_programId); -} - -PainterShaderProgramPtr ShaderProgram::create(const std::string& vertexShader, const std::string& fragmentShader, bool colorMatrix) -{ - PainterShaderProgramPtr program(new PainterShaderProgram); - if (!program) - g_logger.fatal(stdext::format("Cant creatre shader: \n%s", vertexShader)); - program->addShaderFromSourceCode(Shader::Vertex, vertexShader); - program->addShaderFromSourceCode(Shader::Fragment, fragmentShader); - if (colorMatrix) { - program->enableColorMatrix(); - } - program->link(); - g_graphics.checkForError(__FUNCTION__, vertexShader + "\n" + fragmentShader, __LINE__); - return program; -} - - -bool ShaderProgram::addShader(const ShaderPtr& shader) { - glAttachShader(m_programId, shader->getShaderId()); - m_linked = false; - m_shaders.push_back(shader); - return true; -} - -bool ShaderProgram::addShaderFromSourceCode(Shader::ShaderType shaderType, const std::string& sourceCode) { - ShaderPtr shader(new Shader(shaderType)); - if(!shader->compileSourceCode(sourceCode)) { - g_logger.fatal(stdext::format("failed to compile shader: %s", shader->log())); - return false; - } - return addShader(shader); -} - -bool ShaderProgram::addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string& sourceFile) { - ShaderPtr shader(new Shader(shaderType)); - if(!shader->compileSourceFile(sourceFile)) { - g_logger.fatal(stdext::format("failed to compile shader: %s", shader->log())); - return false; - } - return addShader(shader); -} - -void ShaderProgram::removeShader(const ShaderPtr& shader) -{ - auto it = std::find(m_shaders.begin(), m_shaders.end(), shader); - if(it == m_shaders.end()) - return; - - glDetachShader(m_programId, shader->getShaderId()); - m_shaders.erase(it); - m_linked = false; -} - -void ShaderProgram::removeAllShaders() -{ - while(!m_shaders.empty()) - removeShader(m_shaders.front()); -} - -void ShaderProgram::link() -{ - if(m_linked) - return; - - glLinkProgram(m_programId); - - int value = GL_FALSE; - glGetProgramiv(m_programId, GL_LINK_STATUS, &value); - m_linked = (value != GL_FALSE); - if (m_linked) { - return; - } - - GLint maxLength = 0; - glGetProgramiv(m_programId, GL_INFO_LOG_LENGTH, &maxLength); - std::vector infoLog(maxLength); - glGetProgramInfoLog(m_programId, maxLength, &maxLength, &infoLog[0]); - g_logger.fatal(stdext::format("Program %i linking error (%i): %s - %s - %s %s\nExtensions: %s", m_programId, infoLog.size(), - std::string(infoLog.begin(), infoLog.end()).c_str(), log().c_str(), - g_graphics.getRenderer(), g_graphics.getVersion(), g_graphics.getExtensions())); -} - -bool ShaderProgram::bind() -{ - if(m_currentProgram != m_programId) { - if (!m_linked) { - link(); - } - glUseProgram(m_programId); - m_currentProgram = m_programId; - } - return true; -} - -void ShaderProgram::release() -{ - if(m_currentProgram != 0) { - m_currentProgram = 0; - glUseProgram(0); - } -} - -std::string ShaderProgram::log() -{ - std::string infoLog; - int infoLogLength = 0; - glGetProgramiv(m_programId, GL_INFO_LOG_LENGTH, &infoLogLength); - if(infoLogLength > 1) { - std::vector buf(infoLogLength); - glGetShaderInfoLog(m_programId, infoLogLength-1, NULL, &buf[0]); - infoLog = &buf[0]; - } - return infoLog; -} - -int ShaderProgram::getAttributeLocation(const char* name) -{ - return glGetAttribLocation(m_programId, name); -} - -void ShaderProgram::bindAttributeLocation(int location, const char* name) -{ - return glBindAttribLocation(m_programId, location, name); -} - -void ShaderProgram::bindUniformLocation(int location, const char* name) -{ - VALIDATE(m_linked); - VALIDATE(location >= 0 && location < MAX_UNIFORM_LOCATIONS); - m_uniformLocations[location] = glGetUniformLocation(m_programId, name); -} diff --git a/src/framework/graphics/shaderprogram.h b/src/framework/graphics/shaderprogram.h deleted file mode 100644 index aef613d..0000000 --- a/src/framework/graphics/shaderprogram.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SHADERPROGRAM_H -#define SHADERPROGRAM_H - -#include "shader.h" -#include - - // @bindclass -class ShaderProgram : public LuaObject { - enum { - MAX_UNIFORM_LOCATIONS = 30 - }; - -public: - ShaderProgram(); - ~ShaderProgram(); - - static PainterShaderProgramPtr create(const std::string& vertexShader, const std::string& fragmentShader, bool colorMatrix = false); - - bool addShader(const ShaderPtr& shader); - bool addShaderFromSourceCode(Shader::ShaderType shaderType, const std::string& sourceCode); - bool addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string& sourceFile); - void removeShader(const ShaderPtr& shader); - void removeAllShaders(); - - virtual void link(); - bool bind(); - static void release(); - std::string log(); - - static void disableAttributeArray(int location) { glDisableVertexAttribArray(location); } - static void enableAttributeArray(int location) { glEnableVertexAttribArray(location); } - void disableAttributeArray(const char* name) { glDisableVertexAttribArray(getAttributeLocation(name)); } - void enableAttributeArray(const char* name) { glEnableVertexAttribArray(getAttributeLocation(name)); } - - int getAttributeLocation(const char* name); - void bindAttributeLocation(int location, const char* name); - void bindUniformLocation(int location, const char* name); - - void setAttributeArray(int location, const float* values, int size, int stride = 0) { glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, stride, values); } - void setAttributeValue(int location, float value) { glVertexAttrib1f(location, value); } - void setAttributeValue(int location, float x, float y) { glVertexAttrib2f(location, x, y); } - void setAttributeValue(int location, float x, float y, float z) { glVertexAttrib3f(location, x, y, z); } - void setAttributeArray(const char* name, const float* values, int size, int stride = 0) { glVertexAttribPointer(getAttributeLocation(name), size, GL_FLOAT, GL_FALSE, stride, values); } - void setAttributeValue(const char* name, float value) { glVertexAttrib1f(getAttributeLocation(name), value); } - void setAttributeValue(const char* name, float x, float y) { glVertexAttrib2f(getAttributeLocation(name), x, y); } - void setAttributeValue(const char* name, float x, float y, float z) { glVertexAttrib3f(getAttributeLocation(name), x, y, z); } - - void setUniformValue(int location, const Color& color) { glUniform4f(m_uniformLocations[location], color.rF(), color.gF(), color.bF(), color.aF()); } - void setUniformValue(int location, int value) { glUniform1i(m_uniformLocations[location], value); } - void setUniformValue(int location, float value) { glUniform1f(m_uniformLocations[location], value); } - void setUniformValue(int location, float x, float y) { glUniform2f(m_uniformLocations[location], x, y); } - void setUniformValue(int location, float x, float y, float z) { glUniform3f(m_uniformLocations[location], x, y, z); } - void setUniformValue(int location, float x, float y, float z, float w) { glUniform4f(m_uniformLocations[location], x, y, z, w); } - void setUniformValue(int location, const Matrix2& mat) { glUniformMatrix2fv(m_uniformLocations[location], 1, GL_FALSE, mat.data()); } - void setUniformValue(int location, const Matrix3& mat) { glUniformMatrix3fv(m_uniformLocations[location], 1, GL_FALSE, mat.data()); } - void setUniformValue(int location, const Matrix4& mat) { glUniformMatrix4fv(m_uniformLocations[location], 1, GL_FALSE, mat.data()); } - void setUniformValue(int location, int count, const int* value) { glUniform1iv(m_uniformLocations[location], count, value); } - void setUniformValue(const char* name, const Color& color) { glUniform4f(glGetUniformLocation(m_programId, name), color.rF(), color.gF(), color.bF(), color.aF()); } - void setUniformValue(const char* name, int value) { glUniform1i(glGetUniformLocation(m_programId, name), value); } - void setUniformValue(const char* name, float value) { glUniform1f(glGetUniformLocation(m_programId, name), value); } - void setUniformValue(const char* name, float x, float y) { glUniform2f(glGetUniformLocation(m_programId, name), x, y); } - void setUniformValue(const char* name, float x, float y, float z) { glUniform3f(glGetUniformLocation(m_programId, name), x, y, z); } - void setUniformValue(const char* name, float x, float y, float z, float w) { glUniform4f(glGetUniformLocation(m_programId, name), x, y, z, w); } - void setUniformValue(const char* name, const Matrix2& mat) { glUniformMatrix2fv(glGetUniformLocation(m_programId, name), 1, GL_FALSE, mat.data()); } - void setUniformValue(const char* name, const Matrix3& mat) { glUniformMatrix3fv(glGetUniformLocation(m_programId, name), 1, GL_FALSE, mat.data()); } - void setUniformValue(const char* name, const Matrix4& mat) { glUniformMatrix4fv(glGetUniformLocation(m_programId, name), 1, GL_FALSE, mat.data()); } - // TODO: Point, PointF, Color, Size, SizeF ? - - bool isLinked() { return m_linked; } - uint getProgramId() { return m_programId; } - ShaderList getShaders() { return m_shaders; } - -private: - bool m_linked; - uint m_programId; - static uint m_currentProgram; - ShaderList m_shaders; - std::array m_uniformLocations; -}; - -#endif diff --git a/src/framework/graphics/shaders/newshader.h b/src/framework/graphics/shaders/newshader.h deleted file mode 100644 index 84f3c98..0000000 --- a/src/framework/graphics/shaders/newshader.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef NEWSHADER_H -#define NEWSHADER_H - -#include -// VERTEX -static const std::string newVertexShader = "\n\ - attribute vec2 a_Vertex;\n\ - attribute vec2 a_TexCoord;\n\ - attribute vec4 a_Color;\n\ - \n\ - uniform mat3 u_ProjectionMatrix;\n\ - uniform mat3 u_TransformMatrix;\n\ - uniform mat3 u_TextureMatrix;\n\ - \n\ - varying vec2 v_TexCoord;\n\ - varying vec4 v_Color;\n\ - void main()\n\ - {\n\ - gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, 1.0, 1.0);\n\ - v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\ - v_Color = a_Color;\n\ - }\n"; - -// TEXT -static const std::string textVertexShader = "\n\ - attribute vec2 a_TexCoord;\n\ - uniform mat3 u_TextureMatrix;\n\ - varying vec2 v_TexCoord;\n\ - attribute vec2 a_Vertex;\n\ - uniform mat3 u_TransformMatrix;\n\ - uniform mat3 u_ProjectionMatrix;\n\ - uniform float u_Depth;\n\ - uniform vec2 u_Offset;\n\ - void main()\n\ - {\n\ - gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy + u_Offset, 1.0)).xy, u_Depth / 16384.0, 1.0);\n\ - v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\ - }\n"; - -// FRAGMENT -static const std::string newFragmentShader = "\n\ - varying vec2 v_TexCoord;\n\ - varying vec4 v_Color;\n\ - uniform sampler2D u_Atlas;\n\ - void main()\n\ - {\n\ - if(v_TexCoord.x < 0.0) { gl_FragColor = v_Color; return; }\n\ - gl_FragColor = texture2D(u_Atlas, v_TexCoord) * v_Color;\n\ - }\n"; - -// TEXT -static const std::string textFragmentShader = "\n\ - varying vec2 v_TexCoord;\n\ - uniform vec4 u_Color;\n\ - uniform sampler2D u_Fonts;\n\ - void main()\n\ - {\n\ - gl_FragColor = texture2D(u_Fonts, v_TexCoord) * u_Color;\n\ - }\n"; - -#endif \ No newline at end of file diff --git a/src/framework/graphics/shaders/shaders.h b/src/framework/graphics/shaders/shaders.h deleted file mode 100644 index b9c89ed..0000000 --- a/src/framework/graphics/shaders/shaders.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef SHADERS_H -#define SHADERS_H - -#include "newshader.h" -#include "shadersources.h" - -#endif \ No newline at end of file diff --git a/src/framework/graphics/shaders/shadersources.h b/src/framework/graphics/shaders/shadersources.h deleted file mode 100644 index d156dc0..0000000 --- a/src/framework/graphics/shaders/shadersources.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PAINTEROGL2_SHADERSOURCES_H -#define PAINTEROGL2_SHADERSOURCES_H - -static const std::string glslMainVertexShader = "\n\ - vec4 calculatePosition();\n\ - void main() {\n\ - gl_Position = calculatePosition();\n\ - }\n"; - -static const std::string glslMainWithTexCoordsVertexShader = "\n\ - attribute vec2 a_TexCoord;\n\ - uniform mat3 u_TextureMatrix;\n\ - varying vec2 v_TexCoord;\n\ - vec4 calculatePosition();\n\ - void main()\n\ - {\n\ - gl_Position = calculatePosition();\n\ - v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\ - }\n"; - -static std::string glslPositionOnlyVertexShader = "\n\ - attribute vec2 a_Vertex;\n\ - uniform mat3 u_TransformMatrix;\n\ - uniform mat3 u_ProjectionMatrix;\n\ - uniform float u_Depth;\n\ - vec4 calculatePosition() {\n\ - return vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, u_Depth / 16384.0, 1.0);\n\ - }\n"; - -static const std::string glslMainFragmentShader = "\n\ - uniform float u_Opacity;\n\ - uniform float u_Depth;\n\ - vec4 calculatePixel();\n\ - void main()\n\ - {\n\ - gl_FragColor = calculatePixel();\n\ - gl_FragColor.a *= u_Opacity;\n\ - if(gl_FragColor.a < 0.01 && u_Depth > 0.0)\n\ - discard;\n\ - }\n"; - -static const std::string glslTextureSrcFragmentShader = "\n\ - varying vec2 v_TexCoord;\n\ - uniform vec4 u_Color;\n\ - uniform sampler2D u_Tex0;\n\ - vec4 calculatePixel() {\n\ - return texture2D(u_Tex0, v_TexCoord) * u_Color;\n\ - }\n"; - - -static const std::string glslSolidColorFragmentShader = "\n\ - uniform vec4 u_Color;\n\ - vec4 calculatePixel() {\n\ - return u_Color;\n\ - }\n"; - -static const std::string glslSolidColorOnTextureFragmentShader = "\n\ - uniform vec4 u_Color;\n\ - varying vec2 v_TexCoord;\n\ - uniform sampler2D u_Tex0;\n\ - vec4 calculatePixel() {\n\ - if(texture2D(u_Tex0, v_TexCoord).a > 0.01)\n\ - return u_Color;\n\ - return vec4(0,0,0,0);\n\ - }\n"; - - -static const std::string glslOutfitVertexShader = "\n\ - attribute vec2 a_TexCoord;\n\ - uniform mat3 u_TextureMatrix;\n\ - varying vec2 v_TexCoord;\n\ - varying vec2 v_TexCoord2;\n\ - attribute vec2 a_Vertex;\n\ - uniform mat3 u_TransformMatrix;\n\ - uniform mat3 u_ProjectionMatrix;\n\ - uniform float u_Depth;\n\ - uniform vec2 u_Offset;\n\ - void main()\n\ - {\n\ - gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, u_Depth / 16384.0, 1.0);\n\ - v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;\n\ - v_TexCoord2 = (u_TextureMatrix * vec3(a_TexCoord + u_Offset,1.0)).xy;\n\ - }\n"; - -static const std::string glslOutfitFragmentShader = "\n\ - uniform float u_Opacity;\n\ - uniform float u_Depth;\n\ - uniform mat4 u_Color;\n\ - varying vec2 v_TexCoord;\n\ - varying vec2 v_TexCoord2;\n\ - uniform sampler2D u_Tex0;\n\ - uniform sampler2D u_Tex1;\n\ - void main()\n\ - {\n\ - gl_FragColor = texture2D(u_Tex0, v_TexCoord);\n\ - vec4 texcolor = texture2D(u_Tex0, v_TexCoord2);\n\ - if(texcolor.r > 0.9)\n\ - gl_FragColor *= texcolor.g > 0.9 ? u_Color[0] : u_Color[1];\n\ - else if(texcolor.g > 0.9)\n\ - gl_FragColor *= u_Color[2];\n\ - else if(texcolor.b > 0.9)\n\ - gl_FragColor *= u_Color[3];\n\ - if(gl_FragColor.a < 0.01) discard;\n\ - }\n"; - -#endif diff --git a/src/framework/graphics/textrender.cpp b/src/framework/graphics/textrender.cpp deleted file mode 100644 index 0e65d51..0000000 --- a/src/framework/graphics/textrender.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "painter.h" -#include "textrender.h" -#include - -TextRender g_text; - -void TextRender::init() -{ - -} - -void TextRender::terminate() -{ - for (auto& cache : m_cache) { - cache.clear(); - } -} - -void TextRender::poll() -{ - static int iteration = 0; - int index = (iteration++) % INDEXES; - std::lock_guard lock(m_mutex[index]); - auto& cache = m_cache[index]; - if (cache.size() < 100) - return; - - ticks_t dropPoint = g_clock.millis(); - if (cache.size() > 500) - dropPoint -= 10; - else if (cache.size() > 250) - dropPoint -= 100; - else - dropPoint -= 1000; - - for (auto it = cache.begin(); it != cache.end(); ) { - if (it->second->lastUse < dropPoint) { - it = cache.erase(it); - continue; - } - ++it; - } -} - -uint64_t TextRender::addText(BitmapFontPtr font, const std::string& text, const Size& size, Fw::AlignmentFlag align) -{ - uint64_t hash = 1125899906842597ULL; - for (size_t i = 0; i < text.length(); ++i) { - hash = hash * 31 + text[i]; - } - hash = hash * 31 + size.width(); - hash = hash * 31 + size.height(); - hash = hash * 31 + (uint64_t)align; - hash = hash * 31 + (uint64_t)font->getId(); - - int index = hash % INDEXES; - m_mutex[index].lock(); - auto it = m_cache[index].find(hash); - if (it == m_cache[index].end()) { - m_cache[index][hash] = std::shared_ptr(new TextRenderCache{ font, text, size, align, font->getTexture(), CoordsBuffer(), g_clock.millis() }); - } - m_mutex[index].unlock(); - return hash; -} - -void TextRender::drawText(const Point& pos, uint64_t hash, const Color& color) -{ - int index = hash % INDEXES; - m_mutex[index].lock(); - auto _it = m_cache[index].find(hash); - if (_it == m_cache[index].end()) { - m_mutex[index].unlock(); - return; - } - auto it = _it->second; - m_mutex[index].unlock(); - if (it->font) { // calculate text coords - it->font->calculateDrawTextCoords(it->coords, it->text, Rect(0, 0, it->size), it->align); - it->coords.cache(); - it->text.clear(); - it->font.reset(); - } - it->lastUse = g_clock.millis(); - g_painterNew->drawText(pos, it->coords, color); -} - -void TextRender::drawColoredText(const Point& pos, uint64_t hash, const std::vector>& colors) -{ - if (colors.empty()) - return drawText(pos, hash, Color::white); - int index = hash % INDEXES; - m_mutex[index].lock(); - auto _it = m_cache[index].find(hash); - if (_it == m_cache[index].end()) { - m_mutex[index].unlock(); - return; - } - auto it = _it->second; - m_mutex[index].unlock(); - if (it->font) { // calculate text coords - it->font->calculateDrawTextCoords(it->coords, it->text, Rect(0, 0, it->size), it->align); - it->coords.cache(); - it->text.clear(); - it->font.reset(); - } - it->lastUse = g_clock.millis(); - g_painterNew->drawText(pos, it->coords, colors); -} - diff --git a/src/framework/graphics/textrender.h b/src/framework/graphics/textrender.h deleted file mode 100644 index 6a2b0e1..0000000 --- a/src/framework/graphics/textrender.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef TEXTRENDER_H -#define TEXTRENDER_H - -#include -#include -#include "bitmapfont.h" -#include "coordsbuffer.h" -#include - -struct TextRenderCache { - BitmapFontPtr font; - std::string text; - Size size; - Fw::AlignmentFlag align; - TexturePtr texture; - CoordsBuffer coords; - ticks_t lastUse; -}; - -class TextRender -{ - static const int INDEXES = 10; -public: - void init(); - void terminate(); - void poll(); - uint64_t addText(BitmapFontPtr font, const std::string& text, const Size& size, Fw::AlignmentFlag align = Fw::AlignTopLeft); - void drawText(const Point& pos, uint64_t hash, const Color& color); - void drawColoredText(const Point& pos, uint64_t hash, const std::vector>& colors); - -private: - std::map> m_cache[INDEXES]; - std::mutex m_mutex[INDEXES]; -}; - -extern TextRender g_text; - -#endif diff --git a/src/framework/graphics/texture.cpp b/src/framework/graphics/texture.cpp deleted file mode 100644 index baccbb4..0000000 --- a/src/framework/graphics/texture.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "texture.h" -#include "graphics.h" -#include "framebuffer.h" -#include "image.h" - -#include -#include -#include -#include - -uint Texture::uniqueId = 1; - -Texture::Texture(const Size& size, bool depthTexture, bool smooth, bool upsideDown) -{ - m_uniqueId = uniqueId++; - m_smooth = smooth; - m_upsideDown = upsideDown; - setupSize(size); - - g_stats.addTexture(); -} - -Texture::Texture(const ImagePtr& image, bool buildMipmaps, bool compress, bool smooth) -{ - if (!image) { - g_logger.fatal("Texture can't be created with null image!"); - } - - m_uniqueId = uniqueId++; - m_smooth = smooth; - m_image = image; - setupSize(m_image->getSize()); - - g_stats.addTexture(); -} - -Texture::~Texture() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); -#endif - if (m_id != 0) { // free texture from gl memory - GLuint textureId = m_id; - g_graphicsDispatcher.addEvent([textureId] { - glDeleteTextures(1, &textureId); - }); - } - - g_stats.removeTexture(); -} - -void Texture::replace(const ImagePtr& image) -{ - m_uniqueId = uniqueId++; - if (m_id != 0) { // free existing texture from gl memory - GLuint textureId = m_id; - g_graphicsDispatcher.addEvent([textureId] { - glDeleteTextures(1, &textureId); - }); - } - if (!image) { - g_logger.fatal("Texture can't be replaced with null image!"); - } - m_id = 0; - m_image = image; - setupSize(m_image->getSize()); -} - -void Texture::resize(const Size& size) -{ - if(m_id == 0) - update(); - setupSize(size); - glBindTexture(GL_TEXTURE_2D, m_id); - setupPixels(0, m_size, nullptr, 4); - //m_needsUpdate = true; - /* update(); */ -} - - -void Texture::update() -{ - if (m_id == 0) { - glGenTextures(1, &m_id); - VALIDATE(m_id != 0); - glBindTexture(GL_TEXTURE_2D, m_id); - if (m_image) { - setupSize(m_image->getSize()); - int level = 0; - do { - setupPixels(level++, m_image->getSize(), m_image->getPixelData(), m_image->getBpp()); - } while (m_buildHardwareMipmaps && m_image->nextMipmap()); - } else { - setupPixels(0, m_size, nullptr, 4); - } - m_image = nullptr; // free image - m_needsUpdate = true; - g_graphics.checkForError(__FUNCTION__, __FILE__, __LINE__); - } - - if (m_needsUpdate) { - glBindTexture(GL_TEXTURE_2D, m_id); - setupWrap(); - setupFilters(); - setupTranformMatrix(); - m_needsUpdate = false; - g_graphics.checkForError(__FUNCTION__, __FILE__, __LINE__); - } -} - -bool Texture::buildHardwareMipmaps() -{ - m_buildHardwareMipmaps = true; - return true; -} - -void Texture::setSmooth(bool smooth) -{ - if(smooth == m_smooth) - return; - - m_smooth = smooth; - m_needsUpdate = true; -} - -void Texture::setRepeat(bool repeat) -{ - if(m_repeat == repeat) - return; - - m_repeat = repeat; - m_needsUpdate = true; -} - -void Texture::setUpsideDown(bool upsideDown) -{ - if(m_upsideDown == upsideDown) - return; - m_upsideDown = upsideDown; - m_needsUpdate = true; -} - -void Texture::setupSize(const Size& size) -{ - if (size.width() > g_graphics.getMaxTextureSize() || size.height() > g_graphics.getMaxTextureSize()) { - g_logger.fatal(stdext::format("Tried to create texture with size %ix%i while maximum texture size is %ix%i", - size.width(), size.height(), g_graphics.getMaxTextureSize(), g_graphics.getMaxTextureSize())); - } - m_size = size; -} - -void Texture::setupWrap() -{ - int texParam = GL_REPEAT; - if(!m_repeat) - texParam = GL_CLAMP_TO_EDGE; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam); -} - -void Texture::setupFilters() -{ - int minFilter; - int magFilter; - if(m_smooth) { - minFilter = m_hasMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; - magFilter = GL_LINEAR; - } else { - minFilter = m_hasMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; - magFilter = GL_NEAREST; - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); -} - -void Texture::setupTranformMatrix() -{ - if(m_upsideDown) { - m_transformMatrix = { 1.0f/m_size.width(), 0.0f, 0.0f, - 0.0f, -1.0f/m_size.height(), 0.0f, - 0.0f, m_size.height()/(float)m_size.height(), 1.0f }; - } else { - m_transformMatrix = { 1.0f/m_size.width(), 0.0f, 0.0f, - 0.0f, 1.0f/m_size.height(), 0.0f, - 0.0f, 0.0f, 1.0f }; - } -} - -void Texture::setupPixels(int level, const Size& size, uchar* pixels, int channels, bool compress) -{ - GLenum format = 0; - switch(channels) { - case 4: - format = GL_RGBA; - break; - case 3: - format = GL_RGB; - break; - case 2: - format = GL_LUMINANCE_ALPHA; - break; - case 1: - format = GL_LUMINANCE; - break; - } - - GLenum internalFormat = GL_RGBA; - glTexImage2D(GL_TEXTURE_2D, level, internalFormat, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, pixels); -} diff --git a/src/framework/graphics/texture.h b/src/framework/graphics/texture.h deleted file mode 100644 index 09f78e9..0000000 --- a/src/framework/graphics/texture.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef TEXTURE_H -#define TEXTURE_H - -#include "declarations.h" - -class Texture : public stdext::shared_object -{ - static uint uniqueId; -public: - Texture(const Size& size, bool depthTexture = false, bool smooth = false, bool upsideDown = false); - Texture(const ImagePtr& image, bool buildMipmaps = false, bool compress = false, bool smooth = false); - virtual ~Texture(); - virtual void replace(const ImagePtr& image); - void resize(const Size& size); - - // update must be called always before drawing, only this function can use opengl functions - virtual void update(); - - virtual void setUpsideDown(bool upsideDown); - virtual void setSmooth(bool smooth); - virtual void setRepeat(bool repeat); - virtual bool buildHardwareMipmaps(); - void setTime(ticks_t time) { m_time = time; } - - uint getId() { return m_id; } - uint getUniqueId() { return m_uniqueId; } - ticks_t getTime() { return m_time; } - int getWidth() { return m_size.width(); } - int getHeight() { return m_size.height(); } - const Size& getSize() { return m_size; } - const Matrix3& getTransformMatrix() { return m_transformMatrix; } - bool isEmpty() { return false; } - bool hasRepeat() { return m_repeat; } - bool hasMipmaps() { return m_hasMipmaps; } - virtual bool isAnimatedTexture() { return false; } - -protected: - - void uploadPixels(const ImagePtr& image, bool buildMipmaps = false, bool compress = false); - - void setupSize(const Size& size); - void setupWrap(); - void setupFilters(); - void setupTranformMatrix(); - void setupPixels(int level, const Size& size, uchar *pixels, int channels = 4, bool compress = false); - - uint m_id = 0; - uint m_uniqueId = 0; - ticks_t m_time = 0; - Size m_size; - Matrix3 m_transformMatrix; - bool m_hasMipmaps = false; - bool m_smooth = false; - bool m_upsideDown = false; - bool m_repeat = false; - bool m_buildHardwareMipmaps = false; - bool m_needsUpdate = false; - ImagePtr m_image; -}; - -#endif diff --git a/src/framework/http/http.cpp b/src/framework/http/http.cpp deleted file mode 100644 index b680c6c..0000000 --- a/src/framework/http/http.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include -#include -#include -#include - -#include "http.h" -#include "session.h" -#include "websocket.h" - -Http g_http; - -void Http::init() { - m_working = true; - m_thread = std::thread([&] { - m_ios.run(); - }); -} - -void Http::terminate() { - if (!m_working) - return; - m_working = false; - for (auto& ws : m_websockets) { - ws.second->close(); - } - for (auto& op : m_operations) { - op.second->canceled = true; - } - m_guard.reset(); - if (!m_thread.joinable()) { - stdext::millisleep(100); - m_ios.stop(); - } - m_thread.join(); -} - -int Http::get(const std::string& url, int timeout) { - if (!timeout) // lua is not working with default values - timeout = 5; - int operationId = m_operationId++; - - boost::asio::post(m_ios, [&, url, timeout, operationId] { - auto result = std::make_shared(); - result->url = url; - result->operationId = operationId; - m_operations[operationId] = result; - auto session = std::make_shared(m_ios, url, timeout, result, [&](HttpResult_ptr result) { - bool finished = result->finished; - g_dispatcher.addEventEx("Http::onGet", [result, finished]() { - if (!finished) { - g_lua.callGlobalField("g_http", "onGetProgress", result->operationId, result->url, result->progress); - return; - } - g_lua.callGlobalField("g_http", "onGet", result->operationId, result->url, result->error, std::string(result->response.begin(), result->response.end())); - }); - if (finished) { - m_operations.erase(operationId); - } - }); - session->start(); - }); - - return operationId; -} - -int Http::post(const std::string& url, const std::string& data, int timeout) { - if (!timeout) // lua is not working with default values - timeout = 5; - if (data.empty()) { - g_logger.error(stdext::format("Invalid post request for %s, empty data, use get instead", url)); - return -1; - } - - int operationId = m_operationId++; - boost::asio::post(m_ios, [&, url, data, timeout, operationId] { - auto result = std::make_shared(); - result->url = url; - result->operationId = operationId; - result->postData = data; - m_operations[operationId] = result; - auto session = std::make_shared(m_ios, url, timeout, result, [&](HttpResult_ptr result) { - bool finished = result->finished; - g_dispatcher.addEventEx("Http::onPost", [result, finished]() { - if (!finished) { - g_lua.callGlobalField("g_http", "onPostProgress", result->operationId, result->url, result->progress); - return; - } - g_lua.callGlobalField("g_http", "onPost", result->operationId, result->url, result->error, std::string(result->response.begin(), result->response.end())); - }); - if (finished) { - m_operations.erase(operationId); - } - }); - session->start(); - }); - return operationId; -} - -int Http::download(const std::string& url, std::string path, int timeout) { - if (!timeout) // lua is not working with default values - timeout = 5; - - int operationId = m_operationId++; - boost::asio::post(m_ios, [&, url, path, timeout, operationId] { - auto result = std::make_shared(); - result->url = url; - result->operationId = operationId; - m_operations[operationId] = result; - auto session = std::make_shared(m_ios, url, timeout, result, [&, path](HttpResult_ptr result) { - m_speed = ((result->size) * 10) / (1 + stdext::micros() - m_lastSpeedUpdate); - m_lastSpeedUpdate = stdext::micros(); - - if (!result->finished) { - int speed = m_speed; - g_dispatcher.addEventEx("Http::onDownloadProgress", [result, speed]() { - g_lua.callGlobalField("g_http", "onDownloadProgress", result->operationId, result->url, result->progress, speed); - }); - return; - } - std::string checksum = g_crypt.crc32(std::string(result->response.begin(), result->response.end()), false); - g_dispatcher.addEventEx("Http::onDownload", [&, result, path, checksum]() { - if (result->error.empty()) { - if (!path.empty() && path[0] == '/') - m_downloads[path.substr(1)] = result; - else - m_downloads[path] = result; - } - g_lua.callGlobalField("g_http", "onDownload", result->operationId, result->url, result->error, path, checksum); - }); - m_operations.erase(operationId); - }); - session->start(); - }); - return operationId; -} - -int Http::ws(const std::string& url, int timeout) -{ - if (!timeout) // lua is not working with default values - timeout = 5; - int operationId = m_operationId++; - - boost::asio::post(m_ios, [&, url, timeout, operationId] { - auto result = std::make_shared(); - result->url = url; - result->operationId = operationId; - m_operations[operationId] = result; - auto session = std::make_shared(m_ios, url, timeout, result, [&, result](WebsocketCallbackType type, std::string message) { - g_dispatcher.addEventEx("Http::ws", [result, type, message]() { - if (type == WEBSOCKET_OPEN) { - g_lua.callGlobalField("g_http", "onWsOpen", result->operationId, message); - } else if (type == WEBSOCKET_MESSAGE) { - g_lua.callGlobalField("g_http", "onWsMessage", result->operationId, message); - } else if (type == WEBSOCKET_CLOSE) { - g_lua.callGlobalField("g_http", "onWsClose", result->operationId, message); - } else if (type == WEBSOCKET_ERROR) { - g_lua.callGlobalField("g_http", "onWsError", result->operationId, message); - } - }); - if (type == WEBSOCKET_CLOSE) { - m_websockets.erase(result->operationId); - } - }); - m_websockets[result->operationId] = session; - session->start(); - }); - - return operationId; -} - -bool Http::wsSend(int operationId, std::string message) -{ - boost::asio::post(m_ios, [&, operationId, message] { - auto wit = m_websockets.find(operationId); - if (wit == m_websockets.end()) { - return; - } - wit->second->send(message); - }); - return true; -} - -bool Http::wsClose(int operationId) -{ - cancel(operationId); - return true; -} - - -bool Http::cancel(int id) { - boost::asio::post(m_ios, [&, id] { - auto wit = m_websockets.find(id); - if (wit != m_websockets.end()) { - wit->second->close(); - } - auto it = m_operations.find(id); - if (it == m_operations.end()) - return; - if (it->second->canceled) - return; - it->second->canceled = true; - }); - return true; -} - diff --git a/src/framework/http/http.h b/src/framework/http/http.h deleted file mode 100644 index 1b34fc2..0000000 --- a/src/framework/http/http.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef HTTP_H -#define HTTP_H - -#include -#include "result.h" - -class WebsocketSession; - -class Http { -public: - Http() : m_ios(), m_guard(boost::asio::make_work_guard(m_ios)) {} - - void init(); - void terminate(); - - int get(const std::string& url, int timeout = 5); - int post(const std::string& url, const std::string& data, int timeout = 5); - int download(const std::string& url, std::string path, int timeout = 5); - int ws(const std::string& url, int timeout = 5); - bool wsSend(int operationId, std::string message); - bool wsClose(int operationId); - - bool cancel(int id); - - const std::map& downloads() { - return m_downloads; - } - void clearDownloads() { - m_downloads.clear(); - } - HttpResult_ptr getFile(std::string path) { - if (!path.empty() && path[0] == '/') - path = path.substr(1); - auto it = m_downloads.find(path); - if (it == m_downloads.end()) - return nullptr; - return it->second; - } - -private: - bool m_working = false; - int m_operationId = 1; - int m_speed = 0; - size_t m_lastSpeedUpdate = 0; - std::thread m_thread; - boost::asio::io_context m_ios; - boost::asio::executor_work_guard m_guard; - std::map m_operations; - std::map> m_websockets; - std::map m_downloads; -}; - -extern Http g_http; - -#endif // ! HTTP_H diff --git a/src/framework/http/result.h b/src/framework/http/result.h deleted file mode 100644 index c37e876..0000000 --- a/src/framework/http/result.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -struct HttpResult { - std::string url; - int operationId = 0; - int status = 0; - int size = 0; - int progress = 0; // from 0 to 100 - int redirects = 0; // redirect - bool connected = false; - bool finished = false; - bool canceled = false; - std::string postData; - std::vector response; - std::string error; -}; - - -using HttpResult_ptr = std::shared_ptr; -using HttpResult_cb = std::function; diff --git a/src/framework/input/mouse.cpp b/src/framework/input/mouse.cpp deleted file mode 100644 index 615cd74..0000000 --- a/src/framework/input/mouse.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "mouse.h" -#include -#include -#include -#include - -Mouse g_mouse; - -void Mouse::init() -{ -} - -void Mouse::terminate() -{ - m_cursors.clear(); -} - -void Mouse::loadCursors(std::string filename) -{ - filename = g_resources.guessFilePath(filename, "otml"); - try { - OTMLDocumentPtr doc = OTMLDocument::parse(filename); - OTMLNodePtr cursorsNode = doc->at("Cursors"); - - for(const OTMLNodePtr& cursorNode : cursorsNode->children()) - addCursor(cursorNode->tag(), - stdext::resolve_path(cursorNode->valueAt("image"), cursorNode->source()), - cursorNode->valueAt("hot-spot")); - } catch(stdext::exception& e) { - g_logger.error(stdext::format("unable to load cursors file: %s", e.what())); - } -} - -void Mouse::addCursor(const std::string& name, const std::string& file, const Point& hotSpot) -{ - if (g_mainThreadId != std::this_thread::get_id()) { - g_graphicsDispatcher.addEvent(std::bind(&Mouse::addCursor, this, name, file, hotSpot)); - return; - } - - int cursorId = g_window.loadMouseCursor(file, hotSpot); - if(cursorId >= 0) { - m_cursors[name] = cursorId; - } else - g_logger.error(stdext::format("unable to load cursor %s", name)); -} - -void Mouse::pushCursor(const std::string& name) -{ - if (g_mainThreadId != std::this_thread::get_id()) { - g_graphicsDispatcher.addEvent(std::bind(&Mouse::pushCursor, this, name)); - return; - } - - auto it = m_cursors.find(name); - if(it == m_cursors.end()) - return; - - int cursorId = it->second; - g_window.setMouseCursor(cursorId); - std::lock_guard lock(m_mutex); - m_cursorStack.push_back(cursorId); - return; -} - -void Mouse::popCursor(const std::string& name) -{ - if (g_mainThreadId != std::this_thread::get_id()) { - g_graphicsDispatcher.addEvent(std::bind(&Mouse::popCursor, this, name)); - return; - } - - std::lock_guard lock(m_mutex); - if(m_cursorStack.size() == 0) - return; - - if(name.empty() || m_cursors.find(name) == m_cursors.end()) - m_cursorStack.pop_back(); - else { - int cursorId = m_cursors[name]; - int index = -1; - for(uint i=0;i= 0) - m_cursorStack.erase(m_cursorStack.begin() + index); - else - return; - } - - if(m_cursorStack.size() > 0) - g_window.setMouseCursor(m_cursorStack.back()); - else - g_window.restoreMouseCursor(); -} - -bool Mouse::isCursorChanged() -{ - std::lock_guard lock(m_mutex); - return m_cursorStack.size() > 0; -} - -bool Mouse::isPressed(Fw::MouseButton mouseButton) -{ - return g_window.isMouseButtonPressed(mouseButton); -} diff --git a/src/framework/input/mouse.h b/src/framework/input/mouse.h deleted file mode 100644 index a1b86fc..0000000 --- a/src/framework/input/mouse.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -class Mouse -{ -public: - void init(); - void terminate(); - - void loadCursors(std::string filename); - void addCursor(const std::string& name, const std::string& file, const Point& hotSpot); - void pushCursor(const std::string& name); - void popCursor(const std::string& name); - bool isCursorChanged(); - bool isPressed(Fw::MouseButton mouseButton); - -private: - std::map m_cursors; - std::deque m_cursorStack; - std::mutex m_mutex; -}; - -extern Mouse g_mouse; diff --git a/src/framework/luaengine/declarations.h b/src/framework/luaengine/declarations.h deleted file mode 100644 index 38403d7..0000000 --- a/src/framework/luaengine/declarations.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FRAMEWORK_LUA_DECLARATIONS_H -#define FRAMEWORK_LUA_DECLARATIONS_H - -#include - -#include - -class LuaInterface; -class LuaObject; - -typedef std::function LuaCppFunction; -typedef std::unique_ptr LuaCppFunctionPtr; -typedef stdext::shared_object_ptr LuaObjectPtr; - -#endif diff --git a/src/framework/luaengine/lbitlib.cpp b/src/framework/luaengine/lbitlib.cpp deleted file mode 100644 index 941cb8b..0000000 --- a/src/framework/luaengine/lbitlib.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/* - * This is the bit32 library from lua 5.2.0, backported to - * lua 5.1.4. - * - * version 5.2.0-backport4 - * - * This backport was assembled by Sean Bolton (sean at smbolton - * dot com) almost entirely from the above mentioned Lua distributions, - * which are: - * - * Copyright (C) 1994-2011 Lua.org, PUC-Rio. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#define LUA_LIB - -extern "C" { -#if defined(_MSC_VER) || defined(ANDROID) -#include -#include -#include -#else -#include -#include -#include -#endif -} - -/* ----- adapted from lua-5.2.0 luaconf.h: ----- */ - -/* -@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. -** It must have at least 32 bits. -*/ -#ifndef LUAI_INT32 -#define LUAI_INT32 int -#endif -#define LUA_UNSIGNED unsigned LUAI_INT32 - -#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ - -/* On a Microsoft compiler on a Pentium, use assembler to avoid clashes - with a DirectX idiosyncrasy */ -#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ - -#define MS_ASMTRICK - -#else /* }{ */ -/* the next definition uses a trick that should work on any machine - using IEEE754 with a 32-bit integer type */ - -#define LUA_IEEE754TRICK - -/* -@@ LUA_IEEEENDIAN is the endianness of doubles in your machine -** (0 for little endian, 1 for big endian); if not defined, Lua will -** check it dynamically. -*/ -/* check for known architectures */ -#if defined(__i386__) || defined(__i386) || defined(__X86__) || \ - defined (__x86_64) -#define LUA_IEEEENDIAN 0 -#elif defined(__POWERPC__) || defined(__ppc__) -#define LUA_IEEEENDIAN 1 -#endif - -#endif /* } */ - -#endif /* } */ - -/* ----- from lua-5.2.0 lua.h: ----- */ - -/* unsigned integer type */ -typedef LUA_UNSIGNED lua_Unsigned; - -/* ----- adapted from lua-5.2.0 llimits.h: ----- */ - -/* lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. -** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. -*/ - -#if defined(MS_ASMTRICK) /* { */ -/* trick with Microsoft assembler for X86 */ - -#define lua_number2unsigned(i,n) \ - {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} - -#elif defined(LUA_IEEE754TRICK) /* }{ */ -/* the next trick should work on any machine using IEEE754 with - a 32-bit integer type */ - -union luai_Cast2 { double l_d; LUAI_INT32 l_p[2]; }; - -#if !defined(LUA_IEEEENDIAN) /* { */ -#define LUAI_EXTRAIEEE \ - static const union luai_Cast2 ieeeendian = {-(33.0 + 6755399441055744.0)}; -#define LUA_IEEEENDIAN (ieeeendian.l_p[1] == 33) -#else -#define LUAI_EXTRAIEEE /* empty */ -#endif /* } */ - -#define lua_number2int32(i,n,t) \ - { LUAI_EXTRAIEEE \ - volatile union luai_Cast2 u; u.l_d = (n) + 6755399441055744.0; \ - (i) = (t)u.l_p[LUA_IEEEENDIAN]; } - -#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) - -#endif /* } */ - -#if !defined(lua_number2unsigned) /* { */ -/* the following definition assures proper modulo behavior */ -#if defined(LUA_NUMBER_DOUBLE) -#include -#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) -#define lua_number2unsigned(i,n) \ - ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) -#else -#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) -#endif -#endif /* } */ - -/* on several machines, coercion from unsigned to double is slow, - so it may be worth to avoid */ -#define lua_unsigned2number(u) \ - (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) - -/* ----- adapted from lua-5.2.0 lapi.c: ----- */ - -static void lua_pushunsigned (lua_State *L, lua_Unsigned u) { - lua_Number n; - n = lua_unsigned2number(u); - lua_pushnumber(L, n); -} - -/* ----- adapted from lua-5.2.0-work3 lbitlib.c getuintarg(): ----- */ - -static lua_Unsigned luaL_checkunsigned (lua_State *L, int arg) { - lua_Unsigned r; - lua_Number x = lua_tonumber(L, arg); - if (x == 0) luaL_checktype(L, arg, LUA_TNUMBER); - lua_number2unsigned(r, x); - return r; -} - -/* ----- Lua 5.2 luaL_newlib() compatibility: ----- */ - -#define LUAMOD_API LUALIB_API -#define LUA_BIT32LIBNAME "bit32" -#define luaL_newlib(x, y) luaL_register(x, LUA_BIT32LIBNAME, y) - -/* ----- avoid a 'symbol redefined' warning below ----- */ - -#undef LUA_LIB - -/* ----- here follows the unmodified lbitlib.c from Lua 5.2.0 ----- */ - -/* -** $Id: lbitlib.c,v 1.16 2011/06/20 16:35:23 roberto Exp $ -** Standard library for bitwise operations -** See Copyright Notice in lua.h -*/ - -#define lbitlib_c -#define LUA_LIB - - -/* number of bits to consider in a number */ -#if !defined(LUA_NBITS) -#define LUA_NBITS 32 -#endif - - -#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) - -/* macro to trim extra bits */ -#define trim(x) ((x) & ALLONES) - - -/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ -#define mask(n) (~((ALLONES << 1) << ((n) - 1))) - - -typedef lua_Unsigned b_uint; - - - -static b_uint andaux (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = ~(b_uint)0; - for (i = 1; i <= n; i++) - r &= luaL_checkunsigned(L, i); - return trim(r); -} - - -static int b_and (lua_State *L) { - b_uint r = andaux(L); - lua_pushunsigned(L, r); - return 1; -} - - -static int b_test (lua_State *L) { - b_uint r = andaux(L); - lua_pushboolean(L, r != 0); - return 1; -} - - -static int b_or (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = 0; - for (i = 1; i <= n; i++) - r |= luaL_checkunsigned(L, i); - lua_pushunsigned(L, trim(r)); - return 1; -} - - -static int b_xor (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = 0; - for (i = 1; i <= n; i++) - r ^= luaL_checkunsigned(L, i); - lua_pushunsigned(L, trim(r)); - return 1; -} - - -static int b_not (lua_State *L) { - b_uint r = ~luaL_checkunsigned(L, 1); - lua_pushunsigned(L, trim(r)); - return 1; -} - - -static int b_shift (lua_State *L, b_uint r, int i) { - if (i < 0) { /* shift right? */ - i = -i; - r = trim(r); - if (i >= LUA_NBITS) r = 0; - else r >>= i; - } - else { /* shift left */ - if (i >= LUA_NBITS) r = 0; - else r <<= i; - r = trim(r); - } - lua_pushunsigned(L, r); - return 1; -} - - -static int b_lshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); -} - - -static int b_rshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); -} - - -static int b_arshift (lua_State *L) { - b_uint r = luaL_checkunsigned(L, 1); - int i = luaL_checkint(L, 2); - if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) - return b_shift(L, r, -i); - else { /* arithmetic shift for 'negative' number */ - if (i >= LUA_NBITS) r = ALLONES; - else - r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ - lua_pushunsigned(L, r); - return 1; - } -} - - -static int b_rot (lua_State *L, int i) { - b_uint r = luaL_checkunsigned(L, 1); - i &= (LUA_NBITS - 1); /* i = i % NBITS */ - r = trim(r); - r = (r << i) | (r >> (LUA_NBITS - i)); - lua_pushunsigned(L, trim(r)); - return 1; -} - - -static int b_lrot (lua_State *L) { - return b_rot(L, luaL_checkint(L, 2)); -} - - -static int b_rrot (lua_State *L) { - return b_rot(L, -luaL_checkint(L, 2)); -} - - -/* -** get field and width arguments for field-manipulation functions, -** checking whether they are valid -*/ -static int fieldargs (lua_State *L, int farg, int *width) { - int f = luaL_checkint(L, farg); - int w = luaL_optint(L, farg + 1, 1); - luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); - luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); - if (f + w > LUA_NBITS) - luaL_error(L, "trying to access non-existent bits"); - *width = w; - return f; -} - - -static int b_extract (lua_State *L) { - int w; - b_uint r = luaL_checkunsigned(L, 1); - int f = fieldargs(L, 2, &w); - r = (r >> f) & mask(w); - lua_pushunsigned(L, r); - return 1; -} - - -static int b_replace (lua_State *L) { - int w; - b_uint r = luaL_checkunsigned(L, 1); - b_uint v = luaL_checkunsigned(L, 2); - int f = fieldargs(L, 3, &w); - int m = mask(w); - v &= m; /* erase bits outside given width */ - r = (r & ~(m << f)) | (v << f); - lua_pushunsigned(L, r); - return 1; -} - - -static const luaL_Reg bitlib[] = { - {"arshift", b_arshift}, - {"band", b_and}, - {"bnot", b_not}, - {"bor", b_or}, - {"bxor", b_xor}, - {"btest", b_test}, - {"extract", b_extract}, - {"lrotate", b_lrot}, - {"lshift", b_lshift}, - {"replace", b_replace}, - {"rrotate", b_rrot}, - {"rshift", b_rshift}, - {NULL, NULL} -}; - -int luaopen_bit32 (lua_State *L) { - luaL_newlib(L, bitlib); - return 1; -} - -#undef trim - diff --git a/src/framework/luaengine/lbitlib.h b/src/framework/luaengine/lbitlib.h deleted file mode 100644 index bb8f1ba..0000000 --- a/src/framework/luaengine/lbitlib.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LBITLIB_520_BACKPORT4_H -#define LBITLIB_520_BACKPORT4_H - -struct lua_State; - -int luaopen_bit32 (lua_State *L); - -#endif diff --git a/src/framework/luaengine/luabinder.h b/src/framework/luaengine/luabinder.h deleted file mode 100644 index f2b3dd2..0000000 --- a/src/framework/luaengine/luabinder.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LUABINDER_H -#define LUABINDER_H - -// this file is and must be included only from luainterface.h -#include "luainterface.h" -#include "luaexception.h" - -#include -#include - -/// This namespace contains some dirty metaprogamming that uses a lot of C++0x features -/// The purpose here is to create templates that can bind any function from C++ -/// and expose in lua environment. This is done combining variadic templates, -/// lambdas, tuples and some type traits features from the new C++0x standard to create -/// templates that can detect functions's arguments and then generate lambdas. These lambdas -/// pops arguments from lua stack, call the bound C++ function and then -/// pushes the result to lua. -namespace luabinder -{ - /// Pack arguments from lua stack into a tuple recursively - template - struct pack_values_into_tuple { - template - static void call(Tuple& tuple, LuaInterface* lua) { - typedef typename std::tuple_element::type ValueType; - std::get(tuple) = lua->polymorphicPop(); - pack_values_into_tuple::call(tuple, lua); - } - }; - template<> - struct pack_values_into_tuple<0> { - template - static void call(Tuple& tuple, LuaInterface* lua) { } - }; - - /// C++ function caller that can push results to lua - template - typename std::enable_if::value, int>::type - call_fun_and_push_result(const F& f, LuaInterface* lua, const Args&... args) { - Ret ret = f(args...); - int numRets = lua->polymorphicPush(ret); - return numRets; - } - - /// C++ void function caller - template - typename std::enable_if::value, int>::type - call_fun_and_push_result(const F& f, LuaInterface* lua, const Args&... args) { - f(args...); - return 0; - } - - /// Expand arguments from tuple for later calling the C++ function - template - struct expand_fun_arguments { - template - static int call(const Tuple& tuple, const F& f, LuaInterface* lua, const Args&... args) { - return expand_fun_arguments::call(tuple, f, lua, std::get(tuple), args...); - } - }; - template - struct expand_fun_arguments<0,Ret> { - template - static int call(const Tuple& tuple, const F& f, LuaInterface* lua, const Args&... args) { - return call_fun_and_push_result(f, lua, args...); - } - }; - - /// Bind different types of functions generating a lambda - template - LuaCppFunction bind_fun_specializer(const F& f) { - enum { N = std::tuple_size::value }; - return [=](LuaInterface* lua) -> int { - while(lua->stackSize() != N) { - if(lua->stackSize() < N) - g_lua.pushNil(); - else - g_lua.pop(); - } - Tuple tuple; - pack_values_into_tuple::call(tuple, lua); - return expand_fun_arguments::call(tuple, f, lua); - }; - } - - /// Bind a customized function - inline - LuaCppFunction bind_fun(const std::function& f) { - return f; - } - - /// Bind a std::function - template - LuaCppFunction bind_fun(const std::function& f) { - typedef typename std::tuple::type...> Tuple; - return bind_fun_specializer::type, - decltype(f), - Tuple>(f); - } - - /// Specialization for lambdas - template - struct bind_lambda_fun; - - template - struct bind_lambda_fun { - static LuaCppFunction call(const Lambda& f) { - typedef typename std::tuple::type...> Tuple; - return bind_fun_specializer::type, - decltype(f), - Tuple>(f); - - } - }; - - template - typename std::enable_if::value, LuaCppFunction>::type bind_fun(const Lambda& f) { - typedef decltype(&Lambda::operator()) F; - return bind_lambda_fun::call(f); - } - - /// Convert to C++ functions pointers to std::function then bind - template - LuaCppFunction bind_fun(Ret (*f)(Args...)) { - return bind_fun(std::function(f)); - } - - /// Create member function lambdas - template - std::function&, const Args&...)> make_mem_func(Ret (C::* f)(Args...)) { - auto mf = std::mem_fn(f); - return [=](const stdext::shared_object_ptr& obj, const Args&... args) mutable -> Ret { - if(!obj) - throw LuaException("failed to call a member function because the passed object is nil"); - return mf(obj.get(), args...); - }; - } - template - std::function&, const Args&...)> make_mem_func(void (C::* f)(Args...)) { - auto mf = std::mem_fn(f); - return [=](const stdext::shared_object_ptr& obj, const Args&... args) mutable -> void { - if(!obj) - throw LuaException("failed to call a member function because the passed object is nil"); - mf(obj.get(), args...); - }; - } - - /// Create member function lambdas for singleton classes - template - std::function make_mem_func_singleton(Ret (C::* f)(Args...), C* instance) { - auto mf = std::mem_fn(f); - return [=](Args... args) mutable -> Ret { return mf(instance, args...); }; - } - template - std::function make_mem_func_singleton(void (C::* f)(Args...), C* instance) { - auto mf = std::mem_fn(f); - return [=](Args... args) mutable -> void { mf(instance, args...); }; - } - - - /// Bind member functions - template - LuaCppFunction bind_mem_fun(Ret (FC::* f)(Args...)) { - typedef typename std::tuple, typename stdext::remove_const_ref::type...> Tuple; - auto lambda = make_mem_func(f); - return bind_fun_specializer::type, - decltype(lambda), - Tuple>(lambda); - } - - /// Bind singleton member functions - template - LuaCppFunction bind_singleton_mem_fun(Ret (FC::*f)(Args...), C *instance) { - typedef typename std::tuple::type...> Tuple; - VALIDATE(instance); - auto lambda = make_mem_func_singleton(f, static_cast(instance)); - return bind_fun_specializer::type, - decltype(lambda), - Tuple>(lambda); - } - - /// Bind customized member functions - template - LuaCppFunction bind_mem_fun(int (C::*f)(LuaInterface*)) { - auto mf = std::mem_fn(f); - return [=](LuaInterface* lua) mutable -> int { - auto obj = lua->castValue>(1); - lua->remove(1); - return mf(obj, lua); - }; - } -} - -#endif diff --git a/src/framework/luaengine/luaexception.cpp b/src/framework/luaengine/luaexception.cpp deleted file mode 100644 index 10fbb27..0000000 --- a/src/framework/luaengine/luaexception.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "luaexception.h" -#include "luainterface.h" - -LuaException::LuaException(const std::string& error, int traceLevel) -{ - //g_lua.clearStack(); // on every exception, clear lua stack - generateLuaErrorMessage(error, traceLevel); -} - -void LuaException::generateLuaErrorMessage(const std::string& error, int traceLevel) -{ - // append trace level to error message - if(traceLevel >= 0) - m_what = stdext::format("LUA ERROR: %s", g_lua.traceback(error, traceLevel)); - else - m_what = stdext::format("LUA ERROR:\n%s", error); -} - -LuaBadNumberOfArgumentsException::LuaBadNumberOfArgumentsException(int expected, int got) -{ - std::string error = "attempt to call a function with wrong number of arguments"; - if(expected >= 0 && got >= 0) - error = stdext::format("%s (expected %d, but got %d)", error, expected, got); - generateLuaErrorMessage(error, 1); -} - -LuaBadValueCastException::LuaBadValueCastException(const std::string& luaTypeName, const std::string& cppTypeName) -{ - std::string error = stdext::format("attempt to cast a '%s' lua value to '%s'", luaTypeName, cppTypeName); - generateLuaErrorMessage(error, 0); -} diff --git a/src/framework/luaengine/luaexception.h b/src/framework/luaengine/luaexception.h deleted file mode 100644 index 2eedbdb..0000000 --- a/src/framework/luaengine/luaexception.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LUAEXCEPTION_H -#define LUAEXCEPTION_H - -#include "declarations.h" - -class LuaException : public stdext::exception -{ -public: - LuaException(const std::string& error, int traceLevel = -1); - virtual ~LuaException() throw() { } - - void generateLuaErrorMessage(const std::string& error, int traceLevel); - - virtual const char* what() const throw() { return m_what.c_str(); } - -protected: - LuaException() { } - - std::string m_what; -}; - -class LuaBadNumberOfArgumentsException : public LuaException -{ -public: - LuaBadNumberOfArgumentsException(int expected = -1, int got = -1); -}; - -class LuaBadValueCastException : public LuaException -{ -public: - LuaBadValueCastException(const std::string& luaTypeName, const std::string& cppTypeName); -}; - -#endif diff --git a/src/framework/luaengine/luainterface.cpp b/src/framework/luaengine/luainterface.cpp deleted file mode 100644 index 916866e..0000000 --- a/src/framework/luaengine/luainterface.cpp +++ /dev/null @@ -1,1394 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "luainterface.h" -#include "luaobject.h" - -#include -#include -#if defined(_MSC_VER) || defined(ANDROID) -#include -#else -#include -#endif - -#include "lbitlib.h" - -LuaInterface g_lua; - -LuaInterface::LuaInterface() -{ - L = nullptr; - m_cppCallbackDepth = 0; - m_weakTableRef = 0; - m_totalObjRefs = 0; - m_totalFuncRefs = 0; -} - -LuaInterface::~LuaInterface() -{ -} - -void LuaInterface::init() -{ - createLuaState(); - - // store global environment reference - pushThread(); - getEnv(); - m_globalEnv = ref(); - pop(); - - // check if demangle_class is working as expected - VALIDATE(stdext::demangle_class() == "LuaObject"); - - // register LuaObject, the base of all other objects - registerClass(); - bindClassMemberFunction("getUseCount", &LuaObject::getUseCount); - bindClassMemberFunction("getClassName", &LuaObject::getClassName); - - registerClassMemberFunction("getFieldsTable", (LuaCppFunction) ([](LuaInterface* lua) -> int { - LuaObjectPtr obj = g_lua.popObject(); - obj->luaGetFieldsTable(); - return 1; - })); -} - -void LuaInterface::terminate() -{ - // close lua state, it will release all objects - closeLuaState(); - VALIDATE(m_totalFuncRefs == 0); - VALIDATE(m_totalObjRefs == 0); -} - -void LuaInterface::registerSingletonClass(const std::string& className) -{ - newTable(); - pushValue(); - setGlobal(className); - pop(); -} - -void LuaInterface::registerClass(const std::string& className, const std::string& baseClass) -{ - // creates the class table (that it's also the class methods table) - newTable(); - pushValue(); - setGlobal(className); - const int klass = getTop(); - - // creates the class fieldmethods table - newTable(); - pushValue(); - setGlobal(className + "_fieldmethods"); - int klass_fieldmethods = getTop(); - - // creates the class metatable - newTable(); - pushValue(); - setGlobal(className + "_mt"); - int klass_mt = getTop(); - - // set metatable metamethods - pushCppFunction(&LuaInterface::luaObjectGetEvent); - setField("__index", klass_mt); - pushCppFunction(&LuaInterface::luaObjectSetEvent); - setField("__newindex", klass_mt); - pushCppFunction(&LuaInterface::luaObjectEqualEvent); - setField("__eq", klass_mt); - pushCppFunction(&LuaInterface::luaObjectCollectEvent); - setField("__gc", klass_mt); - - // set some fields that will be used later in metatable - pushValue(klass); - setField("methods", klass_mt); - pushValue(klass_fieldmethods); - setField("fieldmethods", klass_mt); - - // redirect methods and fieldmethods to the base class ones - if(!className.empty() && className != "LuaObject") { - // the following code is what create classes hierarchy for lua, by reproducing: - // DerivedClass = { __index = BaseClass } - // DerivedClass_fieldmethods = { __index = BaseClass_methods } - - // redirect the class methods to the base methods - pushValue(klass); - newTable(); - getGlobal(baseClass); - setField("__index"); - setMetatable(); - pop(); - - // redirect the class fieldmethods to the base fieldmethods - pushValue(klass_fieldmethods); - newTable(); - getGlobal(baseClass + "_fieldmethods"); - setField("__index"); - setMetatable(); - pop(); - } - - // pops klass, klass_mt, klass_fieldmethods - pop(3); -} - -void LuaInterface::registerClassStaticFunction(const std::string& className, - const std::string& functionName, - const LuaCppFunction& function) -{ - registerClassMemberFunction(className, functionName, function); -} - -void LuaInterface::registerClassMemberFunction(const std::string& className, - const std::string& functionName, - const LuaCppFunction& function) -{ - getGlobal(className); - pushCppFunction(function); - setField(functionName); - pop(); -} - -void LuaInterface::registerClassMemberField(const std::string& className, - const std::string& field, - const LuaCppFunction& getFunction, - const LuaCppFunction& setFunction) -{ - getGlobal(className + "_fieldmethods"); - - if(getFunction) { - pushCppFunction(getFunction); - setField(stdext::format("get_%s", field)); - } - - if(setFunction) { - pushCppFunction(setFunction); - setField(stdext::format("set_%s", field)); - } - - pop(); -} - -void LuaInterface::registerGlobalFunction(const std::string& functionName, const LuaCppFunction& function) -{ - pushCppFunction(function); - setGlobal(functionName); -} - -int LuaInterface::luaObjectGetEvent(LuaInterface* lua) -{ - // stack: obj, key - LuaObjectPtr obj = lua->toObject(-2); - std::string key = lua->toString(-1); - VALIDATE(obj); - - lua->remove(-1); // removes key - - // if a get method for this key exists, calls it - lua->getMetatable(); // pushes obj metatable - lua->getField("fieldmethods"); // push obj fieldmethods - lua->remove(-2); // removes obj metatable - lua->getField(std::string("get_") + key); // pushes get method - lua->remove(-2); // remove obj fieldmethods - if(!lua->isNil()) { // is the get method not nil? - lua->insert(-2); // moves obj to the top - lua->signalCall(1, 1); // calls get method, arguments: obj - return 1; - } - lua->pop(); // pops the nil get method - - // if the field for this key exists, returns it - obj->luaGetField(key); - if(!lua->isNil()) { - lua->remove(-2); // removes the obj - // field value is on the stack - return 1; - } - lua->pop(); // pops the nil field - - // pushes the method assigned by this key - lua->getMetatable(); // pushes obj metatable - lua->getField("methods"); // push obj methods - lua->remove(-2); // removes obj metatable - lua->getField(key); // pushes obj method - lua->remove(-2); // remove obj methods - lua->remove(-2); // removes obj - - // the result value is on the stack - return 1; -} - -int LuaInterface::luaObjectSetEvent(LuaInterface* lua) -{ - // stack: obj, key, value - LuaObjectPtr obj = lua->toObject(-3); - std::string key = lua->toString(-2); - VALIDATE(obj); - - lua->remove(-2); // removes key - lua->insert(-2); // moves obj to the top - - // check if a set method for this field exists and call it - lua->getMetatable(); // pushes obj metatable - lua->getField("fieldmethods"); // push obj fieldmethods - lua->remove(-2); // removes obj metatable - lua->getField(std::string("set_") + key); // pushes set method - lua->remove(-2); // remove obj fieldmethods - if(!lua->isNil()) { // is the set method not nil? - lua->insert(-3); // moves func to -3 - lua->insert(-2); // moves obj to -2, and value to -1 - lua->signalCall(2, 0); // calls set method, arguments: obj, value - return 0; - } - lua->pop(); // pops the nil set method - - // no set method exists, then treats as an field and set it - lua->pop(); // pops the object - obj->luaSetField(key); // sets the obj field - return 0; -} - -int LuaInterface::luaObjectEqualEvent(LuaInterface* lua) -{ - // stack: obj1, obj2 - bool ret = false; - - // check if obj1 == obj2 - if(lua->isUserdata(-1) && lua->isUserdata(-2)) { - LuaObjectPtr* objPtr2 = static_cast(lua->popUserdata()); - LuaObjectPtr* objPtr1 = static_cast(lua->popUserdata()); - VALIDATE(objPtr1 && objPtr2); - if(*objPtr1 == *objPtr2) - ret = true; - } else - lua->pop(2); - - lua->pushBoolean(ret); - return 1; -} - -int LuaInterface::luaObjectCollectEvent(LuaInterface* lua) -{ - // gets object pointer - auto objPtr = static_cast(lua->popUserdata()); - VALIDATE(objPtr); - - // resets pointer to decrease object use count - objPtr->reset(); - g_lua.m_totalObjRefs--; - return 0; -} - - -/////////////////////////////////////////////////////////////////////////////// - - -bool LuaInterface::safeRunScript(const std::string& fileName) -{ - try { - runScript(fileName); - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Failed to load script '%s': %s", fileName, e.what())); - return false; - } -} - -void LuaInterface::runScript(const std::string& fileName) -{ - loadScript(fileName); - safeCall(0, 0); -} - -void LuaInterface::runBuffer(const std::string& buffer, const std::string& source) -{ - loadBuffer(buffer, source); - safeCall(0, 0); -} - -void LuaInterface::loadScript(const std::string& fileName) -{ - // resolve file full path - std::string filePath = fileName; - if(!stdext::starts_with(fileName, "/")) - filePath = getCurrentSourcePath() + "/" + filePath; - - filePath = g_resources.guessFilePath(filePath, "lua"); - - std::string buffer = g_resources.readFileContents(filePath); - std::string source = std::string("@") + filePath; - loadBuffer(buffer, source); -} - -void LuaInterface::loadFunction(const std::string& buffer, const std::string& source) -{ - if(buffer.empty()) { - pushNil(); - return; - } - - std::string buf; - if(stdext::starts_with(buffer, "function")) - buf = stdext::format("__func = %s", buffer); - else - buf = stdext::format("__func = function(self)\n%s\nend", buffer); - - loadBuffer(buf, source); - safeCall(); - - // get the function - getGlobal("__func"); - - // reset the global __func - pushNil(); - setGlobal("__func"); -} - -void LuaInterface::evaluateExpression(const std::string& expression, const std::string& source) -{ - // evaluates the expression - if(!expression.empty()) { - std::string buffer = stdext::format("__exp = (%s)", expression); - loadBuffer(buffer, source); - safeCall(); - - // gets the expression result - getGlobal("__exp"); - - // resets global __exp - pushNil(); - setGlobal("__exp"); - } else - pushNil(); -} - -std::string LuaInterface::traceback(const std::string& errorMessage, int level) -{ - // gets debug.traceback - getGlobal("debug"); - getField("traceback"); - remove(-2); // remove debug - - // calls debug.traceback(errorMessage, level) - pushString(errorMessage); - pushInteger(level); - call(2,1); - - // returns the traceback message - return popString(); -} - -void LuaInterface::throwError(const std::string& message) -{ - if(isInCppCallback()) { - pushString(message); - error(); - } else - throw stdext::exception(message); -} - -std::string LuaInterface::getCurrentSourcePath(int level) -{ - std::string path; - if(!L) - return path; - - // check all stack functions for script source path - while(true) { - getStackFunction(level); // pushes stack function - - // only lua functions is wanted, because only them have a working directory - if(isLuaFunction()) { - path = functionSourcePath(); - break; - } else if(isNil()) { - pop(); - break; - } else - pop(); - - // next level - level++; - } - - return path; -} - -std::string LuaInterface::getCurrentFunction(int level) -{ - std::string path = "unknown"; - if(!L) - return path; - - // check all stack functions for script source path - while(true) { - getStackFunction(level); // pushes stack function - - // only lua functions is wanted, because only them have a working directory - if(isLuaFunction()) { - path = functionSource(); - break; - } else if(isNil()) { - pop(); - break; - } else - pop(); - - // next level - level++; - } - - return path; -} - -int LuaInterface::safeCall(int numArgs, int numRets, const std::shared_ptr& error) -{ - VALIDATE(hasIndex(-numArgs-1)); - - // saves the current stack size for calculating the number of results later - int previousStackSize = stackSize(); - - // pushes error function - int errorFuncIndex = previousStackSize - numArgs; - pushCFunction(&LuaInterface::luaErrorHandler); - insert(errorFuncIndex); - - // calls the function in protected mode (means errors will be caught) - int ret = pcall(numArgs, LUA_MULTRET, errorFuncIndex); - - remove(errorFuncIndex); // remove error func - - // if there was an error throw an exception - if (ret != 0) { - if (error) { - error->assign(popString()); - clearStack(); - return 0; - } else { - std::string errorMsg = popString(); - g_logger.error(stdext::format("Lua error: %s", errorMsg)); - throw LuaException(errorMsg); - } - } - int rets = (stackSize() + numArgs + 1) - previousStackSize; - while(numRets != -1 && rets != numRets) { - if(rets < numRets) { - pushNil(); - rets++; - } else { - pop(); - rets--; - } - } - - // returns the number of results - return rets; -} - -int LuaInterface::signalCall(int numArgs, int numRets) -{ - int rets = 0; - int funcIndex = -numArgs-1; - - try { - // must be a function - if(isFunction(funcIndex)) { - static std::shared_ptr error = std::make_shared(); - rets = safeCall(numArgs, -1, error); - if (!error->empty()) { - g_logger.error(stdext::format("protected lua call failed: %s", *error)); - error->clear(); - return rets; - } - - if(numRets != -1) { - if(rets != numRets) - throw LuaException("function call didn't return the expected number of results", 0); - } - } - // can also calls table of functions - else if(isTable(funcIndex)) { - // loop through table values - pushNil(); - bool done = false; - while(next(funcIndex-1)) { - if(isFunction()) { - // repush arguments - for(int i=0;i error = std::make_shared(); - int rets = safeCall(numArgs, -1, error); - if (!error->empty()) { - g_logger.error(stdext::format("protected lua call failed: %s", *error)); - error->clear(); - return rets; - } - if(rets == 1) { - done = popBoolean(); - if(done) { - pop(); - break; - } - } else if(rets != 0) - throw LuaException("function call didn't return the expected number of results", 0); - } else { - throw LuaException("attempt to call a non function", 0); - } - } - pop(numArgs + 1); // pops the table of function and arguments - - if(numRets == 1 || numRets == -1) { - rets = 1; - pushBoolean(done); - } - } - // nil values are ignored - else if(isNil(funcIndex)) { - pop(numArgs + 1); // pops the function and arguments - } - // if not nil, warn - else { - throw LuaException("attempt to call a non function value", 0); - } - } catch(stdext::exception& e) { - g_logger.error(stdext::format("protected lua call failed: %s", e.what())); - } - - // pushes nil values if needed - while(numRets != -1 && rets < numRets) { - pushNil(); - rets++; - } - - // returns the number of results on the stack - return rets; -} - -int LuaInterface::newSandboxEnv() -{ - newTable(); // pushes the new environment table - newTable(); // pushes the new environment metatable - getRef(getGlobalEnvironment()); // pushes the global environment - setField("__index"); // sets metatable __index to the global environment - setMetatable(); // assigns environment metatable - return ref(); // return a reference to the environment table -} - -/////////////////////////////////////////////////////////////////////////////// -// lua C functions - -int LuaInterface::luaScriptLoader(lua_State* L) -{ - // loads the script as a function - std::string fileName = g_lua.popString(); - - try { - g_lua.loadScript(fileName); - return 1; - } catch(stdext::exception& e) { - g_lua.pushString(std::string("\n\t") + e.what()); - return 1; - } -} - -int LuaInterface::lua_dofile(lua_State* L) -{ - std::string file = g_lua.popString(); - - try { - g_lua.loadScript(file); - g_lua.call(0, LUA_MULTRET); - return g_lua.stackSize(); - } catch(stdext::exception& e) { - g_lua.pushString(e.what()); - g_lua.error(); - return 0; - } -} - -int LuaInterface::lua_dofiles(lua_State* L) -{ - std::string contains = ""; - if(g_lua.getTop() > 2) { - contains = g_lua.popString(); - } - - bool recursive = false; - if(g_lua.getTop() > 1) { - recursive = g_lua.popBoolean(); - } - - std::string directory = g_lua.popString(); - g_lua.loadFiles(directory, recursive, contains); - - return 0; -} - -int LuaInterface::lua_loadfile(lua_State* L) -{ - std::string fileName = g_lua.popString(); - - try { - g_lua.loadScript(fileName); - return 1; - } catch(stdext::exception& e) { - g_lua.pushNil(); - g_lua.pushString(e.what()); - g_lua.error(); - return 2; - } -} - -int LuaInterface::luaErrorHandler(lua_State* L) -{ - // pops the error message - auto error = g_lua.popString(); - - // prevents repeated tracebacks - if(error.find("stack traceback:") == std::string::npos) - error = g_lua.traceback(error, 1); - - // pushes the new error message with traceback information - g_lua.pushString(error); - return 1; -} - -int LuaInterface::luaCppFunctionCallback(lua_State* L) -{ - // retrieves function pointer from userdata - auto funcPtr = static_cast(g_lua.popUpvalueUserdata()); - VALIDATE(funcPtr); - - int numRets = 0; - - // enable only for tests, high cpu usage - //AutoStat s(STATS_LUACALLBACK, g_lua.getCurrentFunction()); - - // do the call - try { - g_lua.m_cppCallbackDepth++; - numRets = (*(funcPtr->get()))(&g_lua); - g_lua.m_cppCallbackDepth--; - VALIDATE(numRets == g_lua.stackSize()); - } catch(stdext::exception& e) { - // cleanup stack - while(g_lua.stackSize() > 0) - g_lua.pop(); - numRets = 0; - g_lua.pushString(stdext::format("C++ call failed: %s", g_lua.traceback(e.what()))); - g_lua.error(); - } - catch (...) { - g_logger.fatal(stdext::format("Critical lua error!\nC++ call failed:\n%s|%s", g_lua.getCurrentFunction(), g_lua.traceback("fatal error"))); - } - - return numRets; -} - -int LuaInterface::luaCollectCppFunction(lua_State* L) -{ - auto funcPtr = static_cast(g_lua.popUserdata()); - VALIDATE(funcPtr); - funcPtr->reset(); - g_lua.m_totalFuncRefs--; - return 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -// from here all next functions are interfaces for the Lua API - -void LuaInterface::createLuaState() -{ - // creates lua state - L = luaL_newstate(); - if(!L) - g_logger.fatal("Unable to create lua state"); - - // load lua standard libraries - luaL_openlibs(L); - - // load bit32 lib for bitwise operations - luaopen_bit32(L); - - // creates weak table - newTable(); - newTable(); - pushString("v"); - setField("__mode"); - setMetatable(); - m_weakTableRef = ref(); - - // installs script loader - getGlobal("package"); - getField("loaders"); - pushCFunction(&LuaInterface::luaScriptLoader); - rawSeti(5); - pop(2); - - // replace dofile - pushCFunction(&LuaInterface::lua_dofile); - setGlobal("dofile"); - - // dofiles - pushCFunction(&LuaInterface::lua_dofiles); - setGlobal("dofiles"); - - // replace loadfile - pushCFunction(&LuaInterface::lua_loadfile); - setGlobal("loadfile"); -} - -void LuaInterface::closeLuaState() -{ - if(L) { - // close lua, it also collects - lua_close(L); - L = NULL; - } -} - -void LuaInterface::collectGarbage() -{ - // prevents recursive collects - static bool collecting = false; - if(!collecting) { - collecting = true; - - // we must collect two times because __gc metamethod - // is called on uservalues only the second time - for(int i=0;i<2;++i) - lua_gc(L, LUA_GCCOLLECT, 0); - - collecting = false; - } -} - -void LuaInterface::loadBuffer(const std::string& buffer, const std::string& source) -{ - // loads lua buffer - int ret = luaL_loadbuffer(L, buffer.c_str(), buffer.length(), source.c_str()); - if(ret != 0) - throw LuaException(popString(), 0); -} - -int dumpWriter(lua_State *L, const void* p, size_t sz, void* ud) { - if (!ud) - return -1; - - std::string* ret = (std::string*)ud; - ret->append((const char*)p, sz); - return 0; -} - -std::string LuaInterface::generateByteCode(const std::string& buffer, std::string source) -{ - stdext::replace_all(source, "\\", "/"); - source = std::string("@/") + source; - - std::string ret; - int status = luaL_loadbuffer(L, buffer.c_str(), buffer.length(), source.c_str()); - if (status != 0) - return ret; - - lua_dump(L, dumpWriter, &ret); - clearStack(); - return ret; -} - -int LuaInterface::pcall(int numArgs, int numRets, int errorFuncIndex) -{ - VALIDATE(hasIndex(-numArgs - 1)); - return lua_pcall(L, numArgs, numRets, errorFuncIndex); -} - -void LuaInterface::call(int numArgs, int numRets) -{ - VALIDATE(hasIndex(-numArgs - 1)); - lua_call(L, numArgs, numRets); -} - -void LuaInterface::error() -{ - VALIDATE(hasIndex(-1)); - lua_error(L); -} - -int LuaInterface::ref() -{ - int ref = luaL_ref(L, LUA_REGISTRYINDEX); - VALIDATE(ref != LUA_NOREF); - VALIDATE(ref < 2147483647); - return ref; -} - -int LuaInterface::weakRef() -{ - static int id = 0; - - // generates a new id - ++id; - if(id == 2147483647) - id = 0; - - // gets weak table - getRef(m_weakTableRef); - insert(-2); - - // sets weak_table[id] = v - rawSeti(id); - - // pops weak table - pop(); - - return id; -} - -void LuaInterface::unref(int ref) -{ - if(ref >= 0 && L != NULL) - luaL_unref(L, LUA_REGISTRYINDEX, ref); -} - -const char* LuaInterface::typeName(int index) -{ - VALIDATE(hasIndex(index)); - int type = lua_type(L, index); - return lua_typename(L, type); -} - -std::string LuaInterface::functionSourcePath() -{ - std::string path; - - // gets function source path - lua_Debug ar; - memset(&ar, 0, sizeof(ar)); - lua_getinfo(L, ">Sn", &ar); - if(ar.source) { - // scripts coming from files has source beginning with '@' - if(ar.source[0] == '@') { - path = ar.source; - path = path.substr(1, path.find_last_of("/") - 1); - path = path.substr(0, path.find_last_of(":")); - } - } - - return path; -} - -std::string LuaInterface::functionSource() -{ - std::string path; - - // gets function source path - lua_Debug ar; - memset(&ar, 0, sizeof(ar)); - lua_getinfo(L, ">Sn", &ar); - if(ar.source) { - // scripts coming from files has source beginning with '@' - //if(ar.source[0] == '@') { - path = ar.source; - //path = path.substr(1, path.find_last_of("/") - 1); - //path = path.substr(0, path.find_last_of(":")); - //} - } - - return path; -} - -void LuaInterface::insert(int index) -{ - VALIDATE(hasIndex(index)); - lua_insert(L, index); -} - -void LuaInterface::remove(int index) -{ - VALIDATE(hasIndex(index)); - lua_remove(L, index); -} - -bool LuaInterface::next(int index) -{ - VALIDATE(hasIndex(index)); - return lua_next(L, index); -} - -void LuaInterface::getStackFunction(int level) -{ - lua_Debug ar; - if(lua_getstack(L, level, &ar) == 1) - lua_getinfo(L, "f", &ar); - else - pushNil(); -} - -void LuaInterface::getRef(int ref) -{ - lua_rawgeti(L, LUA_REGISTRYINDEX, ref); -} - -void LuaInterface::getWeakRef(int weakRef) -{ - // pushes weak_table[weakRef] - getRef(m_weakTableRef); - rawGeti(weakRef); - remove(-2); -} - -void LuaInterface::setGlobalEnvironment(int env) -{ - pushThread(); - getRef(env); - VALIDATE(isTable()); - setEnv(); - pop(); -} - -void LuaInterface::setMetatable(int index) -{ - VALIDATE(hasIndex(index)); - lua_setmetatable(L, index); -} - -void LuaInterface::getMetatable(int index) -{ - VALIDATE(hasIndex(index)); - lua_getmetatable(L, index); -} - -void LuaInterface::getField(const char* key, int index) -{ - VALIDATE(hasIndex(index)); - VALIDATE(isUserdata(index) || isTable(index)); - lua_getfield(L, index, key); -} - -void LuaInterface::setField(const char* key, int index) -{ - VALIDATE(hasIndex(index)); - VALIDATE(isUserdata(index) || isTable(index)); - lua_setfield(L, index, key); -} - -void LuaInterface::getEnv(int index) -{ - VALIDATE(hasIndex(index)); - lua_getfenv(L, index); -} - -void LuaInterface::setEnv(int index) -{ - VALIDATE(hasIndex(index)); - lua_setfenv(L, index); -} - -void LuaInterface::getTable(int index) -{ - VALIDATE(hasIndex(index)); - lua_gettable(L, index); -} - -void LuaInterface::setTable(int index) -{ - VALIDATE(hasIndex(index)); - lua_settable(L, index); -} - -void LuaInterface::clearTable(int index) -{ - VALIDATE(hasIndex(index) && isTable(index)); - pushNil(); // table, nil - while(next(index-1)) { // table, key, value - pop(); // table, key - pushValue(); // table, key, key - if(next(index-2)) { // table, key, nextkey, value - pop(); // table, key, nextkey - insert(-2); // table, nextkey, key - pushNil(); // table, nextkey, key, nil - rawSet(index-3); // table, nextkey - } else { // table, key - pushNil(); // table, key, nil - rawSet(index-2); // table - break; - } - } -} - -void LuaInterface::getGlobal(const std::string& key) -{ - lua_getglobal(L, key.c_str()); -} - -void LuaInterface::getGlobalField(const std::string& globalKey, const std::string& fieldKey) -{ - getGlobal(globalKey); - if(!isNil()) { - VALIDATE(isTable() || isUserdata()); - getField(fieldKey); - remove(-2); - } -} - -void LuaInterface::setGlobal(const std::string& key) -{ - VALIDATE(hasIndex(-1)); - lua_setglobal(L, key.c_str()); -} - -void LuaInterface::rawGet(int index) -{ - VALIDATE(hasIndex(index)); - lua_rawget(L, index); -} - -void LuaInterface::rawGeti(int n, int index) -{ - VALIDATE(hasIndex(index)); - lua_rawgeti(L, index, n); -} - -void LuaInterface::rawSet(int index) -{ - VALIDATE(hasIndex(index)); - lua_rawset(L, index); -} - -void LuaInterface::rawSeti(int n, int index) -{ - VALIDATE(hasIndex(index)); - lua_rawseti(L, index, n); -} - -void LuaInterface::newTable() -{ - lua_newtable(L); -} - -void LuaInterface::createTable(int narr, int nrec) -{ - lua_createtable(L, narr, nrec); -} - -void* LuaInterface::newUserdata(int size) -{ - return lua_newuserdata(L, size); -} - -void LuaInterface::pop(int n) -{ - if(n > 0) { - VALIDATE(hasIndex(-n)); - lua_pop(L, n); - } -} - -long LuaInterface::popInteger() -{ - VALIDATE(hasIndex(-1)); - long v = toInteger(-1); - pop(); - return v; -} - -double LuaInterface::popNumber() -{ - VALIDATE(hasIndex(-1)); - double v = toNumber(-1); - pop(); - return v; -} - -bool LuaInterface::popBoolean() -{ - VALIDATE(hasIndex(-1)); - bool v = toBoolean(-1); - pop(); - return v; -} - -std::string LuaInterface::popString() -{ - VALIDATE(hasIndex(-1)); - std::string v = toString(-1); - pop(); - return v; -} - -void* LuaInterface::popUserdata() -{ - VALIDATE(hasIndex(-1)); - void* v = toUserdata(-1); - pop(); - return v; -} - -LuaObjectPtr LuaInterface::popObject() -{ - VALIDATE(hasIndex(-1)); - LuaObjectPtr v = toObject(-1); - pop(); - return v; -} - -void* LuaInterface::popUpvalueUserdata() -{ - return lua_touserdata(L, lua_upvalueindex(1)); -} - -void LuaInterface::pushNil() -{ - lua_pushnil(L); - checkStack(); -} - -void LuaInterface::pushInteger(long v) -{ - lua_pushinteger(L, v); - checkStack(); -} - -void LuaInterface::pushNumber(double v) -{ - lua_pushnumber(L, v); - checkStack(); -} - -void LuaInterface::pushBoolean(bool v) -{ - lua_pushboolean(L, v); - checkStack(); -} - -void LuaInterface::pushCString(const char* v) -{ - if (!v) { - lua_pushnil(L); - } else { - lua_pushstring(L, v); - } - checkStack(); -} - -void LuaInterface::pushString(const std::string& v) -{ - lua_pushlstring(L, v.c_str(), v.length()); - checkStack(); -} - -void LuaInterface::pushLightUserdata(void* p) -{ - lua_pushlightuserdata(L, p); - checkStack(); -} - -void LuaInterface::pushThread() -{ - lua_pushthread(L); - checkStack(); -} - -void LuaInterface::pushObject(const LuaObjectPtr& obj) -{ - // fills a new userdata with a new LuaObjectPtr pointer - new(newUserdata(sizeof(LuaObjectPtr))) LuaObjectPtr(obj); - m_totalObjRefs++; - - obj->luaGetMetatable(); - if(isNil()) - g_logger.fatal(stdext::format("metatable for class '%s' not found, did you bind the C++ class?", obj->getClassName())); - setMetatable(); -} - -void LuaInterface::pushCFunction(LuaCFunction func, int n) -{ - lua_pushcclosure(L, func, n); - checkStack(); -} - -void LuaInterface::pushCppFunction(const LuaCppFunction& func) -{ - // create a pointer to func (this pointer will hold the function existence) - new(newUserdata(sizeof(LuaCppFunctionPtr))) LuaCppFunctionPtr(new LuaCppFunction(func)); - m_totalFuncRefs++; - - // sets the userdata __gc metamethod, needed to free the function pointer when it gets collected - newTable(); - pushCFunction(&LuaInterface::luaCollectCppFunction); - setField("__gc"); - setMetatable(); - - // actually pushes a C function callback that will call the cpp function - pushCFunction(&LuaInterface::luaCppFunctionCallback, 1); -} - -void LuaInterface::pushValue(int index) -{ - VALIDATE(hasIndex(index)); - lua_pushvalue(L, index); - checkStack(); -} - -bool LuaInterface::isNil(int index) -{ - VALIDATE(hasIndex(index)); - return lua_isnil(L, index); -} - -bool LuaInterface::isBoolean(int index) -{ - VALIDATE(hasIndex(index)); - return lua_isboolean(L, index); -} - -bool LuaInterface::isNumber(int index) -{ - VALIDATE(hasIndex(index)); - return lua_isnumber(L, index); -} - -bool LuaInterface::isString(int index) -{ - VALIDATE(hasIndex(index)); - return lua_isstring(L, index); -} - -bool LuaInterface::isTable(int index) -{ - VALIDATE(hasIndex(index)); - return lua_istable(L, index); -} - -bool LuaInterface::isFunction(int index) -{ - VALIDATE(hasIndex(index)); - return lua_isfunction(L, index); -} - -bool LuaInterface::isCFunction(int index) -{ - VALIDATE(hasIndex(index)); - return lua_iscfunction(L, index); -} - -bool LuaInterface::isUserdata(int index) -{ - VALIDATE(hasIndex(index)); - return lua_isuserdata(L, index); -} - -bool LuaInterface::toBoolean(int index) -{ - VALIDATE(hasIndex(index)); - return (bool)lua_toboolean(L, index); -} - -int LuaInterface::toInteger(int index) -{ - VALIDATE(hasIndex(index)); - return lua_tointeger(L, index); -} - -double LuaInterface::toNumber(int index) -{ - VALIDATE(hasIndex(index)); - return lua_tonumber(L, index); -} - -const char* LuaInterface::toCString(int index) -{ - VALIDATE(hasIndex(index)); - return lua_tostring(L, index); -} - -std::string LuaInterface::toString(int index) -{ - VALIDATE(hasIndex(index)); - std::string str; - size_t len; - const char *c_str = lua_tolstring(L, index, &len); - if(c_str && len > 0) - str.assign(c_str, len); - return str; -} - -void* LuaInterface::toUserdata(int index) -{ - VALIDATE(hasIndex(index)); - return lua_touserdata(L, index); -} - -LuaObjectPtr LuaInterface::toObject(int index) -{ - VALIDATE(hasIndex(index)); - if(isUserdata(index)) { - LuaObjectPtr* objRef = static_cast(toUserdata(index)); - if(objRef && *objRef) - return *objRef; - } - return nullptr; -} - -int LuaInterface::getTop() -{ - return lua_gettop(L); -} - -std::string LuaInterface::getSource(int level) -{ - lua_Debug ar; - ar.short_src[0] = 0; - ar.currentline = 0; - if (lua_getstack(L, level, &ar) == 1) { - lua_getinfo(L, "Sl", &ar); - } - return std::string(ar.short_src) + ":" + std::to_string(ar.currentline); -} - -void LuaInterface::loadFiles(std::string directory, bool recursive, std::string contains) -{ - for(const std::string& fileName : g_resources.listDirectoryFiles(directory)) { - std::string fullPath = directory + "/" + fileName; - - if(recursive && g_resources.directoryExists(fullPath)) { - loadFiles(fullPath, true, contains); - continue; - } - - if(!g_resources.isFileType(fileName, "lua")) - continue; - - if(!contains.empty() && fileName.find(contains) == std::string::npos) - continue; - - try { - g_lua.loadScript(fullPath); - g_lua.call(0, 0); - } catch(stdext::exception& e) { - g_lua.pushString(e.what()); - g_lua.error(); - } - } -} diff --git a/src/framework/luaengine/luainterface.h b/src/framework/luaengine/luainterface.h deleted file mode 100644 index c884a20..0000000 --- a/src/framework/luaengine/luainterface.h +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LUAINTERFACE_H -#define LUAINTERFACE_H - -#include "declarations.h" - -#include - - -struct lua_State; -typedef int (*LuaCFunction) (lua_State *L); - -/// Class that manages LUA stuff -class LuaInterface -{ -public: - LuaInterface(); - ~LuaInterface(); - - void init(); - void terminate(); - - /// Register core script functions - void registerFunctions(); - - // functions that will register all script stuff in lua global environment - void registerSingletonClass(const std::string& className); - void registerClass(const std::string& className, const std::string& baseClass = "LuaObject"); - - void registerClassStaticFunction(const std::string& className, - const std::string& functionName, - const LuaCppFunction& function); - - void registerClassMemberFunction(const std::string& className, - const std::string& functionName, - const LuaCppFunction& function); - - void registerClassMemberField(const std::string& className, - const std::string& field, - const LuaCppFunction& getFunction, - const LuaCppFunction& setFunction); - - void registerGlobalFunction(const std::string& functionName, - const LuaCppFunction& function); - - // register shortcuts using templates - template - void registerClass() { - registerClass(stdext::demangle_class(), stdext::demangle_class()); - } - - template - void registerClassStaticFunction(const std::string& functionName, const LuaCppFunction& function) { - registerClassStaticFunction(stdext::demangle_class(), functionName, function); - } - - template - void registerClassMemberFunction(const std::string& functionName, const LuaCppFunction& function) { - registerClassMemberFunction(stdext::demangle_class(), functionName, function); - } - - template - void registerClassMemberField(const std::string& field, - const LuaCppFunction& getFunction, - const LuaCppFunction& setFunction) { - registerClassMemberField(stdext::demangle_class(), field, getFunction, setFunction); - } - - // methods for binding functions - template - void bindSingletonFunction(const std::string& functionName, F C::*function, C *instance); - template - void bindSingletonFunction(const std::string& className, const std::string& functionName, F C::* function, C* instance); - template - void bindSingletonFunction(const std::string& className, const std::string& functionName, const F& function); - - template - void bindClassStaticFunction(const std::string& functionName, const F& function); - template - void bindClassStaticFunction(const std::string& className, const std::string& functionName, const F& function); - - template - void bindClassMemberFunction(const std::string& functionName, F FC::*function); - template - void bindClassMemberFunction(const std::string& className, const std::string& functionName, F FC::*function); - - template - void bindClassMemberField(const std::string& fieldName, F1 FC::*getFunction, F2 FC::*setFunction); - template - void bindClassMemberField(const std::string& className, const std::string& fieldName, F1 FC::*getFunction, F2 FC::*setFunction); - - template - void bindClassMemberGetField(const std::string& fieldName, F FC::*getFunction); - template - void bindClassMemberGetField(const std::string& className, const std::string& fieldName, F FC::*getFunction); - - template - void bindClassMemberSetField(const std::string& fieldName, F FC::*setFunction); - template - void bindClassMemberSetField(const std::string& className, const std::string& fieldName, F FC::*setFunction); - - template - void bindGlobalFunction(const std::string& functionName, const F& function); - -private: - /// Metamethod that will retrieve fields values (that include functions) from the object when using '.' or ':' - static int luaObjectGetEvent(LuaInterface* lua); - /// Metamethod that is called when setting a field of the object by using the keyword '=' - static int luaObjectSetEvent(LuaInterface* lua); - /// Metamethod that will check equality of objects by using the keyword '==' - static int luaObjectEqualEvent(LuaInterface* lua); - /// Metamethod that is called every two lua garbage collections - /// for any LuaObject that have no references left in lua environment - /// anymore, thus this creates the possibility of holding an object - /// existence by lua until it got no references left - static int luaObjectCollectEvent(LuaInterface* lua); - -public: - /// Loads and runs a script, any errors are printed to stdout and returns false - bool safeRunScript(const std::string& fileName); - - /// Loads and runs a script - /// @exception LuaException is thrown on any lua error - void runScript(const std::string& fileName); - - /// Loads and runs the script from buffer - /// @exception LuaException is thrown on any lua error - void runBuffer(const std::string& buffer, const std::string& source); - - /// Loads a script file and pushes it's main function onto stack, - /// @exception LuaException is thrown on any lua error - void loadScript(const std::string& fileName); - - /// Loads a function from buffer and pushes it onto stack, - /// @exception LuaException is thrown on any lua error - void loadFunction(const std::string& buffer, const std::string& source = "lua function buffer"); - - /// Evaluates a lua expression and pushes the result value onto the stack - /// @exception LuaException is thrown on any lua error - void evaluateExpression(const std::string& expression, const std::string& source = "lua expression"); - - /// Generates a traceback message for the current call stack - /// @param errorMessage is an additional error message - /// @param level is the level of the traceback, 0 means trace from calling function - /// @return the generated traceback message - std::string traceback(const std::string& errorMessage = "", int level = 0); - - /// Throw a lua error if inside a lua call or generates an C++ stdext::exception - /// @param message is the error message wich will be displayed before the error traceback - /// @exception stdext::exception is thrown with the error message if the error is not captured by lua - void throwError(const std::string& message); - - /// Searches for the source of the current running function - std::string getCurrentSourcePath(int level = 0); - - /// gets current function name - std::string getCurrentFunction(int level = 0); - - /// @brief Calls a function - /// The function and arguments must be on top of the stack in order, - /// results are pushed onto the stack. - /// @exception LuaException is thrown on any lua error - /// @return number of results - int safeCall(int numArgs = 0, int numRets = -1, const std::shared_ptr& error = nullptr); - - /// Same as safeCall but catches exceptions and can also calls a table of functions, - /// if any error occurs it will be reported to stdout and returns 0 results - /// @param requestedResults is the number of results requested to pushes onto the stack, - /// if supplied, the call will always pushes that number of results, even if it fails - int signalCall(int numArgs = 0, int numRets = -1); - - /// @brief Creates a new environment table - /// The new environment table is redirected to the global environment (aka _G), - /// this allows to access global variables from _G in the new environment and - /// prevents new variables in this new environment to be set on the global environment - int newSandboxEnv(); - - template - int luaCallGlobalField(const std::string& global, const std::string& field, const T&... args); - - template - void callGlobalField(const std::string& global, const std::string& field, const T&... args); - - template - R callGlobalField(const std::string& global, const std::string& field, const T&... args); - - bool isInCppCallback() { return m_cppCallbackDepth != 0; } - -private: - /// Load scripts requested by lua 'require' - static int luaScriptLoader(lua_State* L); - /// Run scripts requested by lua 'dofile' - static int lua_dofile(lua_State* L); - /// Run scripts requested by lua 'dofiles' - static int lua_dofiles(lua_State* L); - /// Run scripts requested by lua 'dofiles' - static int lua_loadfile(lua_State* L); - /// Handle lua errors from safeCall - static int luaErrorHandler(lua_State* L); - /// Handle bound cpp functions callbacks - static int luaCppFunctionCallback(lua_State* L); - /// Collect bound cpp function pointers - static int luaCollectCppFunction(lua_State* L); - -public: - void createLuaState(); - void closeLuaState(); - - void collectGarbage(); - - void loadBuffer(const std::string& buffer, const std::string& source); - - std::string generateByteCode(const std::string & buffer, std::string source); - - int pcall(int numArgs = 0, int numRets = 0, int errorFuncIndex = 0); - void call(int numArgs = 0, int numRets = 0); - void error(); - - int ref(); - int weakRef(); - void unref(int ref); - void useValue() { pushValue(); ref(); } - - const char* typeName(int index = -1); - std::string functionSourcePath(); - std::string functionSource(); - - void insert(int index); - void remove(int index); - bool next(int index = -2); - - void checkStack() { VALIDATE(getTop() <= 20); } - void getStackFunction(int level = 0); - - void getRef(int ref); - void getWeakRef(int weakRef); - - int getGlobalEnvironment() { return m_globalEnv; } - void setGlobalEnvironment(int env); - void resetGlobalEnvironment() { setGlobalEnvironment(m_globalEnv); } - - void setMetatable(int index = -2); - void getMetatable(int index = -1); - - void getField(const char* key, int index = -1); - void getField(const std::string& key, int index = -1) { return getField(key.c_str(), index); } - void setField(const char* key, int index = -2); - void setField(const std::string& key, int index = -2) { return setField(key.c_str(), index); } - - void getTable(int index = -2); - void setTable(int index = -3); - void clearTable(int index = -1); - - void getEnv(int index = -1); - void setEnv(int index = -2); - - void getGlobal(const std::string& key); - void getGlobalField(const std::string& globalKey, const std::string& fieldKey); - void setGlobal(const std::string& key); - - void rawGet(int index = -1); - void rawGeti(int n, int index = -1); - void rawSet(int index = -3); - void rawSeti(int n, int index = -2); - - void newTable(); - void createTable(int narr, int nrec); - void* newUserdata(int size); - - void pop(int n = 1); - long popInteger(); - double popNumber(); - bool popBoolean(); - std::string popString(); - void* popUserdata(); - void* popUpvalueUserdata(); - LuaObjectPtr popObject(); - - void pushNil(); - void pushInteger(long v); - void pushNumber(double v); - void pushBoolean(bool v); - void pushCString(const char* v); - void pushString(const std::string& v); - void pushLightUserdata(void* p); - void pushThread(); - void pushValue(int index = -1); - void pushObject(const LuaObjectPtr& obj); - void pushCFunction(LuaCFunction func, int n = 0); - void pushCppFunction(const LuaCppFunction& func); - - bool isNil(int index = -1); - bool isBoolean(int index = -1); - bool isNumber(int index = -1); - bool isString(int index = -1); - bool isTable(int index = -1); - bool isFunction(int index = -1); - bool isCFunction(int index = -1); - bool isLuaFunction(int index = -1) { return (isFunction() && !isCFunction()); } - bool isUserdata(int index = -1); - - bool toBoolean(int index = -1); - int toInteger(int index = -1); - double toNumber(int index = -1); - const char* toCString(int index = -1); - std::string toString(int index = -1); - void* toUserdata(int index = -1); - LuaObjectPtr toObject(int index = -1); - - int getTop(); - int stackSize() { return getTop(); } - void clearStack() { pop(stackSize()); } - bool hasIndex(int index) { return (stackSize() >= (index < 0 ? -index : index) && index != 0); } - - std::string getSource(int level = 2); - - void loadFiles(std::string directory, bool recursive = false, std::string contains = ""); - - /// Pushes any type onto the stack - template - int polymorphicPush(const T& v, const Args&... args); - int polymorphicPush() { return 0; } - - /// Casts a value from stack to any type - /// @exception LuaBadValueCastException thrown if the cast fails - template - T castValue(int index = -1); - - /// Same as castValue but also pops - template - T polymorphicPop() { T v = castValue(); pop(1); return v; } - -private: - lua_State* L; - int m_weakTableRef; - int m_cppCallbackDepth; - int m_totalObjRefs; - int m_totalFuncRefs; - int m_globalEnv; -}; - -extern LuaInterface g_lua; - -// must be included after, because they need LuaInterface fully declared -#include "luaexception.h" -#include "luabinder.h" -#include "luavaluecasts.h" - -template -int LuaInterface::polymorphicPush(const T& v, const Args&... args) { - int r = push_luavalue(v); - return r + polymorphicPush(args...); -} - -// next templates must be defined after above includes - -template -void LuaInterface::bindSingletonFunction(const std::string& functionName, F C::*function, C *instance) { - registerClassStaticFunction(functionName, luabinder::bind_singleton_mem_fun(function, instance)); -} - -template -void LuaInterface::bindSingletonFunction(const std::string& className, const std::string& functionName, F C::*function, C *instance) { - registerClassStaticFunction(className, functionName, luabinder::bind_singleton_mem_fun(function, instance)); -} - -template -void LuaInterface::bindSingletonFunction(const std::string& className, const std::string& functionName, const F& function) -{ - registerClassStaticFunction(className, functionName, luabinder::bind_fun(function)); -} - -template -void LuaInterface::bindClassStaticFunction(const std::string& functionName, const F& function) { - registerClassStaticFunction(functionName, luabinder::bind_fun(function)); -} -template -void LuaInterface::bindClassStaticFunction(const std::string& className, const std::string& functionName, const F& function) { - registerClassStaticFunction(className, functionName, luabinder::bind_fun(function)); -} - -template -void LuaInterface::bindClassMemberFunction(const std::string& functionName, F FC::*function) { - registerClassMemberFunction(functionName, luabinder::bind_mem_fun(function)); -} -template -void LuaInterface::bindClassMemberFunction(const std::string& className, const std::string& functionName, F FC::*function) { - registerClassMemberFunction(className, functionName, luabinder::bind_mem_fun(function)); -} - -template -void LuaInterface::bindClassMemberField(const std::string& fieldName, F1 FC::*getFunction, F2 FC::*setFunction) { - registerClassMemberField(fieldName, luabinder::bind_mem_fun(getFunction), luabinder::bind_mem_fun(setFunction)); -} -template -void LuaInterface::bindClassMemberField(const std::string& className, const std::string& fieldName, F1 FC::*getFunction, F2 FC::*setFunction) { - registerClassMemberField(className, fieldName, luabinder::bind_mem_fun(getFunction), luabinder::bind_mem_fun(setFunction)); -} - -template -void LuaInterface::bindClassMemberGetField(const std::string& fieldName, F FC::*getFunction) { - registerClassMemberField(fieldName, luabinder::bind_mem_fun(getFunction), LuaCppFunction()); -} -template -void LuaInterface::bindClassMemberGetField(const std::string& className, const std::string& fieldName, F FC::*getFunction) { - registerClassMemberField(className, fieldName, luabinder::bind_mem_fun(getFunction), LuaCppFunction()); -} - -template -void LuaInterface::bindClassMemberSetField(const std::string& fieldName, F FC::*setFunction) { - registerClassMemberField(fieldName, LuaCppFunction(), luabinder::bind_mem_fun(setFunction)); -} -template -void LuaInterface::bindClassMemberSetField(const std::string& className, const std::string& fieldName, F FC::*setFunction) { - registerClassMemberField(className, fieldName, LuaCppFunction(), luabinder::bind_mem_fun(setFunction)); -} - -template -void LuaInterface::bindGlobalFunction(const std::string& functionName, const F& function) { - registerGlobalFunction(functionName, luabinder::bind_fun(function)); -} - -template -T LuaInterface::castValue(int index) { - T o; - if(!luavalue_cast(index, o)) - throw LuaBadValueCastException(typeName(index), stdext::demangle_type()); - return o; -} - -template -int LuaInterface::luaCallGlobalField(const std::string& global, const std::string& field, const T&... args) { - AutoStat s(STATS_LUA, std::string(global) + ":" + field); - - g_lua.getGlobalField(global, field); - int ret = 0; - - if(!g_lua.isNil()) { - int numArgs = g_lua.polymorphicPush(args...); - ret = g_lua.signalCall(numArgs); - } else - g_lua.pop(1); - return ret; -} - -template -void LuaInterface::callGlobalField(const std::string& global, const std::string& field, const T&... args) { - int rets = luaCallGlobalField(global, field, args...); - if(rets > 0) - pop(rets); -} - -template -R LuaInterface::callGlobalField(const std::string& global, const std::string& field, const T&... args) { - R result; - int rets = luaCallGlobalField(global, field, args...); - if(rets > 0) { - VALIDATE(rets == 1); - result = g_lua.polymorphicPop(); - } else - result = R(); - return result; -} - -#endif diff --git a/src/framework/luaengine/luaobject.cpp b/src/framework/luaengine/luaobject.cpp deleted file mode 100644 index 30245ce..0000000 --- a/src/framework/luaengine/luaobject.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "luaobject.h" -#include "luainterface.h" - -#include -#include - -LuaObject::LuaObject() : - m_fieldsTableRef(-1) -{ -} - -LuaObject::~LuaObject() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); -#endif - releaseLuaFieldsTable(); -} - -bool LuaObject::hasLuaField(const std::string& field) -{ - bool ret = false; - if(m_fieldsTableRef != -1) { - g_lua.getRef(m_fieldsTableRef); - g_lua.getField(field); // push the field value - ret = !g_lua.isNil(); - g_lua.pop(2); - } - return ret; -} - -void LuaObject::releaseLuaFieldsTable() -{ - if(m_fieldsTableRef != -1) { - g_lua.unref(m_fieldsTableRef); - m_fieldsTableRef = -1; - } -} - -void LuaObject::luaSetField(const std::string& key) -{ - // create fields table on the fly - if(m_fieldsTableRef == -1) { - g_lua.newTable(); // create fields table - m_fieldsTableRef = g_lua.ref(); // save a reference for it - } - - g_lua.getRef(m_fieldsTableRef); // push the table - g_lua.insert(-2); // move the value to the top - g_lua.setField(key); // set the field - g_lua.pop(); // pop the fields table -} - -void LuaObject::luaGetField(const std::string& key) -{ - if(m_fieldsTableRef != -1) { - g_lua.getRef(m_fieldsTableRef); // push the obj's fields table - g_lua.getField(key); // push the field value - g_lua.remove(-2); // remove the table - } else { - g_lua.pushNil(); - } -} - -void LuaObject::luaGetMetatable() -{ - static std::unordered_map metatableMap; - const std::type_info& tinfo = typeid(*this); - auto it = metatableMap.find(&tinfo); - - int metatableRef; - if(it == metatableMap.end()) { - g_lua.getGlobal(getClassName() + "_mt"); - metatableRef = g_lua.ref(); - metatableMap[&tinfo] = metatableRef; - } else - metatableRef = it->second; - - g_lua.getRef(metatableRef); -} - -void LuaObject::luaGetFieldsTable() -{ - if(m_fieldsTableRef != -1) - g_lua.getRef(m_fieldsTableRef); - else - g_lua.pushNil(); -} - -int LuaObject::getUseCount() -{ - return ref_count(); -} - -std::string LuaObject::getClassName() -{ - // TODO: this could be cached for more performance -#ifdef _MSC_VER - return stdext::demangle_name(typeid(*this).name()) + 6; -#else - return stdext::demangle_name(typeid(*this).name()); -#endif -} diff --git a/src/framework/luaengine/luaobject.h b/src/framework/luaengine/luaobject.h deleted file mode 100644 index 51c1829..0000000 --- a/src/framework/luaengine/luaobject.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LUAOBJECT_H -#define LUAOBJECT_H - -#include -#include "declarations.h" - -/// LuaObject, all script-able classes have it as base -// @bindclass -class LuaObject : public stdext::shared_object -{ -public: - LuaObject(); - virtual ~LuaObject(); - - template - void connectLuaField(const std::string& field, const std::function& f, bool pushFront = false); - - /// Calls a function or table of functions stored in a lua field, results are pushed onto the stack, - /// if any lua error occurs, it will be reported to stdout and return 0 results - /// @return the number of results - template - int luaCallLuaField(const std::string& field, const T&... args); - - template - R callLuaField(const std::string& field, const T&... args); - template - void callLuaField(const std::string& field, const T&... args); - - /// Returns true if the lua field exists - bool hasLuaField(const std::string& field); - - /// Sets a field in this lua object - template - void setLuaField(const std::string& key, const T& value); - - /// Gets a field from this lua object - template - T getLuaField(const std::string& key); - - /// Release fields table reference - void releaseLuaFieldsTable(); - - /// Sets a field from this lua object, the value must be on the stack - void luaSetField(const std::string& key); - - /// Gets a field from this lua object, the result is pushed onto the stack - void luaGetField(const std::string& key); - - /// Get object's metatable - void luaGetMetatable(); - - /// Gets the table containing all stored fields of this lua object, the result is pushed onto the stack - void luaGetFieldsTable(); - - /// Returns the number of references of this object - /// @note each userdata of this object on lua counts as a reference - int getUseCount(); - - /// Returns the derived class name, its the same name used in Lua - std::string getClassName(); - - LuaObjectPtr asLuaObject() { return static_self_cast(); } - - void operator=(const LuaObject& other) { } - -private: - int m_fieldsTableRef; -}; - -template -void connect(const LuaObjectPtr& obj, const std::string& field, const std::function& f, bool pushFront = false); - -template -typename std::enable_if::value, void>::type -connect(const LuaObjectPtr& obj, const std::string& field, const Lambda& f, bool pushFront = false); - -#include "luainterface.h" - -template -void LuaObject::connectLuaField(const std::string& field, const std::function& f, bool pushFront) -{ - luaGetField(field); - if(g_lua.isTable()) { - if(pushFront) - g_lua.pushInteger(1); - push_luavalue(f); - g_lua.callGlobalField("table","insert"); - } else { - if(g_lua.isNil()) { - push_luavalue(f); - luaSetField(field); - g_lua.pop(); - } else if(g_lua.isFunction()) { - g_lua.newTable(); - g_lua.insert(-2); - g_lua.rawSeti(1); - push_luavalue(f); - g_lua.rawSeti(2); - luaSetField(field); - } - } -} - -// connect for std::function -template -void connect(const LuaObjectPtr& obj, const std::string& field, const std::function& f, bool pushFront) { - obj->connectLuaField(field, f, pushFront); -} - -namespace luabinder { - template - struct connect_lambda; - - template - struct connect_lambda { - static void call(const LuaObjectPtr& obj, const std::string& field, const Lambda& f, bool pushFront) { - connect(obj, field, std::function(f), pushFront); - } - }; -}; - -// connect for lambdas -template -typename std::enable_if::value, void>::type -connect(const LuaObjectPtr& obj, const std::string& field, const Lambda& f, bool pushFront) { - typedef decltype(&Lambda::operator()) F; - luabinder::connect_lambda::call(obj, field, f, pushFront); -} - -template -int LuaObject::luaCallLuaField(const std::string& field, const T&... args) { - AutoStat s(STATS_LUA, getClassName() + ":" + field); - - // note that the field must be retrieved from this object lua value - // to force using the __index metamethod of it's metatable - // so cannot use LuaObject::getField here - // push field - //AutoStat s(STATS_LUA, field); - g_lua.pushObject(asLuaObject()); - g_lua.getField(field); - - int ret = 0; - if(!g_lua.isNil()) { - // the first argument is always this object (self) - g_lua.insert(-2); - int numArgs = g_lua.polymorphicPush(args...); - ret = g_lua.signalCall(1 + numArgs); - } else { - g_lua.pop(2); - } - - return ret; -} - -template -R LuaObject::callLuaField(const std::string& field, const T&... args) { - R result; - int rets = luaCallLuaField(field, args...); - if(rets > 0) { - VALIDATE(rets == 1); - result = g_lua.polymorphicPop(); - } else - result = R(); - return result; -} - -template -void LuaObject::callLuaField(const std::string& field, const T&... args) { - int rets = luaCallLuaField(field, args...); - if(rets > 0) - g_lua.pop(rets); -} - -template -void LuaObject::setLuaField(const std::string& key, const T& value) { - g_lua.polymorphicPush(value); - luaSetField(key); -} - -template -T LuaObject::getLuaField(const std::string& key) { - luaGetField(key); - return g_lua.polymorphicPop(); -} - -#endif diff --git a/src/framework/luaengine/luavaluecasts.cpp b/src/framework/luaengine/luavaluecasts.cpp deleted file mode 100644 index 7627d90..0000000 --- a/src/framework/luaengine/luavaluecasts.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "luavaluecasts.h" -#include "luainterface.h" -#include - -// bool -int push_luavalue(bool b) -{ - g_lua.pushBoolean(b); - return 1; -} - -bool luavalue_cast(int index, bool& b) -{ - b = g_lua.toBoolean(index); - return true; -} - -// int -int push_luavalue(int i) -{ - g_lua.pushInteger(i); - return 1; -} - -bool luavalue_cast(int index, int& i) -{ - i = g_lua.toInteger(index); - if(i == 0 && !g_lua.isNumber(index) && !g_lua.isNil()) - return false; - return true; -} - -// double -int push_luavalue(double d) -{ - g_lua.pushNumber(d); - return 1; -} - -bool luavalue_cast(int index, double& d) -{ - d = g_lua.toNumber(index); - if(d == 0 && !g_lua.isNumber(index) && !g_lua.isNil()) - return false; - return true; -} - -// string -int push_luavalue(const char* cstr) -{ - g_lua.pushCString(cstr); - return 1; -} - -int push_luavalue(const std::string& str) -{ - g_lua.pushString(str); - return 1; -} - -bool luavalue_cast(int index, std::string& str) -{ - str = g_lua.toString(index); - return true; -} - -// lua cpp function -int push_luavalue(const LuaCppFunction& func) -{ - g_lua.pushCppFunction(func); - return 1; -} - -// color -int push_luavalue(const Color& color) -{ - g_lua.createTable(0, 4); - g_lua.pushInteger(color.r()); - g_lua.setField("r"); - g_lua.pushInteger(color.g()); - g_lua.setField("g"); - g_lua.pushInteger(color.b()); - g_lua.setField("b"); - g_lua.pushInteger(color.a()); - g_lua.setField("a"); - return 1; -} - -bool luavalue_cast(int index, Color& color) -{ - if(g_lua.isTable(index)) { - g_lua.getField("r", index); - color.setRed((int)g_lua.popInteger()); - g_lua.getField("g", index); - color.setGreen((int)g_lua.popInteger()); - g_lua.getField("b", index); - color.setBlue((int)g_lua.popInteger()); - g_lua.getField("a", index); - color.setAlpha((int)g_lua.popInteger()); - return true; - } else if(g_lua.isString()) { - return stdext::cast(g_lua.toString(index), color); - } else if(g_lua.isNil()) { - color = Color::white; - return true; - } - return false; -} - -// rect -int push_luavalue(const Rect& rect) -{ - g_lua.createTable(0, 4); - g_lua.pushInteger(rect.x()); - g_lua.setField("x"); - g_lua.pushInteger(rect.y()); - g_lua.setField("y"); - g_lua.pushInteger(rect.width()); - g_lua.setField("width"); - g_lua.pushInteger(rect.height()); - g_lua.setField("height"); - return 1; -} - -bool luavalue_cast(int index, Rect& rect) -{ - if(g_lua.isTable(index)) { - g_lua.getField("x", index); - rect.setX(g_lua.popInteger()); - g_lua.getField("y", index); - rect.setY(g_lua.popInteger()); - g_lua.getField("width", index); - rect.setWidth(g_lua.popInteger()); - g_lua.getField("height", index); - rect.setHeight(g_lua.popInteger()); - return true; - } else if(g_lua.isString()) { - return stdext::cast(g_lua.toString(index), rect); - } else if(g_lua.isNil()) { - rect = Rect(); - return true; - } - return false; -} - -// point -int push_luavalue(const Point& point) -{ - g_lua.createTable(0, 2); - g_lua.pushInteger(point.x); - g_lua.setField("x"); - g_lua.pushInteger(point.y); - g_lua.setField("y"); - return 1; -} - -bool luavalue_cast(int index, Point& point) -{ - if(g_lua.isTable(index)) { - g_lua.getField("x", index); - point.x = g_lua.popInteger(); - g_lua.getField("y", index); - point.y = g_lua.popInteger(); - return true; - } else if(g_lua.isString()) { - return stdext::cast(g_lua.toString(index), point); - } else if(g_lua.isNil()) { - point = Point(); - return true; - } - return false; -} - -// size -int push_luavalue(const Size& size) -{ - g_lua.createTable(0, 2); - g_lua.pushInteger(size.width()); - g_lua.setField("width"); - g_lua.pushInteger(size.height()); - g_lua.setField("height"); - return 1; -} - -bool luavalue_cast(int index, Size& size) -{ - if(g_lua.isTable(index)) { - g_lua.getField("width", index); - size.setWidth(g_lua.popInteger()); - g_lua.getField("height", index); - size.setHeight(g_lua.popInteger()); - return true; - } else if(g_lua.isString()) { - return stdext::cast(g_lua.toString(index), size); - } else if(g_lua.isNil()) { - size = Size(); - return true; - } - return false; -} - -// otml nodes -void push_otml_subnode_luavalue(const OTMLNodePtr& node) -{ - if(node->hasValue()) { - union { - bool b; - double d; - long l; - }; - std::string value = node->rawValue(); - if(stdext::cast(value, b)) - g_lua.pushBoolean(b); - else if(stdext::cast(value, l)) - g_lua.pushInteger(l); - else if(stdext::cast(value, d)) - g_lua.pushNumber(d); - else - g_lua.pushString(value); - } else if(node->hasChildren()) { - g_lua.newTable(); - bool pushedChild = false; - int currentIndex = 1; - for(const OTMLNodePtr& cnode : node->children()) { - push_otml_subnode_luavalue(cnode); - if(!g_lua.isNil()) { - if(cnode->isUnique()) { - g_lua.pushString(cnode->tag()); - g_lua.insert(-2); - g_lua.rawSet(); - } else - g_lua.rawSeti(currentIndex++); - pushedChild = true; - } else - g_lua.pop(); - } - if(!pushedChild) { - g_lua.pop(); - g_lua.pushNil(); - } - } else - g_lua.pushNil(); -} - -int push_luavalue(const OTMLNodePtr& node) -{ - if(node) { - g_lua.newTable(); - int currentIndex = 1; - for(const OTMLNodePtr& cnode : node->children()) { - push_otml_subnode_luavalue(cnode); - if(cnode->isUnique() && !cnode->tag().empty()) { - g_lua.setField(cnode->tag()); - } else - g_lua.rawSeti(currentIndex++); - } - } else - g_lua.pushNil(); - return 1; -} - -bool luavalue_cast(int index, OTMLNodePtr& node) -{ - node = OTMLNode::create(); - node->setUnique(true); - if(g_lua.isTable(index)) { - g_lua.pushNil(); - while(g_lua.next(index < 0 ? index-1 : index)) { - std::string cnodeName; - if(g_lua.isString(-2)) { - g_lua.pushValue(-2); - cnodeName = g_lua.toString(); - g_lua.pop(); - } else - VALIDATE(g_lua.isNumber()); - if(g_lua.isTable()) { - OTMLNodePtr cnode; - if(luavalue_cast(-1, cnode)) { - if(cnodeName.empty()) - cnode->setUnique(false); - else - cnode->setTag(cnodeName); - node->addChild(cnode); - } - } else { - std::string value; - if(g_lua.isBoolean()) - value = stdext::unsafe_cast(g_lua.toBoolean()); - else - value = g_lua.toString(); - if(cnodeName.empty()) - node->writeIn(value); - else - node->writeAt(cnodeName, value); - } - g_lua.pop(); - } - return true; - } - return false; -} - -// object ptr -bool luavalue_cast(int index, LuaObjectPtr& obj) { - if(g_lua.isUserdata(index)) { - obj = g_lua.toObject(index); - return true; - } else if(g_lua.isNil(index)) { - obj = nullptr; - return true; - } - return false; -} diff --git a/src/framework/luaengine/luavaluecasts.h b/src/framework/luaengine/luavaluecasts.h deleted file mode 100644 index ebb68d6..0000000 --- a/src/framework/luaengine/luavaluecasts.h +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef LUAVALUECASTS_H -#define LUAVALUECASTS_H - -// this file is and must be included only from luainterface.h - -#include "declarations.h" -#include - -template -int push_internal_luavalue(T v); - -// bool -int push_luavalue(bool b); -bool luavalue_cast(int index, bool& b); - -// int -int push_luavalue(int i); -bool luavalue_cast(int index, int& i); - -// double -int push_luavalue(double d); -bool luavalue_cast(int index, double& d); - -// float -inline int push_luavalue(float f) { push_luavalue((double)f); return 1; } -inline bool luavalue_cast(int index, float& f) { double d; bool r = luavalue_cast(index, d); f = d; return r; } - -// int8 -inline int push_luavalue(int8 v) { push_luavalue((int)v); return 1; } -inline bool luavalue_cast(int index, int8& v) { int i; bool r = luavalue_cast(index, i); v = i; return r; } -// uint8 -inline int push_luavalue(uint8 v) { push_luavalue((int)v); return 1; } -inline bool luavalue_cast(int index, uint8& v){ int i; bool r = luavalue_cast(index, i); v = i; return r; } -// int16 -inline int push_luavalue(int16 v) { push_luavalue((int)v); return 1; } -inline bool luavalue_cast(int index, int16& v){ int i; bool r = luavalue_cast(index, i); v = i; return r; } -// uint16 -inline int push_luavalue(uint16 v) { push_luavalue((int)v); return 1; } -inline bool luavalue_cast(int index, uint16& v){ int i; bool r = luavalue_cast(index, i); v = i; return r; } -// uint32 -inline int push_luavalue(uint32 v) { push_luavalue((double)v); return 1; } -inline bool luavalue_cast(int index, uint32& v) { double d; bool r = luavalue_cast(index, d); v = d; return r; } -// int64 -inline int push_luavalue(int64 v) { push_luavalue((double)v); return 1; } -inline bool luavalue_cast(int index, int64& v) { double d; bool r = luavalue_cast(index, d); v = d; return r; } -// uint64 -inline int push_luavalue(uint64 v) { push_luavalue((double)v); return 1; } -inline bool luavalue_cast(int index, uint64& v) { double d; bool r = luavalue_cast(index, d); v = d; return r; } - -// string -int push_luavalue(const char* cstr); -int push_luavalue(const std::string& str); -bool luavalue_cast(int index, std::string& str); - -// lua cpp function -int push_luavalue(const LuaCppFunction& func); - -// color -int push_luavalue(const Color& color); -bool luavalue_cast(int index, Color& color); - -// rect -int push_luavalue(const Rect& rect); -bool luavalue_cast(int index, Rect& rect); - -// point -int push_luavalue(const Point& point); -bool luavalue_cast(int index, Point& point); - -// size -int push_luavalue(const Size& size); -bool luavalue_cast(int index, Size& size); - -// otml nodes -int push_luavalue(const OTMLNodePtr& node); -bool luavalue_cast(int index, OTMLNodePtr& node); - -// enum -template -typename std::enable_if::value, int>::type -push_luavalue(T e) { return push_luavalue((int)e); } - -template -typename std::enable_if::value, bool>::type -luavalue_cast(int index, T& myenum); - -// LuaObject pointers -template -typename std::enable_if::value, int>::type -push_luavalue(const T& obj); - -bool luavalue_cast(int index, LuaObjectPtr& obj); - -template -typename std::enable_if::value, bool>::type -luavalue_cast(int index, stdext::shared_object_ptr& ptr); - -// std::function -template -int push_luavalue(const std::function& func); - -template -bool luavalue_cast(int index, std::function& func); - -template -typename std::enable_if::value, bool>::type -luavalue_cast(int index, std::function& func); - -// list -template -int push_luavalue(const std::list& list); - -template -bool luavalue_cast(int index, std::list& list); - -// vector -template -int push_luavalue(const std::vector& vec); - -template -bool luavalue_cast(int index, std::vector& vec); - -// set -template -int push_luavalue(const std::set& vec); - -template -bool luavalue_cast(int index, std::set& vec); - -// deque -template -int push_luavalue(const std::deque& vec); - -template -bool luavalue_cast(int index, std::deque& vec); - -// map -template -int push_luavalue(const std::map& map); - -template -bool luavalue_cast(int index, std::map& map); - -// pair -template -bool luavalue_cast(int index, std::pair& pair); - -// tuple -template -int push_luavalue(const std::tuple& tuple); - -template -int push_internal_luavalue(const std::tuple& tuple); - -// start definitions - -#include "luaexception.h" -#include "luainterface.h" -#include "luaobject.h" - -template -int push_internal_luavalue(T v) { - return push_luavalue(v); -} - -template -typename std::enable_if::value, bool>::type -luavalue_cast(int index, T& myenum) { - int i; - if(luavalue_cast(index, i)) { - myenum = (T)i; - return true; - } - return false; -} - -template -typename std::enable_if::value, int>::type -push_luavalue(const T& obj) { - if(obj) - g_lua.pushObject(obj); - else - g_lua.pushNil(); - return 1; -} - -template -typename std::enable_if::value, bool>::type -luavalue_cast(int index, stdext::shared_object_ptr& ptr) { - LuaObjectPtr obj; - if(!luavalue_cast(index, obj)) - return false; - if(obj) - ptr = obj->dynamic_self_cast(); - else - ptr = nullptr; - return true; -} - -template -int push_luavalue(const std::function& func) { - if(func) { - LuaCppFunction f = luabinder::bind_fun(func); - g_lua.pushCppFunction(f); - } else - g_lua.pushNil(); - return 1; -} - -template -bool luavalue_cast(int index, std::function& func) { - if(g_lua.isFunction(index)) { - g_lua.pushValue(index); - // weak references are used here, this means that the script must hold another reference - // to this function, otherwise it will expire - int funcWeakRef = g_lua.weakRef(); - func = [=](Args... args) { - // note that we must catch exceptions, because this lambda can be called from anywhere - // and most of them won't catch exceptions (e.g. dispatcher) - g_lua.getWeakRef(funcWeakRef); - auto error = std::make_shared(); - if(g_lua.isFunction()) { - int numArgs = g_lua.polymorphicPush(args...); - int rets = g_lua.safeCall(numArgs, -1, error); - if (!error->empty()) { - g_logger.error(stdext::format("lua function callback failed: %s", *error)); - } else { - g_lua.pop(rets); - } - } else { - g_logger.error("attempt to call an expired lua function from C++, did you forget to hold a reference for that function?"); - } - }; - return true; - } else if(g_lua.isNil(index)) { - func = std::function(); - return true; - } - return false; -} - -template -typename std::enable_if::value, bool>::type -luavalue_cast(int index, std::function& func) { - if(g_lua.isFunction(index)) { - g_lua.pushValue(index); - // weak references are used here, this means that the script must hold another reference - // to this function, otherwise it will expire - int funcWeakRef = g_lua.weakRef(); - func = [=](Args... args) -> Ret { - // note that we must catch exceptions, because this lambda can be called from anywhere - // and most of them won't catch exceptions (e.g. dispatcher) - try { - g_lua.getWeakRef(funcWeakRef); - if(g_lua.isFunction()) { - int numArgs = g_lua.polymorphicPush(args...); - if(g_lua.safeCall(numArgs) != 1) - throw LuaException("a function from lua didn't retrieve the expected number of results", 0); - return g_lua.polymorphicPop(); - } else { - throw LuaException("attempt to call an expired lua function from C++," - "did you forget to hold a reference for that function?", 0); - } - } catch(LuaException& e) { - g_logger.error(stdext::format("lua function callback failed: %s", e.what())); - } - return Ret(); - }; - return true; - } else if(g_lua.isNil(index)) { - func = std::function(); - return true; - } - return false; -} - -template -int push_luavalue(const std::list& list) { - g_lua.createTable(list.size(), 0); - int i = 1; - for(const T& v : list) { - push_internal_luavalue(v); - g_lua.rawSeti(i); - i++; - } - return 1; -} - -template -bool luavalue_cast(int index, std::list& list) -{ - if(g_lua.isTable(index)) { - g_lua.pushNil(); - while(g_lua.next(index < 0 ? index-1 : index)) { - T value; - if(luavalue_cast(-1, value)) - list.push_back(value); - g_lua.pop(); - } - return true; - } - return false; -} - -template -int push_luavalue(const std::vector& vec) -{ - g_lua.createTable(vec.size(), 0); - int i = 1; - for (const T& v : vec) { - push_internal_luavalue(v); - g_lua.rawSeti(i); - i++; - } - return 1; -} - -template -bool luavalue_cast(int index, std::vector& vec) -{ - if (g_lua.isTable(index)) { - g_lua.pushNil(); - while (g_lua.next(index < 0 ? index - 1 : index)) { - T value; - if (luavalue_cast(-1, value)) - vec.push_back(value); - g_lua.pop(); - } - return true; - } - return false; -} - -template -int push_luavalue(const std::set& set) -{ - g_lua.createTable(set.size(), 0); - int i = 1; - for (const T& v : set) { - push_internal_luavalue(v); - g_lua.rawSeti(i); - i++; - } - return 1; -} - -template -bool luavalue_cast(int index, std::set& set) -{ - if (g_lua.isTable(index)) { - g_lua.pushNil(); - while (g_lua.next(index < 0 ? index - 1 : index)) { - T value; - if (luavalue_cast(-1, value)) - set.insert(value); - g_lua.pop(); - } - return true; - } - return false; -} - -template -int push_luavalue(const std::deque& vec) { - g_lua.createTable(vec.size(), 0); - int i = 1; - for(const T& v : vec) { - push_internal_luavalue(v); - g_lua.rawSeti(i); - i++; - } - return 1; -} - -template -bool luavalue_cast(int index, std::deque& vec) -{ - if(g_lua.isTable(index)) { - g_lua.pushNil(); - while(g_lua.next(index < 0 ? index-1 : index)) { - T value; - if(luavalue_cast(-1, value)) - vec.push_back(value); - g_lua.pop(); - } - return true; - } - return false; -} - -template -int push_luavalue(const std::map& map) -{ - g_lua.newTable(); - for(auto& it : map) { - push_internal_luavalue(it.first); - push_internal_luavalue(it.second); - g_lua.rawSet(); - } - return 1; -} - -template -bool luavalue_cast(int index, std::map& map) -{ - if(g_lua.isTable(index)) { - g_lua.pushNil(); - while(g_lua.next(index < 0 ? index-1 : index)) { - K key; - V value; - if(luavalue_cast(-1, value) && luavalue_cast(-2, key)) - map[key] = value; - g_lua.pop(); - } - return true; - } - return false; -} - -template -bool luavalue_cast(int index, std::pair& pair) -{ - if (g_lua.isTable(index)) { - g_lua.pushNil(); - if (g_lua.next(index < 0 ? index - 1 : index)) { - K value; - if (!luavalue_cast(-1, value)) - pair.first = value; - g_lua.pop(); - } else { - return false; - } - if (g_lua.next(index < 0 ? index - 1 : index)) { - V value; - if (!luavalue_cast(-1, value)) - pair.second = value; - g_lua.pop(); - } else { - return false; - } - - return true; - } - return false; -} - - - -template -struct push_tuple_internal_luavalue { - template - static void call(const Tuple& tuple) { - push_internal_luavalue(std::get(tuple)); - g_lua.rawSeti(N); - push_tuple_internal_luavalue::call(tuple); - } -}; - -template<> -struct push_tuple_internal_luavalue<0> { - template - static void call(const Tuple& tuple) { } -}; - -template -int push_internal_luavalue(const std::tuple& tuple) { - g_lua.newTable(); - push_tuple_internal_luavalue::call(tuple); - return 1; -} - -template -struct push_tuple_luavalue { - template - static void call(const Tuple& tuple) { - push_internal_luavalue(std::get::value - N>(tuple)); - push_tuple_luavalue::call(tuple); - } -}; - -template<> -struct push_tuple_luavalue<0> { - template - static void call(const Tuple& tuple) { } -}; - -template -int push_luavalue(const std::tuple& tuple) { - push_tuple_luavalue::call(tuple); - return sizeof...(Args); -} - -#endif diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp deleted file mode 100644 index c0079a4..0000000 --- a/src/framework/luafunctions.cpp +++ /dev/null @@ -1,997 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef FW_SOUND -#include -#include -#include -#include -#include -#endif - -#ifdef FW_GRAPHICS -#include -#include -#include -#include -#include -#include -#endif - -#ifdef FW_NET -#include -#include -#ifdef FW_PROXY -#include -#endif -#endif - -#ifdef FW_SQL -#include -#endif - -#include - -#include - - -void Application::registerLuaFunctions() -{ - // conversion globals - g_lua.bindGlobalFunction("torect", [](const std::string& v) { return stdext::from_string(v); }); - g_lua.bindGlobalFunction("topoint", [](const std::string& v) { return stdext::from_string(v); }); - g_lua.bindGlobalFunction("tocolor", [](const std::string& v) { return stdext::from_string(v); }); - g_lua.bindGlobalFunction("tosize", [](const std::string& v) { return stdext::from_string(v); }); - g_lua.bindGlobalFunction("recttostring", [](const Rect& v) { return stdext::to_string(v); }); - g_lua.bindGlobalFunction("pointtostring", [](const Point& v) { return stdext::to_string(v); }); - g_lua.bindGlobalFunction("colortostring", [](const Color& v) { return stdext::to_string(v); }); - g_lua.bindGlobalFunction("sizetostring", [](const Size& v) { return stdext::to_string(v); }); - g_lua.bindGlobalFunction("iptostring", [](uint32 v) { return stdext::ip_to_string(v); }); - g_lua.bindGlobalFunction("stringtoip", [](const std::string& v) { return stdext::string_to_ip(v); }); - g_lua.bindGlobalFunction("listSubnetAddresses", [](uint32 a, uint8 b) { return stdext::listSubnetAddresses(a, b); }); - g_lua.bindGlobalFunction("ucwords", [](std::string s) { return stdext::ucwords(s); }); - g_lua.bindGlobalFunction("regexMatch", [](std::string s, const std::string& exp) { - int limit = 10000; - std::vector> ret; - if (s.empty() || exp.empty()) - return ret; - try { - std::smatch m; - std::regex e(exp, std::regex::ECMAScript); - while (std::regex_search (s,m,e)) { - ret.push_back(std::vector()); - for (auto x:m) - ret[ret.size() - 1].push_back(x); - s = m.suffix().str(); - if (--limit == 0) - return ret; - } - } catch (...) { - } - return ret; - }); - - // Platform - g_lua.registerSingletonClass("g_platform"); -#ifdef UNSAFE_LUA_FUNCTIONS - g_lua.bindSingletonFunction("g_platform", "spawnProcess", &Platform::spawnProcess, &g_platform); - g_lua.bindSingletonFunction("g_platform", "copyFile", &Platform::copyFile, &g_platform); - g_lua.bindSingletonFunction("g_platform", "fileExists", &Platform::fileExists, &g_platform); - g_lua.bindSingletonFunction("g_platform", "removeFile", &Platform::removeFile, &g_platform); - g_lua.bindSingletonFunction("g_platform", "killProcess", &Platform::killProcess, &g_platform); -#endif - g_lua.bindSingletonFunction("g_platform", "getProcessId", &Platform::getProcessId, &g_platform); - g_lua.bindSingletonFunction("g_platform", "isProcessRunning", &Platform::isProcessRunning, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getTempPath", &Platform::getTempPath, &g_platform); - g_lua.bindSingletonFunction("g_platform", "openUrl", &Platform::openUrl, &g_platform); - g_lua.bindSingletonFunction("g_platform", "openDir", &Platform::openDir, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getCPUName", &Platform::getCPUName, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getTotalSystemMemory", &Platform::getTotalSystemMemory, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getMemoryUsage", &Platform::getMemoryUsage, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getOSName", &Platform::getOSName, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getFileModificationTime", &Platform::getFileModificationTime, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getMacAddresses", &Platform::getMacAddresses, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getUserName", &Platform::getUserName, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getDlls", &Platform::getDlls, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getProcesses", &Platform::getProcesses, &g_platform); - g_lua.bindSingletonFunction("g_platform", "getWindows", &Platform::getWindows, &g_platform); - - // Application - g_lua.registerSingletonClass("g_app"); - g_lua.bindSingletonFunction("g_app", "setName", &Application::setName, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "setCompactName", &Application::setCompactName, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "setVersion", &Application::setVersion, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "isRunning", &Application::isRunning, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "isStopping", &Application::isStopping, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getName", &Application::getName, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getCompactName", &Application::getCompactName, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getVersion", &Application::getVersion, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getBuildCompiler", &Application::getBuildCompiler, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getBuildDate", &Application::getBuildDate, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getBuildRevision", &Application::getBuildRevision, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getBuildCommit", &Application::getBuildCommit, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getBuildType", &Application::getBuildType, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getBuildArch", &Application::getBuildArch, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getAuthor", &Application::getAuthor, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getOs", &Application::getOs, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "getStartupOptions", &Application::getStartupOptions, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "exit", &Application::exit, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "quick_exit", &Application::quick_exit, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "isMobile", &Application::isMobile, static_cast(&g_app)); - g_lua.bindSingletonFunction("g_app", "restart", &Application::restart, static_cast(&g_app)); - - // Crypt - g_lua.registerSingletonClass("g_crypt"); - g_lua.bindSingletonFunction("g_crypt", "genUUID", &Crypt::genUUID, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "setMachineUUID", &Crypt::setMachineUUID, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "getMachineUUID", &Crypt::getMachineUUID, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "encrypt", &Crypt::encrypt, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "decrypt", &Crypt::decrypt, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "sha1Encode", &Crypt::sha1Encode, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "md5Encode", &Crypt::md5Encode, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "crc32", &Crypt::crc32, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "rsaGenerateKey", &Crypt::rsaGenerateKey, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "rsaSetPublicKey", &Crypt::rsaSetPublicKey, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "rsaSetPrivateKey", &Crypt::rsaSetPrivateKey, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "rsaCheckKey", &Crypt::rsaCheckKey, &g_crypt); - g_lua.bindSingletonFunction("g_crypt", "rsaGetSize", &Crypt::rsaGetSize, &g_crypt); - - // Clock - g_lua.registerSingletonClass("g_clock"); - g_lua.bindSingletonFunction("g_clock", "micros", &Clock::micros, &g_clock); - g_lua.bindSingletonFunction("g_clock", "millis", &Clock::millis, &g_clock); - g_lua.bindSingletonFunction("g_clock", "seconds", &Clock::seconds, &g_clock); - g_lua.bindSingletonFunction("g_clock", "realMillis", &Clock::realMillis, &g_clock); - g_lua.bindSingletonFunction("g_clock", "realMicros", &Clock::realMicros, &g_clock); - - // ConfigManager - g_lua.registerSingletonClass("g_configs"); - g_lua.bindSingletonFunction("g_configs", "getSettings", &ConfigManager::getSettings, &g_configs); - g_lua.bindSingletonFunction("g_configs", "get", &ConfigManager::get, &g_configs); - g_lua.bindSingletonFunction("g_configs", "loadSettings", &ConfigManager::loadSettings, &g_configs); - g_lua.bindSingletonFunction("g_configs", "load", &ConfigManager::load, &g_configs); - g_lua.bindSingletonFunction("g_configs", "unload", &ConfigManager::unload, &g_configs); - g_lua.bindSingletonFunction("g_configs", "create", &ConfigManager::create, &g_configs); - - // Logger - g_lua.registerSingletonClass("g_logger"); - g_lua.bindSingletonFunction("g_logger", "log", &Logger::log, &g_logger); - g_lua.bindSingletonFunction("g_logger", "fireOldMessages", &Logger::fireOldMessages, &g_logger); - g_lua.bindSingletonFunction("g_logger", "setLogFile", &Logger::setLogFile, &g_logger); - g_lua.bindSingletonFunction("g_logger", "setOnLog", &Logger::setOnLog, &g_logger); - g_lua.bindSingletonFunction("g_logger", "debug", &Logger::debug, &g_logger); - g_lua.bindSingletonFunction("g_logger", "info", &Logger::info, &g_logger); - g_lua.bindSingletonFunction("g_logger", "warning", &Logger::warning, &g_logger); - g_lua.bindSingletonFunction("g_logger", "error", &Logger::error, &g_logger); - g_lua.bindSingletonFunction("g_logger", "fatal", &Logger::fatal, &g_logger); - g_lua.bindSingletonFunction("g_logger", "getLastLog", &Logger::getLastLog, &g_logger); - - // Lua stats - g_lua.registerSingletonClass("g_stats"); - g_lua.bindSingletonFunction("g_stats", "types", &Stats::types, &g_stats); - g_lua.bindSingletonFunction("g_stats", "get", &Stats::get, &g_stats); - g_lua.bindSingletonFunction("g_stats", "clear", &Stats::clear, &g_stats); - g_lua.bindSingletonFunction("g_stats", "clearAll", &Stats::clearAll, &g_stats); - g_lua.bindSingletonFunction("g_stats", "getSlow", &Stats::getSlow, &g_stats); - g_lua.bindSingletonFunction("g_stats", "clearSlow", &Stats::clearSlow, &g_stats); - g_lua.bindSingletonFunction("g_stats", "getSleepTime", &Stats::getSleepTime, &g_stats); - g_lua.bindSingletonFunction("g_stats", "resetSleepTime", &Stats::resetSleepTime, &g_stats); - g_lua.bindSingletonFunction("g_stats", "getWidgetsInfo", &Stats::getWidgetsInfo, &g_stats); - - g_lua.registerSingletonClass("g_extras"); - g_lua.bindSingletonFunction("g_extras", "set", &Extras::set, &g_extras); - g_lua.bindSingletonFunction("g_extras", "get", &Extras::get, &g_extras); - g_lua.bindSingletonFunction("g_extras", "getDescription", &Extras::getDescription, &g_extras); - g_lua.bindSingletonFunction("g_extras", "getAll", &Extras::getAll, &g_extras); - - g_lua.registerSingletonClass("g_http"); - g_lua.bindSingletonFunction("g_http", "get", &Http::get, &g_http); - g_lua.bindSingletonFunction("g_http", "post", &Http::post, &g_http); - g_lua.bindSingletonFunction("g_http", "download", &Http::download, &g_http); - g_lua.bindSingletonFunction("g_http", "ws", &Http::ws, &g_http); - g_lua.bindSingletonFunction("g_http", "wsSend", &Http::wsSend, &g_http); - g_lua.bindSingletonFunction("g_http", "wsClose", &Http::wsClose, &g_http); - g_lua.bindSingletonFunction("g_http", "cancel", &Http::cancel, &g_http); - g_lua.bindSingletonFunction("g_http", "setUserAgent", &Http::setUserAgent, &g_http); - - g_lua.registerSingletonClass("g_atlas"); - g_lua.bindSingletonFunction("g_atlas", "getStats", &Atlas::getStats, &g_atlas); - - // ModuleManager - g_lua.registerSingletonClass("g_modules"); - g_lua.bindSingletonFunction("g_modules", "discoverModules", &ModuleManager::discoverModules, &g_modules); - g_lua.bindSingletonFunction("g_modules", "autoLoadModules", &ModuleManager::autoLoadModules, &g_modules); - g_lua.bindSingletonFunction("g_modules", "discoverModule", &ModuleManager::discoverModule, &g_modules); - g_lua.bindSingletonFunction("g_modules", "ensureModuleLoaded", &ModuleManager::ensureModuleLoaded, &g_modules); - g_lua.bindSingletonFunction("g_modules", "unloadModules", &ModuleManager::unloadModules, &g_modules); - g_lua.bindSingletonFunction("g_modules", "reloadModules", &ModuleManager::reloadModules, &g_modules); - g_lua.bindSingletonFunction("g_modules", "getModule", &ModuleManager::getModule, &g_modules); - g_lua.bindSingletonFunction("g_modules", "getModules", &ModuleManager::getModules, &g_modules); - - // EventDispatcher - g_lua.registerSingletonClass("g_dispatcher"); - g_lua.bindSingletonFunction("g_dispatcher", "addEvent", &EventDispatcher::addEventEx, &g_dispatcher); - g_lua.bindSingletonFunction("g_dispatcher", "scheduleEvent", &EventDispatcher::scheduleEventEx, &g_dispatcher); - g_lua.bindSingletonFunction("g_dispatcher", "cycleEvent", &EventDispatcher::cycleEventEx, &g_dispatcher); - - // ResourceManager - g_lua.registerSingletonClass("g_resources"); - g_lua.bindSingletonFunction("g_resources", "fileExists", &ResourceManager::fileExists, &g_resources); - g_lua.bindSingletonFunction("g_resources", "directoryExists", &ResourceManager::directoryExists, &g_resources); - g_lua.bindSingletonFunction("g_resources", "getWorkDir", &ResourceManager::getWorkDir, &g_resources); - g_lua.bindSingletonFunction("g_resources", "getWriteDir", &ResourceManager::getWriteDir, &g_resources); - g_lua.bindSingletonFunction("g_resources", "getBinaryName", &ResourceManager::getBinaryName, &g_resources); - g_lua.bindSingletonFunction("g_resources", "listDirectoryFiles", &ResourceManager::listDirectoryFiles, &g_resources); - g_lua.bindSingletonFunction("g_resources", "isFileType", &ResourceManager::isFileType, &g_resources); - g_lua.bindSingletonFunction("g_resources", "readFileContents", &ResourceManager::readFileContentsSafe, &g_resources); - g_lua.bindSingletonFunction("g_resources", "writeFileContents", &ResourceManager::writeFileContents, &g_resources); - g_lua.bindSingletonFunction("g_resources", "guessFilePath", &ResourceManager::guessFilePath, &g_resources); - g_lua.bindSingletonFunction("g_resources", "makeDir", &ResourceManager::makeDir, &g_resources); - g_lua.bindSingletonFunction("g_resources", "deleteFile", &ResourceManager::deleteFile, &g_resources); - g_lua.bindSingletonFunction("g_resources", "readCrashLog", [] { return std::string(); }); - g_lua.bindSingletonFunction("g_resources", "deleteCrashLog", [] { return std::string(); }); - - g_lua.bindSingletonFunction("g_resources", "resolvePath", &ResourceManager::resolvePath, &g_resources); - g_lua.bindSingletonFunction("g_resources", "isLoadedFromMemory", &ResourceManager::isLoadedFromMemory, &g_resources); - g_lua.bindSingletonFunction("g_resources", "isLoadedFromArchive", &ResourceManager::isLoadedFromArchive, &g_resources); - g_lua.bindSingletonFunction("g_resources", "listUpdateableFiles", [] { return std::list(); } ); - g_lua.bindSingletonFunction("g_resources", "fileChecksum", &ResourceManager::fileChecksum, &g_resources); - g_lua.bindSingletonFunction("g_resources", "filesChecksums", &ResourceManager::filesChecksums, &g_resources); - g_lua.bindSingletonFunction("g_resources", "selfChecksum", &ResourceManager::selfChecksum, &g_resources); - g_lua.bindSingletonFunction("g_resources", "updateData", &ResourceManager::updateData, &g_resources); - g_lua.bindSingletonFunction("g_resources", "updateExecutable", &ResourceManager::updateExecutable, &g_resources); - g_lua.bindSingletonFunction("g_resources", "createArchive", &ResourceManager::createArchive, &g_resources); - g_lua.bindSingletonFunction("g_resources", "decompressArchive", &ResourceManager::decompressArchive, &g_resources); - g_lua.bindSingletonFunction("g_resources", "setLayout", &ResourceManager::setLayout, &g_resources); - g_lua.bindSingletonFunction("g_resources", "getLayout", &ResourceManager::getLayout, &g_resources); - - // Config - g_lua.registerClass(); - g_lua.bindClassMemberFunction("save", &Config::save); - g_lua.bindClassMemberFunction("setValue", &Config::setValue); - g_lua.bindClassMemberFunction("setList", &Config::setList); - g_lua.bindClassMemberFunction("getValue", &Config::getValue); - g_lua.bindClassMemberFunction("getList", &Config::getList); - g_lua.bindClassMemberFunction("exists", &Config::exists); - g_lua.bindClassMemberFunction("remove", &Config::remove); - g_lua.bindClassMemberFunction("setNode", &Config::setNode); - g_lua.bindClassMemberFunction("getNode", &Config::getNode); - g_lua.bindClassMemberFunction("mergeNode", &Config::mergeNode); - g_lua.bindClassMemberFunction("getFileName", &Config::getFileName); - - // Module - g_lua.registerClass(); - g_lua.bindClassMemberFunction("load", &Module::load); - g_lua.bindClassMemberFunction("unload", &Module::unload); - g_lua.bindClassMemberFunction("reload", &Module::reload); - g_lua.bindClassMemberFunction("canReload", &Module::canReload); - g_lua.bindClassMemberFunction("canUnload", &Module::canUnload); - g_lua.bindClassMemberFunction("isLoaded", &Module::isLoaded); - g_lua.bindClassMemberFunction("isReloadble", &Module::isReloadable); - g_lua.bindClassMemberFunction("isSandboxed", &Module::isSandboxed); - g_lua.bindClassMemberFunction("getDescription", &Module::getDescription); - g_lua.bindClassMemberFunction("getName", &Module::getName); - g_lua.bindClassMemberFunction("getAuthor", &Module::getAuthor); - g_lua.bindClassMemberFunction("getWebsite", &Module::getWebsite); - g_lua.bindClassMemberFunction("getVersion", &Module::getVersion); - g_lua.bindClassMemberFunction("getSandbox", &Module::getSandbox); - g_lua.bindClassMemberFunction("isAutoLoad", &Module::isAutoLoad); - g_lua.bindClassMemberFunction("getAutoLoadPriority", &Module::getAutoLoadPriority); - - // Event - g_lua.registerClass(); - g_lua.bindClassMemberFunction("cancel", &Event::cancel); - g_lua.bindClassMemberFunction("execute", &Event::execute); - g_lua.bindClassMemberFunction("isCanceled", &Event::isCanceled); - g_lua.bindClassMemberFunction("isExecuted", &Event::isExecuted); - - // ScheduledEvent - g_lua.registerClass(); - g_lua.bindClassMemberFunction("nextCycle", &ScheduledEvent::nextCycle); - g_lua.bindClassMemberFunction("ticks", &ScheduledEvent::ticks); - g_lua.bindClassMemberFunction("remainingTicks", &ScheduledEvent::remainingTicks); - g_lua.bindClassMemberFunction("delay", &ScheduledEvent::delay); - g_lua.bindClassMemberFunction("cyclesExecuted", &ScheduledEvent::cyclesExecuted); - g_lua.bindClassMemberFunction("maxCycles", &ScheduledEvent::maxCycles); - -#ifdef FW_GRAPHICS - // GraphicalApplication - g_lua.bindSingletonFunction("g_app", "setMaxFps", &GraphicalApplication::setMaxFps, &g_app); - g_lua.bindSingletonFunction("g_app", "getMaxFps", &GraphicalApplication::getMaxFps, &g_app); - g_lua.bindSingletonFunction("g_app", "getFps", &GraphicalApplication::getFps, &g_app); - g_lua.bindSingletonFunction("g_app", "getGraphicsFps", &GraphicalApplication::getGraphicsFps, &g_app); - g_lua.bindSingletonFunction("g_app", "getProcessingFps", &GraphicalApplication::getProcessingFps, &g_app); - g_lua.bindSingletonFunction("g_app", "isOnInputEvent", &GraphicalApplication::isOnInputEvent, &g_app); - g_lua.bindSingletonFunction("g_app", "doScreenshot", &GraphicalApplication::doScreenshot, &g_app); - g_lua.bindSingletonFunction("g_app", "scaleDown", &GraphicalApplication::scaleDown, &g_app); - g_lua.bindSingletonFunction("g_app", "scaleUp", &GraphicalApplication::scaleUp, &g_app); - g_lua.bindSingletonFunction("g_app", "scale", &GraphicalApplication::scale, &g_app); - - // AdaptiveRenderer - g_lua.registerSingletonClass("g_adaptiveRenderer"); - g_lua.bindSingletonFunction("g_adaptiveRenderer", "getLevel", &AdaptiveRenderer::getLevel, &g_adaptiveRenderer); - g_lua.bindSingletonFunction("g_adaptiveRenderer", "setLevel", &AdaptiveRenderer::setForcedLevel, &g_adaptiveRenderer); - g_lua.bindSingletonFunction("g_adaptiveRenderer", "getDebugInfo", &AdaptiveRenderer::getDebugInfo, &g_adaptiveRenderer); - - // PlatformWindow - g_lua.registerSingletonClass("g_window"); - g_lua.bindSingletonFunction("g_window", "move", &PlatformWindow::move, &g_window); - g_lua.bindSingletonFunction("g_window", "resize", &PlatformWindow::resize, &g_window); - g_lua.bindSingletonFunction("g_window", "show", &PlatformWindow::show, &g_window); - g_lua.bindSingletonFunction("g_window", "hide", &PlatformWindow::hide, &g_window); - g_lua.bindSingletonFunction("g_window", "poll", [] {}); // for backward compability - g_lua.bindSingletonFunction("g_window", "maximize", &PlatformWindow::maximize, &g_window); - g_lua.bindSingletonFunction("g_window", "restoreMouseCursor", &PlatformWindow::restoreMouseCursor, &g_window); - g_lua.bindSingletonFunction("g_window", "showMouse", &PlatformWindow::showMouse, &g_window); - g_lua.bindSingletonFunction("g_window", "hideMouse", &PlatformWindow::hideMouse, &g_window); - g_lua.bindSingletonFunction("g_window", "setTitle", &PlatformWindow::setTitle, &g_window); - g_lua.bindSingletonFunction("g_window", "setMouseCursor", &PlatformWindow::setMouseCursor, &g_window); - g_lua.bindSingletonFunction("g_window", "setMinimumSize", &PlatformWindow::setMinimumSize, &g_window); - g_lua.bindSingletonFunction("g_window", "setFullscreen", &PlatformWindow::setFullscreen, &g_window); - g_lua.bindSingletonFunction("g_window", "setVerticalSync", &PlatformWindow::setVerticalSync, &g_window); - g_lua.bindSingletonFunction("g_window", "setIcon", &PlatformWindow::setIcon, &g_window); - g_lua.bindSingletonFunction("g_window", "setClipboardText", &PlatformWindow::setClipboardText, &g_window); - g_lua.bindSingletonFunction("g_window", "getDisplaySize", &PlatformWindow::getDisplaySize, &g_window); - g_lua.bindSingletonFunction("g_window", "getClipboardText", &PlatformWindow::getClipboardText, &g_window); - g_lua.bindSingletonFunction("g_window", "getPlatformType", &PlatformWindow::getPlatformType, &g_window); - g_lua.bindSingletonFunction("g_window", "getDisplayWidth", &PlatformWindow::getDisplayWidth, &g_window); - g_lua.bindSingletonFunction("g_window", "getDisplayHeight", &PlatformWindow::getDisplayHeight, &g_window); - g_lua.bindSingletonFunction("g_window", "getUnmaximizedSize", &PlatformWindow::getUnmaximizedSize, &g_window); - g_lua.bindSingletonFunction("g_window", "getSize", &PlatformWindow::getSize, &g_window); - g_lua.bindSingletonFunction("g_window", "getWidth", &PlatformWindow::getWidth, &g_window); - g_lua.bindSingletonFunction("g_window", "getHeight", &PlatformWindow::getHeight, &g_window); - g_lua.bindSingletonFunction("g_window", "getUnmaximizedPos", &PlatformWindow::getUnmaximizedPos, &g_window); - g_lua.bindSingletonFunction("g_window", "getPosition", &PlatformWindow::getPosition, &g_window); - g_lua.bindSingletonFunction("g_window", "getX", &PlatformWindow::getX, &g_window); - g_lua.bindSingletonFunction("g_window", "getY", &PlatformWindow::getY, &g_window); - g_lua.bindSingletonFunction("g_window", "getMousePosition", &PlatformWindow::getMousePosition, &g_window); - g_lua.bindSingletonFunction("g_window", "getKeyboardModifiers", &PlatformWindow::getKeyboardModifiers, &g_window); - g_lua.bindSingletonFunction("g_window", "isKeyPressed", &PlatformWindow::isKeyPressed, &g_window); - g_lua.bindSingletonFunction("g_window", "isMouseButtonPressed", &PlatformWindow::isMouseButtonPressed, &g_window); - g_lua.bindSingletonFunction("g_window", "isVisible", &PlatformWindow::isVisible, &g_window); - g_lua.bindSingletonFunction("g_window", "isFullscreen", &PlatformWindow::isFullscreen, &g_window); - g_lua.bindSingletonFunction("g_window", "isMaximized", &PlatformWindow::isMaximized, &g_window); - g_lua.bindSingletonFunction("g_window", "hasFocus", &PlatformWindow::hasFocus, &g_window); - g_lua.bindSingletonFunction("g_window", "showTextEditor", &PlatformWindow::showTextEditor, &g_window); - - // Input - g_lua.registerSingletonClass("g_mouse"); - g_lua.bindSingletonFunction("g_mouse", "loadCursors", &Mouse::loadCursors, &g_mouse); - g_lua.bindSingletonFunction("g_mouse", "addCursor", &Mouse::addCursor, &g_mouse); - g_lua.bindSingletonFunction("g_mouse", "pushCursor", &Mouse::pushCursor, &g_mouse); - g_lua.bindSingletonFunction("g_mouse", "popCursor", &Mouse::popCursor, &g_mouse); - g_lua.bindSingletonFunction("g_mouse", "isCursorChanged", &Mouse::isCursorChanged, &g_mouse); - g_lua.bindSingletonFunction("g_mouse", "isPressed", &Mouse::isPressed, &g_mouse); - - // Graphics - g_lua.registerSingletonClass("g_graphics"); - g_lua.bindSingletonFunction("g_graphics", "getVendor", &Graphics::getVendor, &g_graphics); - g_lua.bindSingletonFunction("g_graphics", "getRenderer", &Graphics::getRenderer, &g_graphics); - g_lua.bindSingletonFunction("g_graphics", "getVersion", &Graphics::getVersion, &g_graphics); - g_lua.bindSingletonFunction("g_graphics", "getExtensions", &Graphics::getExtensions, &g_graphics); - - // Textures - g_lua.registerSingletonClass("g_textures"); - g_lua.bindSingletonFunction("g_textures", "preload", &TextureManager::preload, &g_textures); - g_lua.bindSingletonFunction("g_textures", "clearCache", &TextureManager::clearCache, &g_textures); - g_lua.bindSingletonFunction("g_textures", "reload", &TextureManager::reload, &g_textures); - - // UI - g_lua.registerSingletonClass("g_ui"); - g_lua.bindSingletonFunction("g_ui", "clearStyles", &UIManager::clearStyles, &g_ui); - g_lua.bindSingletonFunction("g_ui", "importStyle", &UIManager::importStyle, &g_ui); - g_lua.bindSingletonFunction("g_ui", "importStyleFromString", &UIManager::importStyleFromString, &g_ui); - g_lua.bindSingletonFunction("g_ui", "getStyle", &UIManager::getStyle, &g_ui); - g_lua.bindSingletonFunction("g_ui", "getStyleClass", &UIManager::getStyleClass, &g_ui); - g_lua.bindSingletonFunction("g_ui", "loadUI", &UIManager::loadUI, &g_ui); - g_lua.bindSingletonFunction("g_ui", "loadUIFromString", &UIManager::loadUIFromString, &g_ui); - g_lua.bindSingletonFunction("g_ui", "displayUI", &UIManager::displayUI, &g_ui); - g_lua.bindSingletonFunction("g_ui", "createWidget", &UIManager::createWidget, &g_ui); - g_lua.bindSingletonFunction("g_ui", "createWidgetFromOTML", &UIManager::createWidgetFromOTML, &g_ui); - g_lua.bindSingletonFunction("g_ui", "getRootWidget", &UIManager::getRootWidget, &g_ui); - g_lua.bindSingletonFunction("g_ui", "getDraggingWidget", &UIManager::getDraggingWidget, &g_ui); - g_lua.bindSingletonFunction("g_ui", "getPressedWidget", &UIManager::getPressedWidget, &g_ui); - g_lua.bindSingletonFunction("g_ui", "setDebugBoxesDrawing", &UIManager::setDebugBoxesDrawing, &g_ui); - g_lua.bindSingletonFunction("g_ui", "isDrawingDebugBoxes", &UIManager::isDrawingDebugBoxes, &g_ui); - g_lua.bindSingletonFunction("g_ui", "isMouseGrabbed", &UIManager::isMouseGrabbed, &g_ui); - g_lua.bindSingletonFunction("g_ui", "isKeyboardGrabbed", &UIManager::isKeyboardGrabbed, &g_ui); - - // FontManager - g_lua.registerSingletonClass("g_fonts"); - g_lua.bindSingletonFunction("g_fonts", "clearFonts", &FontManager::clearFonts, &g_fonts); - g_lua.bindSingletonFunction("g_fonts", "importFont", &FontManager::importFont, &g_fonts); - g_lua.bindSingletonFunction("g_fonts", "fontExists", &FontManager::fontExists, &g_fonts); - g_lua.bindSingletonFunction("g_fonts", "setDefaultFont", &FontManager::setDefaultFont, &g_fonts); - - // Particles, for backward compability - g_lua.registerSingletonClass("g_particles"); - g_lua.bindSingletonFunction("g_particles", "importParticle", [](const std::string& v) {}); - - // UIWidget - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UIWidgetPtr(new UIWidget); }); - g_lua.bindClassMemberFunction("addChild", &UIWidget::addChild); - g_lua.bindClassMemberFunction("insertChild", &UIWidget::insertChild); - g_lua.bindClassMemberFunction("removeChild", &UIWidget::removeChild); - g_lua.bindClassMemberFunction("focusChild", &UIWidget::focusChild); - g_lua.bindClassMemberFunction("focusNextChild", &UIWidget::focusNextChild); - g_lua.bindClassMemberFunction("focusPreviousChild", &UIWidget::focusPreviousChild); - g_lua.bindClassMemberFunction("lowerChild", &UIWidget::lowerChild); - g_lua.bindClassMemberFunction("raiseChild", &UIWidget::raiseChild); - g_lua.bindClassMemberFunction("moveChildToIndex", &UIWidget::moveChildToIndex); - g_lua.bindClassMemberFunction("reorderChildren", &UIWidget::reorderChildren); - g_lua.bindClassMemberFunction("lockChild", &UIWidget::lockChild); - g_lua.bindClassMemberFunction("unlockChild", &UIWidget::unlockChild); - g_lua.bindClassMemberFunction("mergeStyle", &UIWidget::mergeStyle); - g_lua.bindClassMemberFunction("applyStyle", &UIWidget::applyStyle); - g_lua.bindClassMemberFunction("addAnchor", &UIWidget::addAnchor); - g_lua.bindClassMemberFunction("removeAnchor", &UIWidget::removeAnchor); - g_lua.bindClassMemberFunction("fill", &UIWidget::fill); - g_lua.bindClassMemberFunction("centerIn", &UIWidget::centerIn); - g_lua.bindClassMemberFunction("breakAnchors", &UIWidget::breakAnchors); - g_lua.bindClassMemberFunction("updateParentLayout", &UIWidget::updateParentLayout); - g_lua.bindClassMemberFunction("updateLayout", &UIWidget::updateLayout); - g_lua.bindClassMemberFunction("lock", &UIWidget::lock); - g_lua.bindClassMemberFunction("unlock", &UIWidget::unlock); - g_lua.bindClassMemberFunction("focus", &UIWidget::focus); - g_lua.bindClassMemberFunction("lower", &UIWidget::lower); - g_lua.bindClassMemberFunction("raise", &UIWidget::raise); - g_lua.bindClassMemberFunction("grabMouse", &UIWidget::grabMouse); - g_lua.bindClassMemberFunction("ungrabMouse", &UIWidget::ungrabMouse); - g_lua.bindClassMemberFunction("grabKeyboard", &UIWidget::grabKeyboard); - g_lua.bindClassMemberFunction("ungrabKeyboard", &UIWidget::ungrabKeyboard); - g_lua.bindClassMemberFunction("bindRectToParent", &UIWidget::bindRectToParent); - g_lua.bindClassMemberFunction("destroy", &UIWidget::destroy); - g_lua.bindClassMemberFunction("destroyChildren", &UIWidget::destroyChildren); - g_lua.bindClassMemberFunction("setId", &UIWidget::setId); - g_lua.bindClassMemberFunction("setParent", &UIWidget::setParent); - g_lua.bindClassMemberFunction("setLayout", &UIWidget::setLayout); - g_lua.bindClassMemberFunction("setRect", &UIWidget::setRect); - g_lua.bindClassMemberFunction("setStyle", &UIWidget::setStyle); - g_lua.bindClassMemberFunction("setStyleFromNode", &UIWidget::setStyleFromNode); - g_lua.bindClassMemberFunction("setEnabled", &UIWidget::setEnabled); - g_lua.bindClassMemberFunction("setVisible", &UIWidget::setVisible); - g_lua.bindClassMemberFunction("setOn", &UIWidget::setOn); - g_lua.bindClassMemberFunction("setChecked", &UIWidget::setChecked); - g_lua.bindClassMemberFunction("setFocusable", &UIWidget::setFocusable); - g_lua.bindClassMemberFunction("setPhantom", &UIWidget::setPhantom); - g_lua.bindClassMemberFunction("setDraggable", &UIWidget::setDraggable); - g_lua.bindClassMemberFunction("setFixedSize", &UIWidget::setFixedSize); - g_lua.bindClassMemberFunction("setClipping", &UIWidget::setClipping); - g_lua.bindClassMemberFunction("setLastFocusReason", &UIWidget::setLastFocusReason); - g_lua.bindClassMemberFunction("setAutoFocusPolicy", &UIWidget::setAutoFocusPolicy); - g_lua.bindClassMemberFunction("setAutoRepeatDelay", &UIWidget::setAutoRepeatDelay); - g_lua.bindClassMemberFunction("setVirtualOffset", &UIWidget::setVirtualOffset); - g_lua.bindClassMemberFunction("isVisible", &UIWidget::isVisible); - g_lua.bindClassMemberFunction("isChildLocked", &UIWidget::isChildLocked); - g_lua.bindClassMemberFunction("hasChild", &UIWidget::hasChild); - g_lua.bindClassMemberFunction("getChildIndex", &UIWidget::getChildIndex); - g_lua.bindClassMemberFunction("getMarginRect", &UIWidget::getMarginRect); - g_lua.bindClassMemberFunction("getPaddingRect", &UIWidget::getPaddingRect); - g_lua.bindClassMemberFunction("getChildrenRect", &UIWidget::getChildrenRect); - g_lua.bindClassMemberFunction("getAnchoredLayout", &UIWidget::getAnchoredLayout); - g_lua.bindClassMemberFunction("getRootParent", &UIWidget::getRootParent); - g_lua.bindClassMemberFunction("getChildAfter", &UIWidget::getChildAfter); - g_lua.bindClassMemberFunction("getChildBefore", &UIWidget::getChildBefore); - g_lua.bindClassMemberFunction("getChildById", &UIWidget::getChildById); - g_lua.bindClassMemberFunction("getChildByPos", &UIWidget::getChildByPos); - g_lua.bindClassMemberFunction("getChildByIndex", &UIWidget::getChildByIndex); - g_lua.bindClassMemberFunction("recursiveGetChildById", &UIWidget::recursiveGetChildById); - g_lua.bindClassMemberFunction("recursiveGetChildByPos", &UIWidget::recursiveGetChildByPos); - g_lua.bindClassMemberFunction("recursiveGetChildren", &UIWidget::recursiveGetChildren); - g_lua.bindClassMemberFunction("recursiveGetChildrenByPos", &UIWidget::recursiveGetChildrenByPos); - g_lua.bindClassMemberFunction("recursiveGetChildrenByMarginPos", &UIWidget::recursiveGetChildrenByMarginPos); - g_lua.bindClassMemberFunction("backwardsGetWidgetById", &UIWidget::backwardsGetWidgetById); - g_lua.bindClassMemberFunction("resize", &UIWidget::resize); - g_lua.bindClassMemberFunction("move", &UIWidget::move); - g_lua.bindClassMemberFunction("hide", &UIWidget::hide); - g_lua.bindClassMemberFunction("show", &UIWidget::show); - g_lua.bindClassMemberFunction("disable", &UIWidget::disable); - g_lua.bindClassMemberFunction("enable", &UIWidget::enable); - g_lua.bindClassMemberFunction("isActive", &UIWidget::isActive); - g_lua.bindClassMemberFunction("isEnabled", &UIWidget::isEnabled); - g_lua.bindClassMemberFunction("isDisabled", &UIWidget::isDisabled); - g_lua.bindClassMemberFunction("isFocused", &UIWidget::isFocused); - g_lua.bindClassMemberFunction("isHovered", &UIWidget::isHovered); - g_lua.bindClassMemberFunction("isPressed", &UIWidget::isPressed); - g_lua.bindClassMemberFunction("isFirst", &UIWidget::isFirst); - g_lua.bindClassMemberFunction("isMiddle", &UIWidget::isMiddle); - g_lua.bindClassMemberFunction("isLast", &UIWidget::isLast); - g_lua.bindClassMemberFunction("isAlternate", &UIWidget::isAlternate); - g_lua.bindClassMemberFunction("isChecked", &UIWidget::isChecked); - g_lua.bindClassMemberFunction("isOn", &UIWidget::isOn); - g_lua.bindClassMemberFunction("isDragging", &UIWidget::isDragging); - g_lua.bindClassMemberFunction("isHidden", &UIWidget::isHidden); - g_lua.bindClassMemberFunction("isExplicitlyEnabled", &UIWidget::isExplicitlyEnabled); - g_lua.bindClassMemberFunction("isExplicitlyVisible", &UIWidget::isExplicitlyVisible); - g_lua.bindClassMemberFunction("isFocusable", &UIWidget::isFocusable); - g_lua.bindClassMemberFunction("isPhantom", &UIWidget::isPhantom); - g_lua.bindClassMemberFunction("isDraggable", &UIWidget::isDraggable); - g_lua.bindClassMemberFunction("isFixedSize", &UIWidget::isFixedSize); - g_lua.bindClassMemberFunction("isClipping", &UIWidget::isClipping); - g_lua.bindClassMemberFunction("isDestroyed", &UIWidget::isDestroyed); - g_lua.bindClassMemberFunction("hasChildren", &UIWidget::hasChildren); - g_lua.bindClassMemberFunction("containsMarginPoint", &UIWidget::containsMarginPoint); - g_lua.bindClassMemberFunction("containsPaddingPoint", &UIWidget::containsPaddingPoint); - g_lua.bindClassMemberFunction("containsPoint", &UIWidget::containsPoint); - g_lua.bindClassMemberFunction("getId", &UIWidget::getId); - g_lua.bindClassMemberFunction("getSource", &UIWidget::getSource); - g_lua.bindClassMemberFunction("getParent", &UIWidget::getParent); - g_lua.bindClassMemberFunction("getFocusedChild", &UIWidget::getFocusedChild); - g_lua.bindClassMemberFunction("getChildren", &UIWidget::getChildren); - g_lua.bindClassMemberFunction("getFirstChild", &UIWidget::getFirstChild); - g_lua.bindClassMemberFunction("getLastChild", &UIWidget::getLastChild); - g_lua.bindClassMemberFunction("getLayout", &UIWidget::getLayout); - g_lua.bindClassMemberFunction("getStyle", &UIWidget::getStyle); - g_lua.bindClassMemberFunction("getChildCount", &UIWidget::getChildCount); - g_lua.bindClassMemberFunction("getLastFocusReason", &UIWidget::getLastFocusReason); - g_lua.bindClassMemberFunction("getAutoFocusPolicy", &UIWidget::getAutoFocusPolicy); - g_lua.bindClassMemberFunction("getAutoRepeatDelay", &UIWidget::getAutoRepeatDelay); - g_lua.bindClassMemberFunction("getVirtualOffset", &UIWidget::getVirtualOffset); - g_lua.bindClassMemberFunction("getStyleName", &UIWidget::getStyleName); - g_lua.bindClassMemberFunction("getLastClickPosition", &UIWidget::getLastClickPosition); - g_lua.bindClassMemberFunction("setX", &UIWidget::setX); - g_lua.bindClassMemberFunction("setY", &UIWidget::setY); - g_lua.bindClassMemberFunction("setWidth", &UIWidget::setWidth); - g_lua.bindClassMemberFunction("setHeight", &UIWidget::setHeight); - g_lua.bindClassMemberFunction("setSize", &UIWidget::setSize); - g_lua.bindClassMemberFunction("setPosition", &UIWidget::setPosition); - g_lua.bindClassMemberFunction("setColor", &UIWidget::setColor); - g_lua.bindClassMemberFunction("setBackgroundColor", &UIWidget::setBackgroundColor); - g_lua.bindClassMemberFunction("setBackgroundOffsetX", &UIWidget::setBackgroundOffsetX); - g_lua.bindClassMemberFunction("setBackgroundOffsetY", &UIWidget::setBackgroundOffsetY); - g_lua.bindClassMemberFunction("setBackgroundOffset", &UIWidget::setBackgroundOffset); - g_lua.bindClassMemberFunction("setBackgroundWidth", &UIWidget::setBackgroundWidth); - g_lua.bindClassMemberFunction("setBackgroundHeight", &UIWidget::setBackgroundHeight); - g_lua.bindClassMemberFunction("setBackgroundSize", &UIWidget::setBackgroundSize); - g_lua.bindClassMemberFunction("setBackgroundRect", &UIWidget::setBackgroundRect); - g_lua.bindClassMemberFunction("setIcon", &UIWidget::setIcon); - g_lua.bindClassMemberFunction("setIconColor", &UIWidget::setIconColor); - g_lua.bindClassMemberFunction("setIconOffsetX", &UIWidget::setIconOffsetX); - g_lua.bindClassMemberFunction("setIconOffsetY", &UIWidget::setIconOffsetY); - g_lua.bindClassMemberFunction("setIconOffset", &UIWidget::setIconOffset); - g_lua.bindClassMemberFunction("setIconWidth", &UIWidget::setIconWidth); - g_lua.bindClassMemberFunction("setIconHeight", &UIWidget::setIconHeight); - g_lua.bindClassMemberFunction("setIconSize", &UIWidget::setIconSize); - g_lua.bindClassMemberFunction("setIconRect", &UIWidget::setIconRect); - g_lua.bindClassMemberFunction("setIconClip", &UIWidget::setIconClip); - g_lua.bindClassMemberFunction("setIconAlign", &UIWidget::setIconAlign); - g_lua.bindClassMemberFunction("setBorderWidth", &UIWidget::setBorderWidth); - g_lua.bindClassMemberFunction("setBorderWidthTop", &UIWidget::setBorderWidthTop); - g_lua.bindClassMemberFunction("setBorderWidthRight", &UIWidget::setBorderWidthRight); - g_lua.bindClassMemberFunction("setBorderWidthBottom", &UIWidget::setBorderWidthBottom); - g_lua.bindClassMemberFunction("setBorderWidthLeft", &UIWidget::setBorderWidthLeft); - g_lua.bindClassMemberFunction("setBorderColor", &UIWidget::setBorderColor); - g_lua.bindClassMemberFunction("setBorderColorTop", &UIWidget::setBorderColorTop); - g_lua.bindClassMemberFunction("setBorderColorRight", &UIWidget::setBorderColorRight); - g_lua.bindClassMemberFunction("setBorderColorBottom", &UIWidget::setBorderColorBottom); - g_lua.bindClassMemberFunction("setBorderColorLeft", &UIWidget::setBorderColorLeft); - g_lua.bindClassMemberFunction("setMargin", &UIWidget::setMargin); - g_lua.bindClassMemberFunction("setMarginHorizontal", &UIWidget::setMarginHorizontal); - g_lua.bindClassMemberFunction("setMarginVertical", &UIWidget::setMarginVertical); - g_lua.bindClassMemberFunction("setMarginTop", &UIWidget::setMarginTop); - g_lua.bindClassMemberFunction("setMarginRight", &UIWidget::setMarginRight); - g_lua.bindClassMemberFunction("setMarginBottom", &UIWidget::setMarginBottom); - g_lua.bindClassMemberFunction("setMarginLeft", &UIWidget::setMarginLeft); - g_lua.bindClassMemberFunction("setPadding", &UIWidget::setPadding); - g_lua.bindClassMemberFunction("setPaddingHorizontal", &UIWidget::setPaddingHorizontal); - g_lua.bindClassMemberFunction("setPaddingVertical", &UIWidget::setPaddingVertical); - g_lua.bindClassMemberFunction("setPaddingTop", &UIWidget::setPaddingTop); - g_lua.bindClassMemberFunction("setPaddingRight", &UIWidget::setPaddingRight); - g_lua.bindClassMemberFunction("setPaddingBottom", &UIWidget::setPaddingBottom); - g_lua.bindClassMemberFunction("setPaddingLeft", &UIWidget::setPaddingLeft); - g_lua.bindClassMemberFunction("setOpacity", &UIWidget::setOpacity); - g_lua.bindClassMemberFunction("setRotation", &UIWidget::setRotation); - g_lua.bindClassMemberFunction("getX", &UIWidget::getX); - g_lua.bindClassMemberFunction("getY", &UIWidget::getY); - g_lua.bindClassMemberFunction("getPosition", &UIWidget::getPosition); - g_lua.bindClassMemberFunction("getWidth", &UIWidget::getWidth); - g_lua.bindClassMemberFunction("getHeight", &UIWidget::getHeight); - g_lua.bindClassMemberFunction("getSize", &UIWidget::getSize); - g_lua.bindClassMemberFunction("getRect", &UIWidget::getRect); - g_lua.bindClassMemberFunction("getColor", &UIWidget::getColor); - g_lua.bindClassMemberFunction("getBackgroundColor", &UIWidget::getBackgroundColor); - g_lua.bindClassMemberFunction("getBackgroundOffsetX", &UIWidget::getBackgroundOffsetX); - g_lua.bindClassMemberFunction("getBackgroundOffsetY", &UIWidget::getBackgroundOffsetY); - g_lua.bindClassMemberFunction("getBackgroundOffset", &UIWidget::getBackgroundOffset); - g_lua.bindClassMemberFunction("getBackgroundWidth", &UIWidget::getBackgroundWidth); - g_lua.bindClassMemberFunction("getBackgroundHeight", &UIWidget::getBackgroundHeight); - g_lua.bindClassMemberFunction("getBackgroundSize", &UIWidget::getBackgroundSize); - g_lua.bindClassMemberFunction("getBackgroundRect", &UIWidget::getBackgroundRect); - g_lua.bindClassMemberFunction("getIconColor", &UIWidget::getIconColor); - g_lua.bindClassMemberFunction("getIconOffsetX", &UIWidget::getIconOffsetX); - g_lua.bindClassMemberFunction("getIconOffsetY", &UIWidget::getIconOffsetY); - g_lua.bindClassMemberFunction("getIconOffset", &UIWidget::getIconOffset); - g_lua.bindClassMemberFunction("getIconWidth", &UIWidget::getIconWidth); - g_lua.bindClassMemberFunction("getIconHeight", &UIWidget::getIconHeight); - g_lua.bindClassMemberFunction("getIconSize", &UIWidget::getIconSize); - g_lua.bindClassMemberFunction("getIconRect", &UIWidget::getIconRect); - g_lua.bindClassMemberFunction("getIconClip", &UIWidget::getIconClip); - g_lua.bindClassMemberFunction("getIconAlign", &UIWidget::getIconAlign); - g_lua.bindClassMemberFunction("getBorderTopColor", &UIWidget::getBorderTopColor); - g_lua.bindClassMemberFunction("getBorderRightColor", &UIWidget::getBorderRightColor); - g_lua.bindClassMemberFunction("getBorderBottomColor", &UIWidget::getBorderBottomColor); - g_lua.bindClassMemberFunction("getBorderLeftColor", &UIWidget::getBorderLeftColor); - g_lua.bindClassMemberFunction("getBorderTopWidth", &UIWidget::getBorderTopWidth); - g_lua.bindClassMemberFunction("getBorderRightWidth", &UIWidget::getBorderRightWidth); - g_lua.bindClassMemberFunction("getBorderBottomWidth", &UIWidget::getBorderBottomWidth); - g_lua.bindClassMemberFunction("getBorderLeftWidth", &UIWidget::getBorderLeftWidth); - g_lua.bindClassMemberFunction("getMarginTop", &UIWidget::getMarginTop); - g_lua.bindClassMemberFunction("getMarginRight", &UIWidget::getMarginRight); - g_lua.bindClassMemberFunction("getMarginBottom", &UIWidget::getMarginBottom); - g_lua.bindClassMemberFunction("getMarginLeft", &UIWidget::getMarginLeft); - g_lua.bindClassMemberFunction("getPaddingTop", &UIWidget::getPaddingTop); - g_lua.bindClassMemberFunction("getPaddingRight", &UIWidget::getPaddingRight); - g_lua.bindClassMemberFunction("getPaddingBottom", &UIWidget::getPaddingBottom); - g_lua.bindClassMemberFunction("getPaddingLeft", &UIWidget::getPaddingLeft); - g_lua.bindClassMemberFunction("getOpacity", &UIWidget::getOpacity); - g_lua.bindClassMemberFunction("getRotation", &UIWidget::getRotation); - g_lua.bindClassMemberFunction("setQRCode", &UIWidget::setQRCode); - g_lua.bindClassMemberFunction("setImageSource", &UIWidget::setImageSource); - g_lua.bindClassMemberFunction("setImageSourceBase64", &UIWidget::setImageSourceBase64); - g_lua.bindClassMemberFunction("setImageClip", &UIWidget::setImageClip); - g_lua.bindClassMemberFunction("setImageOffsetX", &UIWidget::setImageOffsetX); - g_lua.bindClassMemberFunction("setImageOffsetY", &UIWidget::setImageOffsetY); - g_lua.bindClassMemberFunction("setImageOffset", &UIWidget::setImageOffset); - g_lua.bindClassMemberFunction("setImageWidth", &UIWidget::setImageWidth); - g_lua.bindClassMemberFunction("setImageHeight", &UIWidget::setImageHeight); - g_lua.bindClassMemberFunction("setImageSize", &UIWidget::setImageSize); - g_lua.bindClassMemberFunction("setImageRect", &UIWidget::setImageRect); - g_lua.bindClassMemberFunction("setImageColor", &UIWidget::setImageColor); - g_lua.bindClassMemberFunction("setImageFixedRatio", &UIWidget::setImageFixedRatio); - g_lua.bindClassMemberFunction("setImageRepeated", &UIWidget::setImageRepeated); - g_lua.bindClassMemberFunction("setImageSmooth", &UIWidget::setImageSmooth); - g_lua.bindClassMemberFunction("setImageAutoResize", &UIWidget::setImageAutoResize); - g_lua.bindClassMemberFunction("setImageBorderTop", &UIWidget::setImageBorderTop); - g_lua.bindClassMemberFunction("setImageBorderRight", &UIWidget::setImageBorderRight); - g_lua.bindClassMemberFunction("setImageBorderBottom", &UIWidget::setImageBorderBottom); - g_lua.bindClassMemberFunction("setImageBorderLeft", &UIWidget::setImageBorderLeft); - g_lua.bindClassMemberFunction("setImageBorder", &UIWidget::setImageBorder); - g_lua.bindClassMemberFunction("getImageClip", &UIWidget::getImageClip); - g_lua.bindClassMemberFunction("getImageOffsetX", &UIWidget::getImageOffsetX); - g_lua.bindClassMemberFunction("getImageOffsetY", &UIWidget::getImageOffsetY); - g_lua.bindClassMemberFunction("getImageOffset", &UIWidget::getImageOffset); - g_lua.bindClassMemberFunction("getImageWidth", &UIWidget::getImageWidth); - g_lua.bindClassMemberFunction("getImageHeight", &UIWidget::getImageHeight); - g_lua.bindClassMemberFunction("getImageSize", &UIWidget::getImageSize); - g_lua.bindClassMemberFunction("getImageRect", &UIWidget::getImageRect); - g_lua.bindClassMemberFunction("getImageColor", &UIWidget::getImageColor); - g_lua.bindClassMemberFunction("isImageFixedRatio", &UIWidget::isImageFixedRatio); - g_lua.bindClassMemberFunction("isImageSmooth", &UIWidget::isImageSmooth); - g_lua.bindClassMemberFunction("isImageAutoResize", &UIWidget::isImageAutoResize); - g_lua.bindClassMemberFunction("getImageBorderTop", &UIWidget::getImageBorderTop); - g_lua.bindClassMemberFunction("getImageBorderRight", &UIWidget::getImageBorderRight); - g_lua.bindClassMemberFunction("getImageBorderBottom", &UIWidget::getImageBorderBottom); - g_lua.bindClassMemberFunction("getImageBorderLeft", &UIWidget::getImageBorderLeft); - g_lua.bindClassMemberFunction("getImageTextureWidth", &UIWidget::getImageTextureWidth); - g_lua.bindClassMemberFunction("getImageTextureHeight", &UIWidget::getImageTextureHeight); - g_lua.bindClassMemberFunction("resizeToText", &UIWidget::resizeToText); - g_lua.bindClassMemberFunction("clearText", &UIWidget::clearText); - g_lua.bindClassMemberFunction("setText", &UIWidget::setText); - g_lua.bindClassMemberFunction("setColoredText", &UIWidget::setColoredText); - g_lua.bindClassMemberFunction("setTextAlign", &UIWidget::setTextAlign); - g_lua.bindClassMemberFunction("setTextOffset", &UIWidget::setTextOffset); - g_lua.bindClassMemberFunction("setTextWrap", &UIWidget::setTextWrap); - g_lua.bindClassMemberFunction("setTextAutoResize", &UIWidget::setTextAutoResize); - g_lua.bindClassMemberFunction("setTextVerticalAutoResize", &UIWidget::setTextVerticalAutoResize); - g_lua.bindClassMemberFunction("setTextHorizontalAutoResize", &UIWidget::setTextHorizontalAutoResize); - g_lua.bindClassMemberFunction("setFont", &UIWidget::setFont); - g_lua.bindClassMemberFunction("getText", &UIWidget::getText); - g_lua.bindClassMemberFunction("getDrawText", &UIWidget::getDrawText); - g_lua.bindClassMemberFunction("getTextAlign", &UIWidget::getTextAlign); - g_lua.bindClassMemberFunction("getTextOffset", &UIWidget::getTextOffset); - g_lua.bindClassMemberFunction("getTextWrap", &UIWidget::getTextWrap); - g_lua.bindClassMemberFunction("getFont", &UIWidget::getFont); - g_lua.bindClassMemberFunction("getTextSize", &UIWidget::getTextSize); - g_lua.bindClassMemberFunction("getUseCount", &UIWidget::getUseCount); - - // UILayout - g_lua.registerClass(); - g_lua.bindClassMemberFunction("update", &UILayout::update); - g_lua.bindClassMemberFunction("updateLater", &UILayout::updateLater); - g_lua.bindClassMemberFunction("applyStyle", &UILayout::applyStyle); - g_lua.bindClassMemberFunction("addWidget", &UILayout::addWidget); - g_lua.bindClassMemberFunction("removeWidget", &UILayout::removeWidget); - g_lua.bindClassMemberFunction("disableUpdates", &UILayout::disableUpdates); - g_lua.bindClassMemberFunction("enableUpdates", &UILayout::enableUpdates); - g_lua.bindClassMemberFunction("setParent", &UILayout::setParent); - g_lua.bindClassMemberFunction("getParentWidget", &UILayout::getParentWidget); - g_lua.bindClassMemberFunction("isUpdateDisabled", &UILayout::isUpdateDisabled); - g_lua.bindClassMemberFunction("isUpdating", &UILayout::isUpdating); - g_lua.bindClassMemberFunction("isUIAnchorLayout", &UILayout::isUIAnchorLayout); - g_lua.bindClassMemberFunction("isUIBoxLayout", &UILayout::isUIBoxLayout); - g_lua.bindClassMemberFunction("isUIHorizontalLayout", &UILayout::isUIHorizontalLayout); - g_lua.bindClassMemberFunction("isUIVerticalLayout", &UILayout::isUIVerticalLayout); - g_lua.bindClassMemberFunction("isUIGridLayout", &UILayout::isUIGridLayout); - - // UIBoxLayout - g_lua.registerClass(); - g_lua.bindClassMemberFunction("setSpacing", &UIBoxLayout::setSpacing); - g_lua.bindClassMemberFunction("setFitChildren", &UIBoxLayout::setFitChildren); - - // UIVerticalLayout - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", [](UIWidgetPtr parent){ return UIVerticalLayoutPtr(new UIVerticalLayout(parent)); } ); - g_lua.bindClassMemberFunction("setAlignBottom", &UIVerticalLayout::setAlignBottom); - g_lua.bindClassMemberFunction("isAlignBottom", &UIVerticalLayout::isAlignBottom); - - // UIHorizontalLayout - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", [](UIWidgetPtr parent){ return UIHorizontalLayoutPtr(new UIHorizontalLayout(parent)); } ); - g_lua.bindClassMemberFunction("setAlignRight", &UIHorizontalLayout::setAlignRight); - - // UIGridLayout - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", [](UIWidgetPtr parent){ return UIGridLayoutPtr(new UIGridLayout(parent)); }); - g_lua.bindClassMemberFunction("setCellSize", &UIGridLayout::setCellSize); - g_lua.bindClassMemberFunction("setCellWidth", &UIGridLayout::setCellWidth); - g_lua.bindClassMemberFunction("setCellHeight", &UIGridLayout::setCellHeight); - g_lua.bindClassMemberFunction("setCellSpacing", &UIGridLayout::setCellSpacing); - g_lua.bindClassMemberFunction("setFlow", &UIGridLayout::setFlow); - g_lua.bindClassMemberFunction("setNumColumns", &UIGridLayout::setNumColumns); - g_lua.bindClassMemberFunction("setNumLines", &UIGridLayout::setNumLines); - g_lua.bindClassMemberFunction("getNumColumns", &UIGridLayout::getNumColumns); - g_lua.bindClassMemberFunction("getNumLines", &UIGridLayout::getNumLines); - g_lua.bindClassMemberFunction("getCellSize", &UIGridLayout::getCellSize); - g_lua.bindClassMemberFunction("getCellSpacing", &UIGridLayout::getCellSpacing); - g_lua.bindClassMemberFunction("isUIGridLayout", &UIGridLayout::isUIGridLayout); - - // UIAnchorLayout - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", [](UIWidgetPtr parent){ return UIAnchorLayoutPtr(new UIAnchorLayout(parent)); } ); - g_lua.bindClassMemberFunction("removeAnchors", &UIAnchorLayout::removeAnchors); - g_lua.bindClassMemberFunction("centerIn", &UIAnchorLayout::centerIn); - g_lua.bindClassMemberFunction("fill", &UIAnchorLayout::fill); - - // UITextEdit - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return UITextEditPtr(new UITextEdit); } ); - g_lua.bindClassMemberFunction("setCursorPos", &UITextEdit::setCursorPos); - g_lua.bindClassMemberFunction("setSelection", &UITextEdit::setSelection); - g_lua.bindClassMemberFunction("setCursorVisible", &UITextEdit::setCursorVisible); - g_lua.bindClassMemberFunction("setChangeCursorImage", &UITextEdit::setChangeCursorImage); - g_lua.bindClassMemberFunction("setTextHidden", &UITextEdit::setTextHidden); - g_lua.bindClassMemberFunction("setValidCharacters", &UITextEdit::setValidCharacters); - g_lua.bindClassMemberFunction("setShiftNavigation", &UITextEdit::setShiftNavigation); - g_lua.bindClassMemberFunction("setMultiline", &UITextEdit::setMultiline); - g_lua.bindClassMemberFunction("setEditable", &UITextEdit::setEditable); - g_lua.bindClassMemberFunction("setSelectable", &UITextEdit::setSelectable); - g_lua.bindClassMemberFunction("setSelectionColor", &UITextEdit::setSelectionColor); - g_lua.bindClassMemberFunction("setSelectionBackgroundColor", &UITextEdit::setSelectionBackgroundColor); - g_lua.bindClassMemberFunction("setMaxLength", &UITextEdit::setMaxLength); - g_lua.bindClassMemberFunction("setTextVirtualOffset", &UITextEdit::setTextVirtualOffset); - g_lua.bindClassMemberFunction("getTextVirtualOffset", &UITextEdit::getTextVirtualOffset); - g_lua.bindClassMemberFunction("getTextVirtualSize", &UITextEdit::getTextVirtualSize); - g_lua.bindClassMemberFunction("getTextTotalSize", &UITextEdit::getTextTotalSize); - g_lua.bindClassMemberFunction("moveCursorHorizontally", &UITextEdit::moveCursorHorizontally); - g_lua.bindClassMemberFunction("moveCursorVertically", &UITextEdit::moveCursorVertically); - g_lua.bindClassMemberFunction("appendText", &UITextEdit::appendText); - g_lua.bindClassMemberFunction("wrapText", &UITextEdit::wrapText); - g_lua.bindClassMemberFunction("removeCharacter", &UITextEdit::removeCharacter); - g_lua.bindClassMemberFunction("blinkCursor", &UITextEdit::blinkCursor); - g_lua.bindClassMemberFunction("del", &UITextEdit::del); - g_lua.bindClassMemberFunction("paste", &UITextEdit::paste); - g_lua.bindClassMemberFunction("copy", &UITextEdit::copy); - g_lua.bindClassMemberFunction("cut", &UITextEdit::cut); - g_lua.bindClassMemberFunction("selectAll", &UITextEdit::selectAll); - g_lua.bindClassMemberFunction("clearSelection", &UITextEdit::clearSelection); - g_lua.bindClassMemberFunction("getDisplayedText", &UITextEdit::getDisplayedText); - g_lua.bindClassMemberFunction("getSelection", &UITextEdit::getSelection); - g_lua.bindClassMemberFunction("getTextPos", &UITextEdit::getTextPos); - g_lua.bindClassMemberFunction("getCursorPos", &UITextEdit::getCursorPos); - g_lua.bindClassMemberFunction("getMaxLength", &UITextEdit::getMaxLength); - g_lua.bindClassMemberFunction("getSelectionStart", &UITextEdit::getSelectionStart); - g_lua.bindClassMemberFunction("getSelectionEnd", &UITextEdit::getSelectionEnd); - g_lua.bindClassMemberFunction("getSelectionColor", &UITextEdit::getSelectionColor); - g_lua.bindClassMemberFunction("getSelectionBackgroundColor", &UITextEdit::getSelectionBackgroundColor); - g_lua.bindClassMemberFunction("hasSelection", &UITextEdit::hasSelection); - g_lua.bindClassMemberFunction("isEditable", &UITextEdit::isEditable); - g_lua.bindClassMemberFunction("isSelectable", &UITextEdit::isSelectable); - g_lua.bindClassMemberFunction("isCursorVisible", &UITextEdit::isCursorVisible); - g_lua.bindClassMemberFunction("isChangingCursorImage", &UITextEdit::isChangingCursorImage); - g_lua.bindClassMemberFunction("isTextHidden", &UITextEdit::isTextHidden); - g_lua.bindClassMemberFunction("isShiftNavigation", &UITextEdit::isShiftNavigation); - g_lua.bindClassMemberFunction("isMultiline", &UITextEdit::isMultiline); - - g_lua.registerClass(); - g_lua.registerClass(); - g_lua.bindClassMemberFunction("addMultiTexture", &PainterShaderProgram::addMultiTexture); -#endif - -#ifdef FW_NET - // Server - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", &Server::create); - g_lua.bindClassMemberFunction("close", &Server::close); - g_lua.bindClassMemberFunction("isOpen", &Server::isOpen); - g_lua.bindClassMemberFunction("acceptNext", &Server::acceptNext); - - // Connection - g_lua.registerClass(); - g_lua.bindClassMemberFunction("getIp", &Connection::getIp); - - // Protocol - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return ProtocolPtr(new Protocol); }); - g_lua.bindClassMemberFunction("connect", &Protocol::connect); - g_lua.bindClassMemberFunction("disconnect", &Protocol::disconnect); - g_lua.bindClassMemberFunction("isConnected", &Protocol::isConnected); - g_lua.bindClassMemberFunction("isConnecting", &Protocol::isConnecting); - g_lua.bindClassMemberFunction("getConnection", &Protocol::getConnection); - g_lua.bindClassMemberFunction("setConnection", &Protocol::setConnection); - g_lua.bindClassMemberFunction("send", &Protocol::send); - g_lua.bindClassMemberFunction("recv", &Protocol::recv); - g_lua.bindClassMemberFunction("setXteaKey", &Protocol::setXteaKey); - g_lua.bindClassMemberFunction("getXteaKey", &Protocol::getXteaKey); - g_lua.bindClassMemberFunction("generateXteaKey", &Protocol::generateXteaKey); - g_lua.bindClassMemberFunction("enableXteaEncryption", &Protocol::enableXteaEncryption); - g_lua.bindClassMemberFunction("enableChecksum", &Protocol::enableChecksum); - g_lua.bindClassMemberFunction("enableBigPackets", &Protocol::enableBigPackets); - - // InputMessage - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return InputMessagePtr(new InputMessage); }); - g_lua.bindClassMemberFunction("setBuffer", &InputMessage::setBuffer); - g_lua.bindClassMemberFunction("getBuffer", &InputMessage::getBuffer); - g_lua.bindClassMemberFunction("skipBytes", &InputMessage::skipBytes); - g_lua.bindClassMemberFunction("getU8", &InputMessage::getU8); - g_lua.bindClassMemberFunction("getU16", &InputMessage::getU16); - g_lua.bindClassMemberFunction("getU32", &InputMessage::getU32); - g_lua.bindClassMemberFunction("getU64", &InputMessage::getU64); - g_lua.bindClassMemberFunction("getString", &InputMessage::getString); - g_lua.bindClassMemberFunction("peekU8", &InputMessage::peekU8); - g_lua.bindClassMemberFunction("peekU16", &InputMessage::peekU16); - g_lua.bindClassMemberFunction("peekU32", &InputMessage::peekU32); - g_lua.bindClassMemberFunction("peekU64", &InputMessage::peekU64); - g_lua.bindClassMemberFunction("decryptRsa", &InputMessage::decryptRsa); - g_lua.bindClassMemberFunction("getReadSize", &InputMessage::getReadSize); - g_lua.bindClassMemberFunction("getUnreadSize", &InputMessage::getUnreadSize); - g_lua.bindClassMemberFunction("getMessageSize", &InputMessage::getMessageSize); - g_lua.bindClassMemberFunction("eof", &InputMessage::eof); - - // OutputMessage - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return OutputMessagePtr(new OutputMessage); }); - g_lua.bindClassMemberFunction("setBuffer", &OutputMessage::setBuffer); - g_lua.bindClassMemberFunction("getBuffer", &OutputMessage::getBuffer); - g_lua.bindClassMemberFunction("reset", &OutputMessage::reset); - g_lua.bindClassMemberFunction("addU8", &OutputMessage::addU8); - g_lua.bindClassMemberFunction("addU16", &OutputMessage::addU16); - g_lua.bindClassMemberFunction("addU32", &OutputMessage::addU32); - g_lua.bindClassMemberFunction("addU64", &OutputMessage::addU64); - g_lua.bindClassMemberFunction("addString", &OutputMessage::addString); - g_lua.bindClassMemberFunction("addPaddingBytes", &OutputMessage::addPaddingBytes); - g_lua.bindClassMemberFunction("encryptRsa", &OutputMessage::encryptRsa); - g_lua.bindClassMemberFunction("getMessageSize", &OutputMessage::getMessageSize); - g_lua.bindClassMemberFunction("setMessageSize", &OutputMessage::setMessageSize); - g_lua.bindClassMemberFunction("getWritePos", &OutputMessage::getWritePos); - g_lua.bindClassMemberFunction("setWritePos", &OutputMessage::setWritePos); - -#ifdef FW_PROXY - g_lua.registerSingletonClass("g_proxy"); - g_lua.bindSingletonFunction("g_proxy", "addProxy", &ProxyManager::addProxy, &g_proxy); - g_lua.bindSingletonFunction("g_proxy", "removeProxy", &ProxyManager::removeProxy, &g_proxy); - g_lua.bindSingletonFunction("g_proxy", "clear", &ProxyManager::clear, &g_proxy); - g_lua.bindSingletonFunction("g_proxy", "setMaxActiveProxies", &ProxyManager::setMaxActiveProxies, &g_proxy); - g_lua.bindSingletonFunction("g_proxy", "getProxies", &ProxyManager::getProxies, &g_proxy); - g_lua.bindSingletonFunction("g_proxy", "getProxiesDebugInfo", &ProxyManager::getProxiesDebugInfo, &g_proxy); - g_lua.bindSingletonFunction("g_proxy", "getPing", &ProxyManager::getPing, &g_proxy); -#endif - -#endif - -#ifdef FW_SOUND - // SoundManager - g_lua.registerSingletonClass("g_sounds"); - g_lua.bindSingletonFunction("g_sounds", "preload", &SoundManager::preload, &g_sounds); - g_lua.bindSingletonFunction("g_sounds", "play", &SoundManager::play, &g_sounds); - g_lua.bindSingletonFunction("g_sounds", "getChannel", &SoundManager::getChannel, &g_sounds); - g_lua.bindSingletonFunction("g_sounds", "stopAll", &SoundManager::stopAll, &g_sounds); - g_lua.bindSingletonFunction("g_sounds", "enableAudio", &SoundManager::enableAudio, &g_sounds); - g_lua.bindSingletonFunction("g_sounds", "disableAudio", &SoundManager::disableAudio, &g_sounds); - g_lua.bindSingletonFunction("g_sounds", "setAudioEnabled", &SoundManager::setAudioEnabled, &g_sounds); - g_lua.bindSingletonFunction("g_sounds", "isAudioEnabled", &SoundManager::isAudioEnabled, &g_sounds); - - g_lua.registerClass(); - g_lua.registerClass(); - g_lua.registerClass(); - - g_lua.registerClass(); - g_lua.bindClassMemberFunction("play", &SoundChannel::play); - g_lua.bindClassMemberFunction("stop", &SoundChannel::stop); - g_lua.bindClassMemberFunction("enqueue", &SoundChannel::enqueue); - g_lua.bindClassMemberFunction("enable", &SoundChannel::enable); - g_lua.bindClassMemberFunction("disable", &SoundChannel::disable); - g_lua.bindClassMemberFunction("setGain", &SoundChannel::setGain); - g_lua.bindClassMemberFunction("getGain", &SoundChannel::getGain); - g_lua.bindClassMemberFunction("setEnabled", &SoundChannel::setEnabled); - g_lua.bindClassMemberFunction("isEnabled", &SoundChannel::isEnabled); - g_lua.bindClassMemberFunction("getId", &SoundChannel::getId); -#endif - -#ifdef FW_SQL - // Database - g_lua.registerClass(); - g_lua.bindClassMemberFunction("getDatabaseEngine", &Database::getDatabaseEngine); - g_lua.bindClassMemberFunction("isConnected", &Database::isConnected); - g_lua.bindClassMemberFunction("getStringComparer", &Database::getStringComparer); - g_lua.bindClassMemberFunction("getUpdateLimiter", &Database::getUpdateLimiter); - g_lua.bindClassMemberFunction("getLastInsertedRowID", &Database::getLastInsertedRowID); - g_lua.bindClassMemberFunction("escapeString", &Database::escapeString); - //g_lua.bindClassMemberFunction("escapeBlob", &Database::escapeBlob); // need to write a cast for this type to work (if needed) - - // DBQuery - /* (not sure if this class will work as a luafunction) - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return DBQuery(); }); - g_lua.bindClassMemberFunction("append", &DBQuery::append); - g_lua.bindClassMemberFunction("set", &DBQuery::set); - */ - - // DBResult - g_lua.registerClass(); - g_lua.bindClassMemberFunction("getDataInt", &DBResult::getDataInt); - g_lua.bindClassMemberFunction("getDataLong", &DBResult::getDataLong); - g_lua.bindClassMemberFunction("getDataString", &DBResult::getDataString); - //g_lua.bindClassMemberFunction("getDataStream", &DBResult::getDataStream); // need to write a cast for this type to work (if needed) - g_lua.bindClassMemberFunction("getRowCount", &DBResult::getRowCount); - g_lua.bindClassMemberFunction("free", &DBResult::free); - g_lua.bindClassMemberFunction("next", &DBResult::next); - - // MySQL - g_lua.registerClass(); - g_lua.bindClassStaticFunction("create", []{ return DatabaseMySQLPtr(new DatabaseMySQL); }); - g_lua.bindClassMemberFunction("connect", &DatabaseMySQL::connect); - g_lua.bindClassMemberFunction("beginTransaction", &DatabaseMySQL::beginTransaction); - g_lua.bindClassMemberFunction("rollback", &DatabaseMySQL::rollback); - g_lua.bindClassMemberFunction("commit", &DatabaseMySQL::commit); - g_lua.bindClassMemberFunction("executeQuery", &DatabaseMySQL::executeQuery); - g_lua.bindClassMemberFunction("storeQuery", &DatabaseMySQL::storeQuery); - - // MySQLResult - g_lua.registerClass(); - g_lua.bindClassMemberFunction("getDataInt", &MySQLResult::getDataInt); - g_lua.bindClassMemberFunction("getDataLong", &MySQLResult::getDataLong); - g_lua.bindClassMemberFunction("getDataString", &MySQLResult::getDataString); - //g_lua.bindClassMemberFunction("getDataStream", &MySQLResult::getDataStream); // need to write a cast for this type to work (if needed) - g_lua.bindClassMemberFunction("getRowCount", &MySQLResult::getRowCount); - g_lua.bindClassMemberFunction("free", &MySQLResult::free); - g_lua.bindClassMemberFunction("next", &MySQLResult::next); -#endif -} diff --git a/src/framework/net/connection.cpp b/src/framework/net/connection.cpp deleted file mode 100644 index 9657a51..0000000 --- a/src/framework/net/connection.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "connection.h" - -#include -#include -#include -#include -#include -#include - -asio::io_service g_ioService; -std::list> Connection::m_outputStreams; - -Connection::Connection() : - m_readTimer(g_ioService), - m_writeTimer(g_ioService), - m_delayedWriteTimer(g_ioService), - m_resolver(g_ioService), - m_socket(g_ioService) -{ - m_connected = false; - m_connecting = false; -} - -Connection::~Connection() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); -#endif - close(); -} - -void Connection::poll() -{ - AutoStat s(STATS_MAIN, "PollConnection"); - // reset must always be called prior to poll - g_ioService.reset(); - g_ioService.poll(); -} - -void Connection::terminate() -{ - g_ioService.stop(); - m_outputStreams.clear(); -} - -void Connection::close() -{ - if(!m_connected && !m_connecting) - return; - - // flush send data before disconnecting on clean connections - if(m_connected && !m_error && m_outputStream) - internal_write(); - - m_connecting = false; - m_connected = false; - m_connectCallback = nullptr; - m_errorCallback = nullptr; - m_recvCallback = nullptr; - - m_resolver.cancel(); - m_readTimer.cancel(); - m_writeTimer.cancel(); - m_delayedWriteTimer.cancel(); - - if(m_socket.is_open()) { - boost::system::error_code ec; - m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); - m_socket.close(); - } -} - -void Connection::connect(const std::string& host, uint16 port, const std::function& connectCallback) -{ - m_connected = false; - m_connecting = true; - m_error.clear(); - m_connectCallback = connectCallback; - - asio::ip::tcp::resolver::query query(host, stdext::unsafe_cast(port)); - m_resolver.async_resolve(query, std::bind(&Connection::onResolve, asConnection(), std::placeholders::_1, std::placeholders::_2)); - - m_readTimer.cancel(); - m_readTimer.expires_from_now(std::chrono::seconds(READ_TIMEOUT)); - m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1)); -} - -void Connection::internal_connect(asio::ip::basic_resolver::iterator endpointIterator) -{ - m_socket.async_connect(*endpointIterator, std::bind(&Connection::onConnect, asConnection(), std::placeholders::_1)); - - m_readTimer.cancel(); - m_readTimer.expires_from_now(std::chrono::seconds(READ_TIMEOUT)); - m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1)); -} - -void Connection::write(uint8* buffer, size_t size) -{ - if(!m_connected) - return; - - // we can't send the data right away, otherwise we could create tcp congestion - if(!m_outputStream) { - if(!m_outputStreams.empty()) { - m_outputStream = m_outputStreams.front(); - m_outputStreams.pop_front(); - } else - m_outputStream = std::shared_ptr(new asio::streambuf); - - m_delayedWriteTimer.cancel(); - m_delayedWriteTimer.expires_from_now(std::chrono::milliseconds(0)); - m_delayedWriteTimer.async_wait(std::bind(&Connection::onCanWrite, asConnection(), std::placeholders::_1)); - } - - std::ostream os(m_outputStream.get()); - os.write((const char*)buffer, size); - os.flush(); -} - -void Connection::internal_write() -{ - if(!m_connected) - return; - - std::shared_ptr outputStream = m_outputStream; - m_outputStream = nullptr; - - asio::async_write(m_socket, - *outputStream, - std::bind(&Connection::onWrite, asConnection(), std::placeholders::_1, std::placeholders::_2, outputStream)); - - m_writeTimer.cancel(); - m_writeTimer.expires_from_now(std::chrono::seconds(WRITE_TIMEOUT)); - m_writeTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1)); -} - -void Connection::read(uint32 bytes, const RecvCallback& callback) -{ - if(!m_connected) - return; - - m_recvCallback = callback; - - asio::async_read(m_socket, - asio::buffer(m_inputStream.prepare(bytes)), - std::bind(&Connection::onRecv, asConnection(), std::placeholders::_1, std::placeholders::_2)); - - m_readTimer.cancel(); - m_readTimer.expires_from_now(std::chrono::seconds(READ_TIMEOUT)); - m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1)); -} - -void Connection::read_until(const std::string& what, const RecvCallback& callback) -{ - if(!m_connected) - return; - - m_recvCallback = callback; - - asio::async_read_until(m_socket, - m_inputStream, - what.c_str(), - std::bind(&Connection::onRecv, asConnection(), std::placeholders::_1, std::placeholders::_2)); - - m_readTimer.cancel(); - m_readTimer.expires_from_now(std::chrono::seconds(READ_TIMEOUT)); - m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1)); -} - -void Connection::read_some(const RecvCallback& callback) -{ - if(!m_connected) - return; - - m_recvCallback = callback; - - m_socket.async_read_some(asio::buffer(m_inputStream.prepare(RECV_BUFFER_SIZE)), - std::bind(&Connection::onRecv, asConnection(), std::placeholders::_1, std::placeholders::_2)); - - m_readTimer.cancel(); - m_readTimer.expires_from_now(std::chrono::seconds(READ_TIMEOUT)); - m_readTimer.async_wait(std::bind(&Connection::onTimeout, asConnection(), std::placeholders::_1)); -} - -void Connection::onResolve(const boost::system::error_code& error, asio::ip::basic_resolver::iterator endpointIterator) -{ - m_readTimer.cancel(); - - if(error == asio::error::operation_aborted) - return; - - if(!error) - internal_connect(endpointIterator); - else - handleError(error); -} - -void Connection::onConnect(const boost::system::error_code& error) -{ - m_readTimer.cancel(); - m_activityTimer.restart(); - - if(error == asio::error::operation_aborted) - return; - - if(!error) { - m_connected = true; - - // disable nagle's algorithm, this make the game play smoother - boost::asio::ip::tcp::no_delay option(true); - m_socket.set_option(option); - boost::system::error_code ecc; - m_socket.set_option(boost::asio::socket_base::send_buffer_size(524288), ecc); - m_socket.set_option(boost::asio::socket_base::receive_buffer_size(524288), ecc); - - if(m_connectCallback) - m_connectCallback(); - } else - handleError(error); - - m_connecting = false; -} - -void Connection::onCanWrite(const boost::system::error_code& error) -{ - m_delayedWriteTimer.cancel(); - - if(error == asio::error::operation_aborted) - return; - - if(m_connected) - internal_write(); -} - -void Connection::onWrite(const boost::system::error_code& error, size_t writeSize, std::shared_ptr outputStream) -{ - m_writeTimer.cancel(); - - if(error == asio::error::operation_aborted) - return; - - // free output stream and store for using it again later - outputStream->consume(outputStream->size()); - m_outputStreams.push_back(outputStream); - - if(m_connected && error) - handleError(error); -} - -void Connection::onRecv(const boost::system::error_code& error, size_t recvSize) -{ - m_readTimer.cancel(); - m_activityTimer.restart(); - - if(error == asio::error::operation_aborted) - return; - - if(m_connected) { - if(!error) { - if(m_recvCallback) { - const char* header = boost::asio::buffer_cast(m_inputStream.data()); - m_recvCallback((uint8*)header, recvSize); - } - } else - handleError(error); - } - - if(!error) - m_inputStream.consume(recvSize); -} - -void Connection::onTimeout(const boost::system::error_code& error) -{ - if(error == asio::error::operation_aborted) - return; - - handleError(asio::error::timed_out); -} - -void Connection::handleError(const boost::system::error_code& error) -{ - if(error == asio::error::operation_aborted) - return; - - m_error = error; - if(m_errorCallback) - m_errorCallback(error); - if(m_connected || m_connecting) - close(); -} - -int Connection::getIp() -{ - boost::system::error_code error; - const boost::asio::ip::tcp::endpoint ip = m_socket.remote_endpoint(error); - if(!error) - return boost::asio::detail::socket_ops::host_to_network_long(ip.address().to_v4().to_ulong()); - - g_logger.error("Getting remote ip"); - return 0; -} diff --git a/src/framework/net/connection.h b/src/framework/net/connection.h deleted file mode 100644 index 37f6268..0000000 --- a/src/framework/net/connection.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CONNECTION_H -#define CONNECTION_H - -#include "declarations.h" -#include -#include -#include - -class Connection : public LuaObject -{ - typedef std::function ErrorCallback; - typedef std::function RecvCallback; - - static constexpr int32_t READ_TIMEOUT = 30; - static constexpr int32_t WRITE_TIMEOUT = 30; - - enum { - SEND_BUFFER_SIZE = 327680, - RECV_BUFFER_SIZE = 327680 - }; - -public: - Connection(); - ~Connection(); - - static void poll(); - static void terminate(); - - void connect(const std::string& host, uint16 port, const std::function& connectCallback); - void close(); - - void write(uint8* buffer, size_t size); - void read(uint32 bytes, const RecvCallback& callback); - void read_until(const std::string& what, const RecvCallback& callback); - void read_some(const RecvCallback& callback); - - void setErrorCallback(const ErrorCallback& errorCallback) { m_errorCallback = errorCallback; } - - int getIp(); - boost::system::error_code getError() { return m_error; } - bool isConnecting() { return m_connecting; } - bool isConnected() { return m_connected; } - ticks_t getElapsedTicksSinceLastRead() { return m_connected ? m_activityTimer.elapsed_millis() : -1; } - - ConnectionPtr asConnection() { return static_self_cast(); } - -protected: - void internal_connect(asio::ip::basic_resolver::iterator endpointIterator); - void internal_write(); - void onResolve(const boost::system::error_code& error, asio::ip::tcp::resolver::iterator endpointIterator); - void onConnect(const boost::system::error_code& error); - void onCanWrite(const boost::system::error_code& error); - void onWrite(const boost::system::error_code& error, size_t writeSize, std::shared_ptr outputStream); - void onRecv(const boost::system::error_code& error, size_t recvSize); - void onTimeout(const boost::system::error_code& error); - void handleError(const boost::system::error_code& error); - - std::function m_connectCallback; - ErrorCallback m_errorCallback; - RecvCallback m_recvCallback; - - asio::steady_timer m_readTimer; - asio::steady_timer m_writeTimer; - asio::steady_timer m_delayedWriteTimer; - asio::ip::tcp::resolver m_resolver; - asio::ip::tcp::socket m_socket; - - static std::list> m_outputStreams; - std::shared_ptr m_outputStream; - asio::streambuf m_inputStream; - bool m_connected; - bool m_connecting; - boost::system::error_code m_error; - stdext::timer m_activityTimer; - - friend class Server; -}; - -#endif diff --git a/src/framework/net/declarations.h b/src/framework/net/declarations.h deleted file mode 100644 index 4d9217f..0000000 --- a/src/framework/net/declarations.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FRAMEWORK_NET_DECLARATIONS_H -#define FRAMEWORK_NET_DECLARATIONS_H - -#include - -namespace asio = boost::asio; - -class InputMessage; -class OutputMessage; -class Connection; -class Protocol; -class Server; - -typedef stdext::shared_object_ptr InputMessagePtr; -typedef stdext::shared_object_ptr OutputMessagePtr; -typedef stdext::shared_object_ptr ConnectionPtr; -typedef stdext::shared_object_ptr ProtocolPtr; -typedef stdext::shared_object_ptr ServerPtr; - -#endif diff --git a/src/framework/net/inputmessage.cpp b/src/framework/net/inputmessage.cpp deleted file mode 100644 index 0033f96..0000000 --- a/src/framework/net/inputmessage.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "inputmessage.h" -#include -#include - -InputMessage::InputMessage() -{ - reset(); -} - -void InputMessage::reset() -{ - m_messageSize = 0; - m_readPos = MAX_HEADER_SIZE; - m_headerPos = MAX_HEADER_SIZE; -} - -void InputMessage::setBuffer(const std::string& buffer) -{ - int len = buffer.size(); - checkWrite(MAX_HEADER_SIZE + len); - memcpy(m_buffer + MAX_HEADER_SIZE, buffer.c_str(), len); - m_readPos = MAX_HEADER_SIZE; - m_headerPos = MAX_HEADER_SIZE; - m_messageSize = len; -} - -uint8 InputMessage::getU8() -{ - checkRead(1); - uint8 v = m_buffer[m_readPos]; - m_readPos += 1; - return v; -} - -uint16 InputMessage::getU16() -{ - checkRead(2); - uint16 v = stdext::readULE16(m_buffer + m_readPos); - m_readPos += 2; - return v; -} - -uint32 InputMessage::getU32() -{ - checkRead(4); - uint32 v = stdext::readULE32(m_buffer + m_readPos); - m_readPos += 4; - return v; -} - -uint64 InputMessage::getU64() -{ - checkRead(8); - uint64 v = stdext::readULE64(m_buffer + m_readPos); - m_readPos += 8; - return v; -} - -std::string InputMessage::getString() -{ - uint16 stringLength = getU16(); - checkRead(stringLength); - char* v = (char*)(m_buffer + m_readPos); - m_readPos += stringLength; - return std::string(v, stringLength); -} - -double InputMessage::getDouble() -{ - uint8 precision = getU8(); - int32 v = getU32() - INT_MAX; - return (v / std::pow((float)10, precision)); -} - -bool InputMessage::decryptRsa(int size) -{ - checkRead(size); - g_crypt.rsaDecrypt((unsigned char*)m_buffer + m_readPos, size); - return (getU8() == 0x00); -} - -void InputMessage::fillBuffer(uint8 *buffer, uint32 size) -{ - checkWrite(m_readPos + size); - memcpy(m_buffer + m_readPos, buffer, size); - m_messageSize += size; -} - -void InputMessage::setHeaderSize(uint32 size) -{ - VALIDATE(MAX_HEADER_SIZE >= size); - m_headerPos = MAX_HEADER_SIZE - size; - m_readPos = m_headerPos; -} - -bool InputMessage::readChecksum() -{ - uint32 receivedCheck = getU32(); - uint32 checksum = stdext::adler32(m_buffer + m_readPos, getUnreadSize()); - return receivedCheck == checksum; -} - -bool InputMessage::canRead(int bytes) -{ - if((m_readPos - m_headerPos + bytes > m_messageSize) || (m_readPos + bytes > BUFFER_MAXSIZE)) - return false; - return true; -} -void InputMessage::checkRead(int bytes) -{ - if(!canRead(bytes)) - throw stdext::exception("InputMessage eof reached"); -} - -void InputMessage::checkWrite(int bytes) -{ - if(bytes > BUFFER_MAXSIZE) - throw stdext::exception("InputMessage max buffer size reached"); -} - -void InputMessage::addZlibFooter() -{ - if (m_messageSize + 4 > BUFFER_MAXSIZE) - return; - m_buffer[m_messageSize + m_headerPos] = 0x00; - m_buffer[m_messageSize + m_headerPos + 1] = 0x00; - m_buffer[m_messageSize + m_headerPos + 2] = 0xFF; - m_buffer[m_messageSize + m_headerPos + 3] = 0xFF; - m_messageSize += 4; -} diff --git a/src/framework/net/inputmessage.h b/src/framework/net/inputmessage.h deleted file mode 100644 index 556e224..0000000 --- a/src/framework/net/inputmessage.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef INPUTMESSAGE_H -#define INPUTMESSAGE_H - -#include "declarations.h" -#include - -// @bindclass -class InputMessage : public LuaObject -{ -public: - enum { - BUFFER_MAXSIZE = 327680, - MAX_HEADER_SIZE = 12 - }; - - InputMessage(); - - void setBuffer(const std::string& buffer); - std::string getBuffer() { return std::string((char*)m_buffer + m_headerPos, m_messageSize); } - - void skipBytes(uint32 bytes) { m_readPos += bytes; } - void setReadPos(uint32 readPos) { m_readPos = readPos; } - uint8 getU8(); - uint16 getU16(); - uint32 getU32(); - uint64 getU64(); - std::string getString(); - double getDouble(); - - uint8 peekU8() { uint8 v = getU8(); m_readPos-=1; return v; } - uint16 peekU16() { uint16 v = getU16(); m_readPos-=2; return v; } - uint32 peekU32() { uint32 v = getU32(); m_readPos-=4; return v; } - uint64 peekU64() { uint64 v = getU64(); m_readPos-=8; return v; } - - bool decryptRsa(int size); - - int getReadSize() { return m_readPos - m_headerPos; } - int getReadPos() { return m_readPos; } - int getUnreadSize() { return m_messageSize - (m_readPos - m_headerPos); } - uint32 getMessageSize() { return m_messageSize; } - - bool eof() { return (m_readPos - m_headerPos) >= m_messageSize; } - -protected: - void reset(); - void fillBuffer(uint8 *buffer, uint32 size); - - void setHeaderSize(uint32 size); - void setMessageSize(uint32 size) { m_messageSize = size; } - - uint8* getReadBuffer() { return m_buffer + m_readPos; } - uint8* getHeaderBuffer() { return m_buffer + m_headerPos; } - uint8* getDataBuffer() { return m_buffer + MAX_HEADER_SIZE; } - uint32 getHeaderSize() { return (MAX_HEADER_SIZE - m_headerPos); } - - uint32 readSize(bool bigSize) { return bigSize ? getU32() : getU16(); } - bool readChecksum(); - - void addZlibFooter(); - - friend class Protocol; - -private: - bool canRead(int bytes); - void checkRead(int bytes); - void checkWrite(int bytes); - - uint32 m_headerPos; - uint32 m_readPos; - uint32 m_messageSize; - uint8 m_buffer[BUFFER_MAXSIZE]; -}; - -#endif diff --git a/src/framework/net/outputmessage.cpp b/src/framework/net/outputmessage.cpp deleted file mode 100644 index 48f5814..0000000 --- a/src/framework/net/outputmessage.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -OutputMessage::OutputMessage() -{ - reset(); -} - -void OutputMessage::reset() -{ - m_writePos = MAX_HEADER_SIZE; - m_headerPos = MAX_HEADER_SIZE; - m_messageSize = 0; -} - -void OutputMessage::setBuffer(const std::string& buffer) -{ - int len = buffer.size(); - reset(); - checkWrite(len); - memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), len); - m_writePos += len; - m_messageSize += len; -} - -void OutputMessage::addU8(uint8 value) -{ - checkWrite(1); - m_buffer[m_writePos] = value; - m_writePos += 1; - m_messageSize += 1; -} - -void OutputMessage::addU16(uint16 value) -{ - checkWrite(2); - stdext::writeULE16(m_buffer + m_writePos, value); - m_writePos += 2; - m_messageSize += 2; -} - -void OutputMessage::addU32(uint32 value) -{ - checkWrite(4); - stdext::writeULE32(m_buffer + m_writePos, value); - m_writePos += 4; - m_messageSize += 4; -} - -void OutputMessage::addU64(uint64 value) -{ - checkWrite(8); - stdext::writeULE64(m_buffer + m_writePos, value); - m_writePos += 8; - m_messageSize += 8; -} - -void OutputMessage::addString(const std::string& buffer) -{ - int len = buffer.length(); - if(len > MAX_STRING_LENGTH) - throw stdext::exception(stdext::format("string length > %d", MAX_STRING_LENGTH)); - checkWrite(len + 2); - addU16(len); - memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), len); - m_writePos += len; - m_messageSize += len; -} - -void OutputMessage::addPaddingBytes(int bytes, uint8 byte) -{ - if(bytes <= 0) - return; - checkWrite(bytes); - memset((void*)&m_buffer[m_writePos], byte, bytes); - m_writePos += bytes; - m_messageSize += bytes; -} - -void OutputMessage::encryptRsa() -{ - uint32_t size = g_crypt.rsaGetSize(); - if(m_messageSize < size) - throw stdext::exception("insufficient bytes in buffer to encrypt"); - - if(!g_crypt.rsaEncrypt((unsigned char*)m_buffer + m_writePos - size, size)) - throw stdext::exception("rsa encryption failed"); -} - -void OutputMessage::writeChecksum() -{ - uint32 checksum = stdext::adler32(m_buffer + m_headerPos, m_messageSize); - VALIDATE(m_headerPos >= 4); - m_headerPos -= 4; - stdext::writeULE32(m_buffer + m_headerPos, checksum); - m_messageSize += 4; -} - -void OutputMessage::writeMessageSize(bool bigSize) -{ - VALIDATE(m_headerPos >= (bigSize ? 4 : 2)); - m_headerPos -= (bigSize ? 4 : 2); - if (bigSize) { - stdext::writeULE32(m_buffer + m_headerPos, m_messageSize); - } else { - stdext::writeULE16(m_buffer + m_headerPos, m_messageSize); - } - m_messageSize += (bigSize ? 4 : 2); -} - -bool OutputMessage::canWrite(int bytes) -{ - if(m_writePos + bytes > BUFFER_MAXSIZE) - return false; - return true; -} - -void OutputMessage::checkWrite(int bytes) -{ - if(!canWrite(bytes)) - throw stdext::exception("OutputMessage max buffer size reached"); -} diff --git a/src/framework/net/outputmessage.h b/src/framework/net/outputmessage.h deleted file mode 100644 index 6dfa295..0000000 --- a/src/framework/net/outputmessage.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OUTPUTMESSAGE_H -#define OUTPUTMESSAGE_H - -#include "declarations.h" -#include - -// @bindclass -class OutputMessage : public LuaObject -{ -public: - enum { - BUFFER_MAXSIZE = 327680, - MAX_STRING_LENGTH = 65536, - MAX_HEADER_SIZE = 12 - }; - - OutputMessage(); - - void reset(); - - void setBuffer(const std::string& buffer); - std::string getBuffer() { return std::string((char*)m_buffer + m_headerPos, m_messageSize); } - - void addU8(uint8 value); - void addU16(uint16 value); - void addU32(uint32 value); - void addU64(uint64 value); - void addString(const std::string& buffer); - void addPaddingBytes(int bytes, uint8 byte = 0); - - void encryptRsa(); - - uint32 getWritePos() { return m_writePos; } - uint32 getMessageSize() { return m_messageSize; } - - void setWritePos(uint32 writePos) { m_writePos = writePos; } - void setMessageSize(uint32 messageSize) { m_messageSize = messageSize; } - -protected: - uint8* getWriteBuffer() { return m_buffer + m_writePos; } - uint8* getHeaderBuffer() { return m_buffer + m_headerPos; } - uint8* getDataBuffer() { return m_buffer + MAX_HEADER_SIZE; } - - void writeChecksum(); - void writeMessageSize(bool bigSize); - - friend class Protocol; - -private: - bool canWrite(int bytes); - void checkWrite(int bytes); - - uint32 m_headerPos; - uint32 m_writePos; - uint32 m_messageSize; - uint8 m_buffer[BUFFER_MAXSIZE]; -}; - -#endif diff --git a/src/framework/net/protocol.cpp b/src/framework/net/protocol.cpp deleted file mode 100644 index baadbc6..0000000 --- a/src/framework/net/protocol.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "protocol.h" -#include "connection.h" -#include -#include - -extern asio::io_service g_ioService; - -Protocol::Protocol() -{ - m_xteaEncryptionEnabled = false; - m_checksumEnabled = false; - m_bigPackets = false; - m_compression = false; - m_inputMessage = InputMessagePtr(new InputMessage); - - // compression - m_zstreamBuffer.resize(InputMessage::BUFFER_MAXSIZE); - m_zstream.next_in = m_inputMessage->getDataBuffer(); - m_zstream.next_out = m_zstreamBuffer.data(); - m_zstream.avail_in = 0; - m_zstream.avail_out = 0; - m_zstream.total_in = 0; - m_zstream.total_out = 0; - m_zstream.zalloc = nullptr; - m_zstream.zfree = nullptr; - m_zstream.opaque = nullptr; - m_zstream.data_type = Z_BINARY; - inflateInit2(&m_zstream, -15); -} - -Protocol::~Protocol() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); -#endif - disconnect(); - inflateEnd(&m_zstream); -} - -void Protocol::connect(const std::string& host, uint16 port) -{ -#ifdef FW_PROXY - if (host == "proxy" || host == "0.0.0.0" || (host == "127.0.0.1" && g_proxy.isActive())) { - m_disconnected = false; - m_proxy = g_proxy.addSession(port, - std::bind(&Protocol::onProxyPacket, asProtocol(), std::placeholders::_1), - std::bind(&Protocol::onProxyDisconnected, asProtocol(), std::placeholders::_1)); - return onConnect(); - } -#endif - m_connection = ConnectionPtr(new Connection); - m_connection->setErrorCallback(std::bind(&Protocol::onError, asProtocol(), std::placeholders::_1)); - m_connection->connect(host, port, std::bind(&Protocol::onConnect, asProtocol())); -} - -void Protocol::disconnect() -{ -#ifdef FW_PROXY - m_disconnected = true; - if (m_proxy) { - g_proxy.removeSession(m_proxy); - return; - } -#endif - if(m_connection) { - m_connection->close(); - m_connection.reset(); - } -} - -bool Protocol::isConnected() -{ -#ifdef FW_PROXY - if (m_proxy) - return !m_disconnected; -#endif - if(m_connection && m_connection->isConnected()) - return true; - return false; -} - -bool Protocol::isConnecting() -{ -#ifdef FW_PROXY - if (m_proxy) - return false; -#endif - if(m_connection && m_connection->isConnecting()) - return true; - return false; -} - -void Protocol::send(const OutputMessagePtr& outputMessage) -{ - // encrypt - if(m_xteaEncryptionEnabled) - xteaEncrypt(outputMessage); - - // write checksum - if(m_checksumEnabled) - outputMessage->writeChecksum(); - - // write message size - outputMessage->writeMessageSize(m_bigPackets); - -#ifdef FW_PROXY - if (m_proxy) { - auto packet = std::make_shared(outputMessage->getHeaderBuffer(), outputMessage->getWriteBuffer()); - g_proxy.send(m_proxy, packet); - outputMessage->reset(); - return; - } -#endif - - // send - if(m_connection) - m_connection->write(outputMessage->getHeaderBuffer(), outputMessage->getMessageSize()); - - // reset message to allow reuse - outputMessage->reset(); -} - -void Protocol::recv() -{ -#ifdef FW_PROXY - if (m_proxy) { - return; - } -#endif - m_inputMessage->reset(); - - // first update message header size - int headerSize = m_bigPackets ? 4 : 2; // 2 or 4 bytes for message size - if(m_checksumEnabled) - headerSize += 4; // 4 bytes for checksum - if(m_xteaEncryptionEnabled) - headerSize += m_bigPackets ? 4 : 2; // 2 or 4 bytes for XTEA encrypted message size - m_inputMessage->setHeaderSize(headerSize); - - // read the first 2 bytes which contain the message size - if(m_connection) - m_connection->read(m_bigPackets ? 4 : 2, std::bind(&Protocol::internalRecvHeader, asProtocol(), std::placeholders::_1, std::placeholders::_2)); -} - -void Protocol::internalRecvHeader(uint8* buffer, uint32 size) -{ - // read message size - m_inputMessage->fillBuffer(buffer, size); - uint32 remainingSize = m_inputMessage->readSize(m_bigPackets); - - // read remaining message data - if(m_connection) - m_connection->read(remainingSize, std::bind(&Protocol::internalRecvData, asProtocol(), std::placeholders::_1, std::placeholders::_2)); -} - -void Protocol::internalRecvData(uint8* buffer, uint32 size) -{ - // process data only if really connected - if(!isConnected()) { - g_logger.traceError("received data while disconnected"); - return; - } - - m_inputMessage->fillBuffer(buffer, size); - - bool decompress = false; - if(m_checksumEnabled) { - if (m_inputMessage->peekU32() == 0) { // compressed data - m_inputMessage->getU32(); - decompress = true; - } else if (!m_inputMessage->readChecksum()) { - g_logger.traceError(stdext::format("got a network message with invalid checksum, size: %i", (int)m_inputMessage->getMessageSize())); - return; - } - } - - if(m_xteaEncryptionEnabled) { - if(!xteaDecrypt(m_inputMessage)) { - g_logger.traceError("failed to decrypt message"); - return; - } - } - - if (decompress || m_compression) { - m_inputMessage->addZlibFooter(); - m_zstream.next_in = m_inputMessage->getDataBuffer(); - m_zstream.next_out = m_zstreamBuffer.data(); - m_zstream.avail_in = m_inputMessage->getUnreadSize(); - m_zstream.avail_out = m_zstreamBuffer.size(); - if (inflate(&m_zstream, Z_SYNC_FLUSH) != Z_OK) { - g_logger.traceError("failed to decompress message"); - return; - } - int decryptedSize = m_zstreamBuffer.size() - m_zstream.avail_out; - if (decryptedSize == 0) { - g_logger.traceError(stdext::format("invalid size of decompressed message - %i", (int)decryptedSize)); - return; - } - m_inputMessage->fillBuffer(m_zstreamBuffer.data(), decryptedSize); - m_inputMessage->setMessageSize(m_inputMessage->getHeaderSize() + decryptedSize); - } - onRecv(m_inputMessage); -} - -void Protocol::generateXteaKey() -{ - std::mt19937 eng(std::time(NULL)); - std::uniform_int_distribution unif(0, 0xFFFFFFFF); - m_xteaKey[0] = unif(eng); - m_xteaKey[1] = unif(eng); - m_xteaKey[2] = unif(eng); - m_xteaKey[3] = unif(eng); -} - -void Protocol::setXteaKey(uint32 a, uint32 b, uint32 c, uint32 d) -{ - m_xteaKey[0] = a; - m_xteaKey[1] = b; - m_xteaKey[2] = c; - m_xteaKey[3] = d; -} - -std::vector Protocol::getXteaKey() -{ - std::vector xteaKey; - xteaKey.resize(4); - for(int i = 0; i < 4; ++i) - xteaKey[i] = m_xteaKey[i]; - return xteaKey; -} - -bool Protocol::xteaDecrypt(const InputMessagePtr& inputMessage) -{ - uint32 encryptedSize = inputMessage->getUnreadSize(); - if(encryptedSize % 8 != 0) { - g_logger.traceError(stdext::format("invalid encrypted network message %i", (int)encryptedSize)); - return false; - } - - uint32 *buffer = (uint32*)(inputMessage->getReadBuffer()); - uint32_t readPos = 0; - - while(readPos < encryptedSize/4) { - uint32 v0 = buffer[readPos], v1 = buffer[readPos + 1]; - uint32 delta = 0x61C88647; - uint32 sum = 0xC6EF3720; - - for(int32 i = 0; i < 32; i++) { - v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + m_xteaKey[sum>>11 & 3]); - sum += delta; - v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + m_xteaKey[sum & 3]); - } - buffer[readPos] = v0; buffer[readPos + 1] = v1; - readPos = readPos + 2; - } - - uint32 decryptedSize = m_bigPackets ? (inputMessage->getU32() + 4) : (inputMessage->getU16() + 2); - int sizeDelta = decryptedSize - encryptedSize; - if(sizeDelta > 0 || -sizeDelta > (int)encryptedSize) { - g_logger.traceError("invalid decrypted network message"); - return false; - } - - inputMessage->setMessageSize(inputMessage->getMessageSize() + sizeDelta); - return true; -} - -void Protocol::xteaEncrypt(const OutputMessagePtr& outputMessage) -{ - outputMessage->writeMessageSize(m_bigPackets); - uint32 encryptedSize = outputMessage->getMessageSize(); - - //add bytes until reach 8 multiple - if((encryptedSize % 8) != 0) { - uint32 n = 8 - (encryptedSize % 8); - outputMessage->addPaddingBytes(n); - encryptedSize += n; - } - - uint32_t readPos = 0; - uint32 *buffer = (uint32*)(outputMessage->getDataBuffer() - (m_bigPackets ? 4 : 2)); - while(readPos < encryptedSize / 4) { - uint32 v0 = buffer[readPos], v1 = buffer[readPos + 1]; - uint32 delta = 0x61C88647; - uint32 sum = 0; - - for(int32 i = 0; i < 32; i++) { - v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + m_xteaKey[sum & 3]); - sum -= delta; - v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + m_xteaKey[sum>>11 & 3]); - } - buffer[readPos] = v0; buffer[readPos + 1] = v1; - readPos = readPos + 2; - } -} - -void Protocol::onConnect() -{ - callLuaField("onConnect"); -} - -void Protocol::onRecv(const InputMessagePtr& inputMessage) -{ - callLuaField("onRecv", inputMessage); -} - -void Protocol::onError(const boost::system::error_code& err) -{ - callLuaField("onError", err.message(), err.value()); - disconnect(); -} - -#ifdef FW_PROXY -void Protocol::onProxyPacket(ProxyPacketPtr packet) -{ - if (m_disconnected) - return; - auto self(asProtocol()); - boost::asio::post(g_ioService, [&, self, packet] - { - if (m_disconnected) - return; - m_inputMessage->reset(); - - // first update message header size - int headerSize = m_bigPackets ? 4 : 2; // 2 bytes for message size - if (m_checksumEnabled) - headerSize += 4; // 4 bytes for checksum - if (m_xteaEncryptionEnabled) - headerSize += m_bigPackets ? 4 : 2; // 2 bytes for XTEA encrypted message size - m_inputMessage->setHeaderSize(headerSize); - m_inputMessage->fillBuffer(packet->data(), m_bigPackets ? 4 : 2); - m_inputMessage->readSize(m_bigPackets); - internalRecvData(packet->data() + (m_bigPackets ? 4 : 2), packet->size() - (m_bigPackets ? 4 : 2)); - }); -} - -void Protocol::onProxyDisconnected(boost::system::error_code ec) -{ - if (m_disconnected) - return; - auto self(asProtocol()); - boost::asio::post(g_ioService, [&, self, ec] { - if (m_disconnected) - return; - m_disconnected = true; - onError(ec); - }); -} -#endif \ No newline at end of file diff --git a/src/framework/net/protocol.h b/src/framework/net/protocol.h deleted file mode 100644 index 6bfb6b1..0000000 --- a/src/framework/net/protocol.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PROTOCOL_H -#define PROTOCOL_H - -#include "declarations.h" -#include "inputmessage.h" -#include "outputmessage.h" -#include "connection.h" - -#include - -#ifdef FW_PROXY -#include -#endif - -#include - -// @bindclass -class Protocol : public LuaObject -{ -public: - Protocol(); - virtual ~Protocol(); - - void connect(const std::string& host, uint16 port); - void disconnect(); - - bool isConnected(); - bool isConnecting(); - ticks_t getElapsedTicksSinceLastRead() { return m_connection ? m_connection->getElapsedTicksSinceLastRead() : -1; } - - ConnectionPtr getConnection() { return m_connection; } - void setConnection(const ConnectionPtr& connection) { m_connection = connection; } - - void generateXteaKey(); - void setXteaKey(uint32 a, uint32 b, uint32 c, uint32 d); - std::vector getXteaKey(); - void enableXteaEncryption() { m_xteaEncryptionEnabled = true; } - - void enableChecksum() { m_checksumEnabled = true; } - void enableBigPackets() { m_bigPackets = true; } - void enableCompression() { m_compression = true; } - - virtual void send(const OutputMessagePtr& outputMessage); - virtual void recv(); - - ProtocolPtr asProtocol() { return static_self_cast(); } - -protected: - virtual void onConnect(); - virtual void onRecv(const InputMessagePtr& inputMessage); - virtual void onError(const boost::system::error_code& err); - -#ifdef FW_PROXY - void onProxyPacket(ProxyPacketPtr packet); - void onProxyDisconnected(boost::system::error_code ec); - uint32_t m_proxy = 0; - bool m_disconnected = false; -#endif - - uint32 m_xteaKey[4]; - -private: - void internalRecvHeader(uint8* buffer, uint32 size); - void internalRecvData(uint8* buffer, uint32 size); - - bool xteaDecrypt(const InputMessagePtr& inputMessage); - void xteaEncrypt(const OutputMessagePtr& outputMessage); - - bool m_checksumEnabled; - bool m_xteaEncryptionEnabled; - bool m_bigPackets; - bool m_compression; - ConnectionPtr m_connection; - InputMessagePtr m_inputMessage; - z_stream m_zstream; - std::vector m_zstreamBuffer; -}; - -#endif diff --git a/src/framework/net/server.cpp b/src/framework/net/server.cpp deleted file mode 100644 index 19c81e7..0000000 --- a/src/framework/net/server.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "server.h" -#include "connection.h" - -extern asio::io_service g_ioService; - -Server::Server(int port) - : m_acceptor(g_ioService, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)) -{ -} - -ServerPtr Server::create(int port) -{ - try { - Server *server = new Server(port); - return ServerPtr(server); - } - catch(const std::exception& e) { - g_logger.error(stdext::format("Failed to initialize server: %s", e.what())); - return ServerPtr(); - } -} - -void Server::close() -{ - m_isOpen = false; - m_acceptor.cancel(); - m_acceptor.close(); -} - -void Server::acceptNext() -{ - ConnectionPtr connection = ConnectionPtr(new Connection); - connection->m_connecting = true; - auto self = static_self_cast(); - m_acceptor.async_accept(connection->m_socket, [=](const boost::system::error_code& error) { - if(!error) { - connection->m_connected = true; - connection->m_connecting = false; - } - self->callLuaField("onAccept", connection, error.message(), error.value()); - }); -} diff --git a/src/framework/net/server.h b/src/framework/net/server.h deleted file mode 100644 index 7509406..0000000 --- a/src/framework/net/server.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SERVER_H -#define SERVER_H - -#include "declarations.h" -#include - -class Server : public LuaObject -{ -public: - Server(int port); - static ServerPtr create(int port); - bool isOpen() { return m_isOpen; } - void close(); - - void acceptNext(); - -private: - stdext::boolean m_isOpen; - asio::ip::tcp::acceptor m_acceptor; -}; - -#endif diff --git a/src/framework/otml/declarations.h b/src/framework/otml/declarations.h deleted file mode 100644 index 64c01af..0000000 --- a/src/framework/otml/declarations.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FRAMEWORK_OTML_DECLARATIONS_H -#define FRAMEWORK_OTML_DECLARATIONS_H - -#include - -class OTMLNode; -class OTMLDocument; -class OTMLParser; -class OTMLEmitter; - -typedef stdext::shared_object_ptr OTMLNodePtr; -typedef stdext::shared_object_ptr OTMLDocumentPtr; -typedef std::vector OTMLNodeList; - -#endif diff --git a/src/framework/otml/otml.h b/src/framework/otml/otml.h deleted file mode 100644 index 0f40752..0000000 --- a/src/framework/otml/otml.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OTML_H -#define OTML_H - -#include "otmldocument.h" -#include "otmlnode.h" - -#endif \ No newline at end of file diff --git a/src/framework/otml/otmldocument.cpp b/src/framework/otml/otmldocument.cpp deleted file mode 100644 index 070d3d2..0000000 --- a/src/framework/otml/otmldocument.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "otmldocument.h" -#include "otmlparser.h" -#include "otmlemitter.h" - -#include - -OTMLDocumentPtr OTMLDocument::create() -{ - OTMLDocumentPtr doc(new OTMLDocument); - doc->setTag("doc"); - return doc; -} - -OTMLDocumentPtr OTMLDocument::parse(const std::string& fileName) -{ - std::stringstream fin; - std::string source = g_resources.resolvePath(fileName); - g_resources.readFileStream(source, fin); - return parse(fin, source); -} - -OTMLDocumentPtr OTMLDocument::parseString(const std::string& data, const std::string& source) -{ - std::istringstream is(data); - return parse(is, source); -} - -OTMLDocumentPtr OTMLDocument::parse(std::istream& in, const std::string& source) -{ - OTMLDocumentPtr doc(new OTMLDocument); - doc->setSource(source); - OTMLParser parser(doc, in); - parser.parse(); - return doc; -} - -std::string OTMLDocument::emit() -{ - return OTMLEmitter::emitNode(asOTMLNode()) + "\n"; -} - -bool OTMLDocument::save(const std::string& fileName) -{ - m_source = fileName; - return g_resources.writeFileContents(fileName, emit()); -} - diff --git a/src/framework/otml/otmldocument.h b/src/framework/otml/otmldocument.h deleted file mode 100644 index c7d437a..0000000 --- a/src/framework/otml/otmldocument.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OTMLDOCUMENT_H -#define OTMLDOCUMENT_H - -#include "otmlnode.h" - -class OTMLDocument : public OTMLNode -{ -public: - virtual ~OTMLDocument() { } - - /// Create a new OTML document for filling it with nodes - static OTMLDocumentPtr create(); - - /// Parse OTML from a file - static OTMLDocumentPtr parse(const std::string& fileName); - - /// Parse OTML from a string - static OTMLDocumentPtr parseString(const std::string& data, const std::string& source); - - /// Parse OTML from input stream - /// @param source is the file name that will be used to show errors messages - static OTMLDocumentPtr parse(std::istream& in, const std::string& source); - - /// Emits this document and all it's children to a std::string - std::string emit(); - - /// Save this document to a file - bool save(const std::string& fileName); - -private: - OTMLDocument() { } -}; - -#endif diff --git a/src/framework/otml/otmlemitter.cpp b/src/framework/otml/otmlemitter.cpp deleted file mode 100644 index 0adf7a1..0000000 --- a/src/framework/otml/otmlemitter.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "otmlemitter.h" -#include "otmldocument.h" - -std::string OTMLEmitter::emitNode(const OTMLNodePtr& node, int currentDepth) -{ - std::stringstream ss; - - // emit nodes - if(currentDepth >= 0) { - // fill spaces for current depth - for(int i=0;ihasTag()) { - ss << node->tag(); - - // add ':' to if the node is unique or has value - if(node->hasValue() || node->isUnique() || node->isNull()) - ss << ":"; - } else - ss << "-"; - - // emit node value - if(node->isNull()) - ss << " ~"; - else if(node->hasValue()) { - ss << " "; - - std::string value = node->value(); - - // emit multiline values - if(value.find("\n") != std::string::npos) { - if(value[value.length()-1] == '\n' && value[value.length()-2] == '\n') - ss << "|+"; - else if(value[value.length()-1] == '\n') - ss << "|"; - else - ss << "|-"; - - // multilines - for(std::size_t pos = 0; pos < value.length(); ++pos) { - ss << "\n"; - - // fill spaces for multiline depth - for(int i=0;isize();++i) { - if(currentDepth >= 0 || i != 0) - ss << "\n"; - ss << emitNode(node->atIndex(i), currentDepth+1); - } - - return ss.str(); -} diff --git a/src/framework/otml/otmlemitter.h b/src/framework/otml/otmlemitter.h deleted file mode 100644 index c429834..0000000 --- a/src/framework/otml/otmlemitter.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OTMLEMITTER_H -#define OTMLEMITTER_H - -#include "declarations.h" - -class OTMLEmitter -{ -public: - /// Emits a node and it's children to a std::string - static std::string emitNode(const OTMLNodePtr& node, int currentDepth = -1); -}; - -#endif diff --git a/src/framework/otml/otmlexception.cpp b/src/framework/otml/otmlexception.cpp deleted file mode 100644 index e87e3ce..0000000 --- a/src/framework/otml/otmlexception.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "otmlexception.h" -#include "otmldocument.h" - -OTMLException::OTMLException(const OTMLNodePtr& node, const std::string& error) -{ - std::stringstream ss; - ss << "OTML error"; - if(!node->source().empty()) - ss << " in '" << node->source() << "'"; - ss << ": " << error; - m_what = ss.str(); -} - -OTMLException::OTMLException(const OTMLDocumentPtr& doc, const std::string& error, int line) -{ - std::stringstream ss; - ss << "OTML error"; - if(doc && !doc->source().empty()) { - ss << " in '" << doc->source() << "'"; - if(line >= 0) - ss << " at line " << line; - } - ss << ": " << error; - m_what = ss.str(); -} diff --git a/src/framework/otml/otmlexception.h b/src/framework/otml/otmlexception.h deleted file mode 100644 index 0b23e48..0000000 --- a/src/framework/otml/otmlexception.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OTMLEXCEPTION_H -#define OTMLEXCEPTION_H - -#include "declarations.h" - -/// All OTML errors throw this exception -class OTMLException : public stdext::exception -{ -public: - OTMLException(const OTMLNodePtr& node, const std::string& error); - OTMLException(const OTMLDocumentPtr& doc, const std::string& error, int line = -1); - virtual ~OTMLException() throw() { }; - - virtual const char* what() const throw() { return m_what.c_str(); } - -protected: - std::string m_what; -}; - -#endif diff --git a/src/framework/otml/otmlnode.cpp b/src/framework/otml/otmlnode.cpp deleted file mode 100644 index dde07d2..0000000 --- a/src/framework/otml/otmlnode.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "otmlnode.h" -#include "otmlemitter.h" -#include "otmldocument.h" - -#include - -OTMLNodePtr OTMLNode::create(std::string tag, bool unique) -{ - OTMLNodePtr node(new OTMLNode); - node->setTag(tag); - node->setUnique(unique); - return node; -} - -OTMLNodePtr OTMLNode::create(std::string tag, std::string value) -{ - OTMLNodePtr node(new OTMLNode); - node->setTag(tag); - node->setValue(value); - node->setUnique(true); - return node; -} - -bool OTMLNode::hasChildren() -{ - for(const OTMLNodePtr& child : m_children) { - if (!child->isNull()) - return true; - } - return false; -} - -OTMLNodePtr OTMLNode::get(const std::string& childTag) -{ - //if (g_extras.OTMLChildIdCache) { - if (childTag.size() > 0 && childTag[0] == '!') - g_logger.fatal(stdext::format("Invalid childTag %s", childTag)); - auto it = m_childrenTagCache.find(childTag); - if (it != m_childrenTagCache.end() && !it->second->isNull()) - return it->second; - //} - - for(const OTMLNodePtr& child : m_children) { - if (child->tag() == childTag && !child->isNull()) { - std::string tag = child->tag(); - if (tag.size() > 0 && tag[0] == '!') - tag = tag.substr(1); - m_childrenTagCache[tag] = child; - child->lockTag(); - return child; - } - } - return nullptr; -} - -OTMLNodePtr OTMLNode::getIndex(int childIndex) -{ - if(childIndex < size() && childIndex >= 0) - return m_children[childIndex]; - return nullptr; -} - -OTMLNodePtr OTMLNode::at(const std::string& childTag) -{ - OTMLNodePtr res; - for(const OTMLNodePtr& child : m_children) { - if(child->tag() == childTag && !child->isNull()) { - res = child; - break; - } - } - if(!res) - throw OTMLException(asOTMLNode(), stdext::format("child node with tag '%s' not found", childTag)); - return res; -} - -OTMLNodePtr OTMLNode::atIndex(int childIndex) -{ - if(childIndex >= size() || childIndex < 0) - throw OTMLException(asOTMLNode(), stdext::format("child node with index '%d' not found", childIndex)); - return m_children[childIndex]; -} - -void OTMLNode::addChild(const OTMLNodePtr& newChild) -{ - // replace is needed when the tag is marked as unique - if(newChild->hasTag()) { - for(const OTMLNodePtr& node : m_children) { - if(node->tag() == newChild->tag() && (node->isUnique() || newChild->isUnique())) { - newChild->setUnique(true); - - if(node->hasChildren() && newChild->hasChildren()) { - OTMLNodePtr tmpNode = node->clone(); - tmpNode->merge(newChild); - newChild->copy(tmpNode); - } - - replaceChild(node, newChild); - - // remove any other child with the same tag - auto it = m_children.begin(); - while(it != m_children.end()) { - OTMLNodePtr node = (*it); - if(node != newChild && node->tag() == newChild->tag()) { - std::string tag = newChild->tag(); - if (tag.size() > 0 && tag[0] == '!') - tag = tag.substr(1); - auto cacheIt = m_childrenTagCache.find(tag); - if (cacheIt != m_childrenTagCache.end()) { - if (cacheIt->second != newChild) { - m_childrenTagCache.erase(cacheIt); - m_childrenTagCache[tag] = newChild; - newChild->lockTag(); - } - } - it = m_children.erase(it); - } else - ++it; - } - return; - } - } - } - - m_children.push_back(newChild); - std::string tag = newChild->tag(); - if (tag.size() > 0 && tag[0] == '!') - tag = tag.substr(1); - m_childrenTagCache[tag] = newChild; - newChild->lockTag(); -} - -bool OTMLNode::removeChild(const OTMLNodePtr& oldChild) -{ - auto it = std::find(m_children.begin(), m_children.end(), oldChild); - if(it != m_children.end()) { - m_children.erase(it); - m_childrenTagCache.erase((*it)->tag()); - return true; - } - return false; -} - -bool OTMLNode::replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild) -{ - auto it = std::find(m_children.begin(), m_children.end(), oldChild); - if(it != m_children.end()) { - std::string tag = (*it)->tag(); - if (tag.size() > 0 && tag[0] == '!') - tag = tag.substr(1); - auto cacheIt = m_childrenTagCache.find(tag); - if (cacheIt != m_childrenTagCache.end()) { - if (cacheIt->second == (*it)) - m_childrenTagCache.erase(cacheIt); - } - it = m_children.erase(it); - - m_children.insert(it, newChild); - tag = newChild->tag(); - if (tag.size() > 0 && tag[0] == '!') - tag = tag.substr(1); - m_childrenTagCache[tag] = newChild; - newChild->lockTag(); - return true; - } - return false; -} - -void OTMLNode::copy(const OTMLNodePtr& node) -{ - setTag(node->tag()); - setValue(node->rawValue()); - setUnique(node->isUnique()); - setNull(node->isNull()); - setSource(node->source()); - clear(); - for(const OTMLNodePtr& child : node->m_children) - addChild(child->clone()); -} - -void OTMLNode::merge(const OTMLNodePtr& node) -{ - for(const OTMLNodePtr& child : node->m_children) - addChild(child->clone()); - setTag(node->tag()); - setSource(node->source()); -} - -void OTMLNode::clear() -{ - m_children.clear(); - m_childrenTagCache.clear(); -} - -OTMLNodeList OTMLNode::children() -{ - OTMLNodeList children; - for(const OTMLNodePtr& child : m_children) - if(!child->isNull()) - children.push_back(child); - return children; -} - -OTMLNodePtr OTMLNode::clone() -{ - OTMLNodePtr myClone(new OTMLNode); - myClone->setTag(m_tag); - myClone->setValue(m_value); - myClone->setUnique(m_unique); - myClone->setNull(m_null); - myClone->setSource(m_source); - for(const OTMLNodePtr& child : m_children) - myClone->addChild(child->clone()); - return myClone; -} - -std::string OTMLNode::emit() -{ - return OTMLEmitter::emitNode(asOTMLNode(), 0); -} - -void OTMLNode::setTag(const std::string& tag) { - if (m_tagLocked && tag != m_tag) { - std::string correct_tag = m_tag; - if (correct_tag.size() > 0 && m_tag[0] == '!') - correct_tag = correct_tag.substr(1); - if(correct_tag != tag) - g_logger.fatal(stdext::format("Trying to setTag for locked QTMLNode %s to %s", m_tag, tag)); - } - m_tag = tag; -} diff --git a/src/framework/otml/otmlnode.h b/src/framework/otml/otmlnode.h deleted file mode 100644 index 6208714..0000000 --- a/src/framework/otml/otmlnode.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OTMLNODE_H -#define OTMLNODE_H - -#include "declarations.h" - -class OTMLNode : public stdext::shared_object -{ -public: - virtual ~OTMLNode() { } - - static OTMLNodePtr create(std::string tag = "", bool unique = false); - static OTMLNodePtr create(std::string tag, std::string value); - - std::string tag() { return m_tag; } - int size() { return m_children.size(); } - std::string source() { return m_source; } - std::string rawValue() { return m_value; } - - bool isUnique() { return m_unique; } - bool isNull() { return m_null; } - - bool hasTag() { return !m_tag.empty(); } - bool hasValue() { return !m_value.empty(); } - bool hasChildren(); - bool hasChildAt(const std::string& childTag) { return !!get(childTag); } - bool hasChildAtIndex(int childIndex) { return !!getIndex(childIndex); } - - void setTag(const std::string& tag); - void setValue(const std::string& value) { m_value = value; } - void setNull(bool null) { m_null = null; } - void setUnique(bool unique) { m_unique = unique; } - void setSource(const std::string& source) { m_source = source; } - - void lockTag() { - m_tagLocked = true; - } - - OTMLNodePtr get(const std::string& childTag); - OTMLNodePtr getIndex(int childIndex); - - OTMLNodePtr at(const std::string& childTag); - OTMLNodePtr atIndex(int childIndex); - - void addChild(const OTMLNodePtr& newChild); - bool removeChild(const OTMLNodePtr& oldChild); - bool replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild); - void copy(const OTMLNodePtr& node); - void merge(const OTMLNodePtr& node); - void clear(); - - OTMLNodeList children(); - OTMLNodePtr clone(); - - template - T value(); - template - T valueAt(const std::string& childTag); - template - T valueAtIndex(int childIndex); - template - T valueAt(const std::string& childTag, const T& def); - template - T valueAtIndex(int childIndex, const T& def); - - template - void write(const T& v); - template - void writeAt(const std::string& childTag, const T& v); - template - void writeIn(const T& v); - - virtual std::string emit(); - - OTMLNodePtr asOTMLNode() { return static_self_cast(); } - -protected: - OTMLNode() : m_unique(false), m_null(false) { } - - OTMLNodeList m_children; - std::unordered_map m_childrenTagCache; - std::string m_tag; - std::string m_value; - std::string m_source; - bool m_unique; - bool m_null; - bool m_tagLocked = false; -}; - -#include "otmlexception.h" - -template<> -inline std::string OTMLNode::value() { - std::string value = m_value; - if(stdext::starts_with(value, "\"") && stdext::ends_with(value, "\"")) { - value = value.substr(1, value.length()-2); - stdext::replace_all(value, "\\\\", "\\"); - stdext::replace_all(value, "\\\"", "\""); - stdext::replace_all(value, "\\t", "\t"); - stdext::replace_all(value, "\\n", "\n"); - stdext::replace_all(value, "\\'", "\'"); - } - return value; -} - -template -T OTMLNode::value() { - T ret; - if(!stdext::cast(m_value, ret)) - throw OTMLException(asOTMLNode(), stdext::format("failed to cast node value '%s' to type '%s'", m_value, stdext::demangle_type())); - return ret; -} - -template -T OTMLNode::valueAt(const std::string& childTag) { - OTMLNodePtr node = at(childTag); - return node->value(); -} - -template -T OTMLNode::valueAtIndex(int childIndex) { - OTMLNodePtr node = atIndex(childIndex); - return node->value(); -} - -template -T OTMLNode::valueAt(const std::string& childTag, const T& def) { - if(OTMLNodePtr node = get(childTag)) - if(!node->isNull()) - return node->value(); - return def; -} - -template -T OTMLNode::valueAtIndex(int childIndex, const T& def) { - if(OTMLNodePtr node = getIndex(childIndex)) - return node->value(); - return def; -} - -template -void OTMLNode::write(const T& v) { - m_value = stdext::safe_cast(v); -} - -template -void OTMLNode::writeAt(const std::string& childTag, const T& v) { - OTMLNodePtr child = OTMLNode::create(childTag); - child->setUnique(true); - child->write(v); - addChild(child); -} - -template -void OTMLNode::writeIn(const T& v) { - OTMLNodePtr child = OTMLNode::create(); - child->write(v); - addChild(child); -} - -#endif - diff --git a/src/framework/otml/otmlparser.cpp b/src/framework/otml/otmlparser.cpp deleted file mode 100644 index 256fb7d..0000000 --- a/src/framework/otml/otmlparser.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "otmlparser.h" -#include "otmldocument.h" -#include "otmlexception.h" -#include - -OTMLParser::OTMLParser(OTMLDocumentPtr doc, std::istream& in) : - currentDepth(0), currentLine(0), - doc(doc), currentParent(doc), previousNode(0), - in(in) -{ -} - -void OTMLParser::parse() -{ - if(!in.good()) - throw OTMLException(doc, "cannot read from input stream"); - - while(!in.eof()) - parseLine(getNextLine()); -} - -std::string OTMLParser::getNextLine() -{ - currentLine++; - std::string line; - std::getline(in, line); - return line; -} - -int OTMLParser::getLineDepth(const std::string& line, bool multilining) -{ - // count number of spaces at the line beginning - std::size_t spaces = 0; - while(line[spaces] == ' ') - spaces++; - - // pre calculate depth - int depth = spaces / 2; - - if(!multilining || depth <= currentDepth) { - // check the next character is a tab - if(line[spaces] == '\t') - throw OTMLException(doc, "indentation with tabs are not allowed", currentLine); - - // must indent every 2 spaces - if(spaces % 2 != 0) - throw OTMLException(doc, "must indent every 2 spaces", currentLine); - } - - return depth; -} - -void OTMLParser::parseLine(std::string line) -{ - int depth = getLineDepth(line); - - if(depth == -1) - return; - - // remove line sides spaces - stdext::trim(line); - - // skip empty lines - if(line.empty()) - return; - - // skip comments - if(stdext::starts_with(line, "//")) - return; - - // a depth above, change current parent to the previous added node - if(depth == currentDepth+1) { - currentParent = previousNode; - // a depth below, change parent to previous parent - } else if(depth < currentDepth) { - for(int i=0;i dotsPos+1) - value = data.substr(dotsPos+1); - // node that has only a tag - } else { - tag = data; - } - - stdext::trim(tag); - stdext::trim(value); - - // process multitine values - if(value == "|" || value == "|-" || value == "|+") { - // reads next lines until we can a value below the same depth - std::string multiLineData; - do { - size_t lastPos = in.tellg(); - std::string line = getNextLine(); - int depth = getLineDepth(line, true); - - // depth above current depth, add the text to the multiline - if(depth > currentDepth) { - multiLineData += line.substr((currentDepth+1)*2); - // it has contents below the current depth - } else { - // if not empty, its a node - stdext::trim(line); - if(!line.empty()) { - // rewind and break - in.seekg(lastPos, std::ios::beg); - currentLine--; - break; - } - } - multiLineData += "\n"; - } while(!in.eof()); - - /* determine how to treat new lines at the end - * | strip all new lines at the end and add just a new one - * |- strip all new lines at the end - * |+ keep all the new lines at the end (the new lines until next node) - */ - if(value == "|" || value == "|-") { - // remove all new lines at the end - int lastPos = multiLineData.length(); - while(multiLineData[--lastPos] == '\n') - multiLineData.erase(lastPos, 1); - - if(value == "|") - multiLineData.append("\n"); - } // else it's |+ - - value = multiLineData; - } - - // create the node - OTMLNodePtr node = OTMLNode::create(tag); - - node->setUnique(dotsPos != std::string::npos); - node->setTag(tag); - node->setSource(doc->source() + ":" + stdext::unsafe_cast(nodeLine)); - - // ~ is considered the null value - if(value == "~") - node->setNull(true); - else { - if(stdext::starts_with(value, "[") && stdext::ends_with(value, "]")) { - std::string tmp = value.substr(1, value.length()-2); - boost::tokenizer> tokens(tmp); - for(std::string v : tokens) { - stdext::trim(v); - node->writeIn(v); - } - } else - node->setValue(value); - } - - currentParent->addChild(node); - parentMap[node] = currentParent; - previousNode = node; -} diff --git a/src/framework/otml/otmlparser.h b/src/framework/otml/otmlparser.h deleted file mode 100644 index 364c347..0000000 --- a/src/framework/otml/otmlparser.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef OTMLPARSER_H -#define OTMLPARSER_H - -#include "declarations.h" - -class OTMLParser -{ -public: - OTMLParser(OTMLDocumentPtr doc, std::istream& in); - - /// Parse the entire document - void parse(); - -private: - /// Retrieve next line from the input stream - std::string getNextLine(); - /// Counts depth of a line (every 2 spaces increments one depth) - int getLineDepth(const std::string& line, bool multilining = false); - - /// Parse each line of the input stream - void parseLine(std::string line); - /// Parse nodes tag and value - void parseNode(const std::string& data); - - int currentDepth; - int currentLine; - OTMLDocumentPtr doc; - OTMLNodePtr currentParent; - std::unordered_map parentMap; - OTMLNodePtr previousNode; - std::istream& in; -}; - -#endif diff --git a/src/framework/pch.h b/src/framework/pch.h deleted file mode 100644 index 02af543..0000000 --- a/src/framework/pch.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PCH_H -#define PCH_H - -// common C headers -#include -#include -#include -#include -#include - -// common STL headers -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// new -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef ANDROID -#include -#endif - - // boost -#ifdef ANDROID -#define BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX -#endif -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/src/framework/platform/crashhandler.h b/src/framework/platform/crashhandler.h deleted file mode 100644 index 571e5a4..0000000 --- a/src/framework/platform/crashhandler.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CRASHHANDLER_H -#define CRASHHANDLER_H - -#ifdef CRASH_HANDLER -void installCrashHandler(); -void uninstallCrashHandler(); -#endif - -#endif diff --git a/src/framework/platform/platform.cpp b/src/framework/platform/platform.cpp deleted file mode 100644 index a258813..0000000 --- a/src/framework/platform/platform.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "platform.h" - -Platform g_platform; diff --git a/src/framework/platform/platform.h b/src/framework/platform/platform.h deleted file mode 100644 index 1be5dc0..0000000 --- a/src/framework/platform/platform.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PLATFORM_H -#define PLATFORM_H - -#include -#include -#include - -class Platform -{ -public: - void processArgs(std::vector& args); - bool spawnProcess(std::string process, const std::vector& args); - int getProcessId(); - bool isProcessRunning(const std::string& name); - bool killProcess(const std::string& name); - std::string getTempPath(); - std::string getCurrentDir(); - bool copyFile(std::string from, std::string to); - bool fileExists(std::string file); - bool removeFile(std::string file); - ticks_t getFileModificationTime(std::string file); - bool openUrl(std::string url, bool now = false); - bool openDir(std::string path, bool now = false); - std::string getCPUName(); - double getTotalSystemMemory(); - double getMemoryUsage(); - std::string getOSName(); - std::string traceback(const std::string& where, int level = 1, int maxDepth = 32); - std::vector getMacAddresses(); - std::string getUserName(); - std::vector getDlls(); - std::vector getProcesses(); - std::vector getWindows(); -}; - -extern Platform g_platform; - -#endif diff --git a/src/framework/platform/platformwindow.cpp b/src/framework/platform/platformwindow.cpp deleted file mode 100644 index acad7de..0000000 --- a/src/framework/platform/platformwindow.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "platformwindow.h" - -#if defined(WIN32) -#include "win32window.h" -WIN32Window window; -#elif defined(ANDROID) -#include "androidwindow.h" -#else -#include "x11window.h" -#include -X11Window window; -#endif - -#include -#include -#include - -#ifdef ANDROID -PlatformWindow& g_window = g_androidWindow; -#else -PlatformWindow& g_window = window; -#endif - -int PlatformWindow::loadMouseCursor(const std::string& file, const Point& hotSpot) -{ - ImagePtr image = Image::load(file); - - if(!image) { - g_logger.traceError(stdext::format("unable to load cursor image file %s", file)); - return -1; - } - - if(image->getBpp() != 4) { - g_logger.error("the cursor image must have 4 channels"); - return -1; - } - - if(image->getWidth() != 32 || image->getHeight() != 32) { - g_logger.error("the cursor image must have 32x32 dimension"); - return -1; - } - - return internalLoadMouseCursor(image, hotSpot); -} - -void PlatformWindow::updateUnmaximizedCoords() -{ - if(!isMaximized() && !isFullscreen()) { - m_unmaximizedPos = m_position; - m_unmaximizedSize = m_size; - } -} - -void PlatformWindow::processKeyDown(Fw::Key keyCode) -{ - if (std::this_thread::get_id() != g_dispatcherThreadId) { - g_dispatcher.addEvent(std::bind(&PlatformWindow::processKeyDown, this, keyCode)); - return; - } - - if(keyCode == Fw::KeyUnknown) - return; - - if(keyCode == Fw::KeyCtrl) { - m_inputEvent.keyboardModifiers |= Fw::KeyboardCtrlModifier; - return; - } else if(keyCode == Fw::KeyAlt) { - m_inputEvent.keyboardModifiers |= Fw::KeyboardAltModifier; - return; - } else if(keyCode == Fw::KeyShift) { - m_inputEvent.keyboardModifiers |= Fw::KeyboardShiftModifier; - return; - } - - if(m_keysState[keyCode]) - return; - - m_keysState[keyCode] = true; - m_lastKeysPress[keyCode] = -1; - - m_inputEvent.reset(Fw::KeyDownInputEvent); - m_inputEvent.type = Fw::KeyDownInputEvent; - m_inputEvent.keyCode = keyCode; - - if(m_onInputEvent) { - m_onInputEvent(m_inputEvent); - - m_inputEvent.reset(Fw::KeyPressInputEvent); - m_inputEvent.keyCode = keyCode; - m_lastKeysPress[keyCode] = g_clock.millis(); - m_firstKeysPress[keyCode] = g_clock.millis(); - m_onInputEvent(m_inputEvent); - } -} - -void PlatformWindow::processKeyUp(Fw::Key keyCode) -{ - if (std::this_thread::get_id() != g_dispatcherThreadId) { - g_dispatcher.addEvent(std::bind(&PlatformWindow::processKeyUp, this, keyCode)); - return; - } - - if(keyCode == Fw::KeyUnknown) - return; - - if(keyCode == Fw::KeyCtrl) { - m_inputEvent.keyboardModifiers &= ~Fw::KeyboardCtrlModifier; - return; - } else if(keyCode == Fw::KeyAlt) { - m_inputEvent.keyboardModifiers &= ~Fw::KeyboardAltModifier; - return; - } else if(keyCode == Fw::KeyShift) { - m_inputEvent.keyboardModifiers &= ~Fw::KeyboardShiftModifier; - return; - } else if(keyCode == Fw::KeyNumLock) { - for(uchar k = Fw::KeyNumpad0; k <= Fw::KeyNumpad9; ++k) { - if(m_keysState[(Fw::Key)k]) - processKeyUp((Fw::Key)k); - } - } - - if(!m_keysState[keyCode]) - return; - - m_keysState[keyCode] = false; - - if(m_onInputEvent) { - m_inputEvent.reset(Fw::KeyUpInputEvent); - m_inputEvent.keyCode = keyCode; - m_onInputEvent(m_inputEvent); - } -} - -void PlatformWindow::releaseAllKeys() -{ - if (std::this_thread::get_id() != g_dispatcherThreadId) { - g_dispatcher.addEvent(std::bind(&PlatformWindow::releaseAllKeys, this)); - return; - } - - for(auto it : m_keysState) { - Fw::Key keyCode = it.first; - bool pressed = it.second; - - if(!pressed) - continue; - - processKeyUp(keyCode); - } - - m_inputEvent.keyboardModifiers = 0; - - for(int i=0;i<4;++i) - m_mouseButtonStates[i] = false; -} - -void PlatformWindow::fireKeysPress() -{ - if (std::this_thread::get_id() != g_dispatcherThreadId) { - g_dispatcher.addEvent(std::bind(&PlatformWindow::fireKeysPress, this)); - return; - } - - // avoid massive checks - if(m_keyPressTimer.ticksElapsed() < 10) - return; - m_keyPressTimer.restart(); - - for(auto it : m_keysState) { - Fw::Key keyCode = it.first; - bool pressed = it.second; - - if(!pressed) - continue; - - ticks_t lastPressTicks = m_lastKeysPress[keyCode]; - ticks_t firstKeyPress = m_firstKeysPress[keyCode]; - if(g_clock.millis() - lastPressTicks >= KEY_PRESS_REPEAT_INTERVAL) { - if(m_onInputEvent) { - m_inputEvent.reset(Fw::KeyPressInputEvent); - m_inputEvent.keyCode = keyCode; - m_inputEvent.autoRepeatTicks = g_clock.millis() - firstKeyPress; - m_onInputEvent(m_inputEvent); - } - m_lastKeysPress[keyCode] = g_clock.millis(); - } - } -} - diff --git a/src/framework/platform/platformwindow.h b/src/framework/platform/platformwindow.h deleted file mode 100644 index 9a3eb48..0000000 --- a/src/framework/platform/platformwindow.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PLATFORMWINDOW_H -#define PLATFORMWINDOW_H - -#include -#include -#include -#include - -//@bindsingleton g_window -class PlatformWindow -{ - enum { - KEY_PRESS_REPEAT_INTERVAL = 30, - }; - - typedef std::function OnResizeCallback; - typedef std::function OnInputEventCallback; - -public: - virtual void init() = 0; - virtual void terminate() = 0; - - virtual void move(const Point& pos) = 0; - virtual void resize(const Size& size) = 0; - virtual void show() = 0; - virtual void hide() = 0; - virtual void maximize() = 0; - virtual void poll() = 0; - virtual void swapBuffers() = 0; - virtual void showMouse() = 0; - virtual void hideMouse() = 0; - virtual void displayFatalError(const std::string& message) { } - - int loadMouseCursor(const std::string& file, const Point& hotSpot); - virtual void setMouseCursor(int cursorId) = 0; - virtual void restoreMouseCursor() = 0; - - virtual void setTitle(const std::string& title) = 0; - virtual void setMinimumSize(const Size& minimumSize) = 0; - virtual void setFullscreen(bool fullscreen) = 0; - virtual void setVerticalSync(bool enable) = 0; - virtual void setIcon(const std::string& iconFile) = 0; - virtual void setClipboardText(const std::string& text) = 0; - - bool hasVerticalSync() { return m_verticalSync; } - - virtual Size getDisplaySize() = 0; - virtual std::string getClipboardText() = 0; - virtual std::string getPlatformType() = 0; - - int getDisplayWidth() { return getDisplaySize().width(); } - int getDisplayHeight() { return getDisplaySize().height(); } - - Size getUnmaximizedSize() { return m_unmaximizedSize; } - Size getSize() { return m_size; } - Size getMinimumSize() { return m_minimumSize; } - int getWidth() { return m_size.width(); } - int getHeight() { return m_size.height(); } - Point getUnmaximizedPos() { return m_unmaximizedPos; } - Point getPosition() { return m_position; } - int getX() { return m_position.x; } - int getY() { return m_position.y; } - Point getMousePosition() { return m_inputEvent.mousePos; } - int getKeyboardModifiers() { return m_inputEvent.keyboardModifiers; } - - bool isKeyPressed(Fw::Key keyCode) { return m_keysState[keyCode]; } - bool isMouseButtonPressed(Fw::MouseButton mouseButton) { return m_mouseButtonStates[mouseButton]; } - bool isVisible() { return m_visible; } - bool isMaximized() { return m_maximized; } - bool isFullscreen() { return m_fullscreen; } - bool hasFocus() { return m_focused; } - - void setOnClose(const std::function& onClose) { m_onClose = onClose; } - void setOnResize(const OnResizeCallback& onResize) { m_onResize = onResize; } - void setOnInputEvent(const OnInputEventCallback& onInputEvent) { m_onInputEvent = onInputEvent; } - - virtual void showTextEditor(const std::string& title, const std::string& description, const std::string& text, int flags) {} - virtual void handleTextInput(std::string text) {} // for android - - void setScaling(float scaling) { m_scaling = scaling; } - -protected: - virtual int internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot) = 0; - - void updateUnmaximizedCoords(); - - void processKeyDown(Fw::Key keyCode); - void processKeyUp(Fw::Key keyCode); - void releaseAllKeys(); - void fireKeysPress(); - - std::map m_keyMap; - std::map> m_keysState; - std::map m_firstKeysPress; - std::map m_lastKeysPress; - Timer m_keyPressTimer; - - Size m_size; - Size m_minimumSize; - Point m_position; - Size m_unmaximizedSize; - Point m_unmaximizedPos; - InputEvent m_inputEvent; - stdext::boolean m_mouseButtonStates[4]; - - stdext::boolean m_created; - stdext::boolean m_visible; - stdext::boolean m_focused; - stdext::boolean m_fullscreen; - stdext::boolean m_maximized; - bool m_verticalSync = false; - float m_scaling = 1.0; - - std::function m_onClose; - OnResizeCallback m_onResize; - OnInputEventCallback m_onInputEvent; -}; - -extern PlatformWindow& g_window; - -#endif diff --git a/src/framework/sound/combinedsoundsource.cpp b/src/framework/sound/combinedsoundsource.cpp deleted file mode 100644 index 7b0e130..0000000 --- a/src/framework/sound/combinedsoundsource.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#include "combinedsoundsource.h" - -CombinedSoundSource::CombinedSoundSource() : SoundSource(0) -{ -} - -void CombinedSoundSource::addSource(const SoundSourcePtr& source) -{ - m_sources.push_back(source); -} - -void CombinedSoundSource::play() -{ - for(const SoundSourcePtr& source : m_sources) - source->play(); -} - -void CombinedSoundSource::stop() -{ - for(const SoundSourcePtr& source : m_sources) - source->stop(); -} - -bool CombinedSoundSource::isBuffering() -{ - for(const SoundSourcePtr& source : m_sources) { - if(source->isBuffering()) - return true; - } - return false; -} - -bool CombinedSoundSource::isPlaying() -{ - for(const SoundSourcePtr& source : m_sources) { - if(source->isPlaying()) - return true; - } - return false; -} - -void CombinedSoundSource::setLooping(bool looping) -{ - for(const SoundSourcePtr& source : m_sources) - source->setLooping(looping); -} - -void CombinedSoundSource::setRelative(bool relative) -{ - for(const SoundSourcePtr& source : m_sources) - source->setRelative(relative); -} - -void CombinedSoundSource::setReferenceDistance(float distance) -{ - for(const SoundSourcePtr& source : m_sources) - source->setReferenceDistance(distance); -} - -void CombinedSoundSource::setGain(float gain) -{ - for(const SoundSourcePtr& source : m_sources) - source->setGain(gain); -} - -void CombinedSoundSource::setPitch(float pitch) -{ - for(const SoundSourcePtr& source : m_sources) - source->setPitch(pitch); -} - -void CombinedSoundSource::setPosition(const Point& pos) -{ - for(const SoundSourcePtr& source : m_sources) - source->setPosition(pos); -} - -void CombinedSoundSource::setVelocity(const Point& velocity) -{ - for(const SoundSourcePtr& source : m_sources) - source->setVelocity(velocity); -} - -void CombinedSoundSource::setFading(SoundSource::FadeState state, float fadetime) -{ - for(const SoundSourcePtr& source : m_sources) - source->setFading(state, fadetime); -} - -void CombinedSoundSource::update() -{ - for(const SoundSourcePtr& source : m_sources) - source->update(); -} - -#endif \ No newline at end of file diff --git a/src/framework/sound/combinedsoundsource.h b/src/framework/sound/combinedsoundsource.h deleted file mode 100644 index e4da04e..0000000 --- a/src/framework/sound/combinedsoundsource.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef COMBINEDSOUNDSOURCE_H -#define COMBINEDSOUNDSOURCE_H - -#include "soundsource.h" - -class CombinedSoundSource : public SoundSource -{ -public: - CombinedSoundSource(); - - void addSource(const SoundSourcePtr& source); - std::vector getSources() { return m_sources; } - - void play(); - void stop(); - - bool isBuffering(); - bool isPlaying(); - - void setLooping(bool looping); - void setRelative(bool relative); - void setReferenceDistance(float distance); - void setGain(float gain); - void setPitch(float pitch); - void setPosition(const Point& pos); - void setVelocity(const Point& velocity); - void setFading(FadeState state, float fadetime); - -protected: - virtual void update(); - -private: - std::vector m_sources; -}; - -#endif - -#endif \ No newline at end of file diff --git a/src/framework/sound/declarations.h b/src/framework/sound/declarations.h deleted file mode 100644 index dc92d3d..0000000 --- a/src/framework/sound/declarations.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef FRAMEWORK_SOUND_DECLARATIONS_H -#define FRAMEWORK_SOUND_DECLARATIONS_H - -#include - -#define AL_LIBTYPE_STATIC - -#include -#include - -class SoundManager; -class SoundSource; -class SoundBuffer; -class SoundFile; -class SoundChannel; -class StreamSoundSource; -class CombinedSoundSource; -class OggSoundFile; - -typedef stdext::shared_object_ptr SoundSourcePtr; -typedef stdext::shared_object_ptr SoundFilePtr; -typedef stdext::shared_object_ptr SoundBufferPtr; -typedef stdext::shared_object_ptr SoundChannelPtr; -typedef stdext::shared_object_ptr StreamSoundSourcePtr; -typedef stdext::shared_object_ptr CombinedSoundSourcePtr; -typedef stdext::shared_object_ptr OggSoundFilePtr; - -#endif - -#endif \ No newline at end of file diff --git a/src/framework/sound/oggsoundfile.cpp b/src/framework/sound/oggsoundfile.cpp deleted file mode 100644 index 556fe96..0000000 --- a/src/framework/sound/oggsoundfile.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#include "oggsoundfile.h" - -OggSoundFile::OggSoundFile(const FileStreamPtr& fileStream) : SoundFile(fileStream) -{ - memset(&m_vorbisFile, 0, sizeof(m_vorbisFile)); -} - -OggSoundFile::~OggSoundFile() -{ - ov_clear(&m_vorbisFile); -} - -bool OggSoundFile::prepareOgg() -{ - ov_callbacks callbacks = { cb_read, cb_seek, cb_close, cb_tell }; - ov_open_callbacks(m_file.get(), &m_vorbisFile, 0, 0, callbacks); - - vorbis_info* vi = ov_info(&m_vorbisFile, -1); - if(!vi) { - g_logger.error(stdext::format("ogg file not supported: %s", m_file->name())); - return false; - } - - m_channels = vi->channels; - m_rate = vi->rate; - m_bps = 16; - m_size = ov_pcm_total(&m_vorbisFile, -1) * (m_bps/8) * m_channels; - - return true; -} - -int OggSoundFile::read(void *buffer, int bufferSize) -{ - char* bytesBuffer = reinterpret_cast(buffer); - int section = 0; - size_t totalBytesRead = 0; - - while(bufferSize > 0) { - size_t bytesToRead = bufferSize; - long bytesRead = ov_read(&m_vorbisFile, bytesBuffer, bytesToRead, 0, 2, 1, §ion); - if(bytesRead == 0) - break; - - bufferSize -= bytesRead; - bytesBuffer += bytesRead; - totalBytesRead += bytesRead; - } - - return totalBytesRead; -} - -void OggSoundFile::reset() -{ - ov_pcm_seek(&m_vorbisFile, 0); -} - -size_t OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source) -{ - FileStream *file = static_cast(source); - return file->read(ptr, size, nmemb); -} - -int OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence) -{ - FileStream *file = static_cast(source); - switch(whence) { - case SEEK_SET: - file->seek(offset); - return 0; - case SEEK_CUR: - file->seek(file->tell() + offset); - return 0; - case SEEK_END: - file->seek(file->size() + offset); - return 0; - } - return -1; -} - -int OggSoundFile::cb_close(void* source) -{ - FileStream *file = static_cast(source); - file->close(); - return 0; -} - -long OggSoundFile::cb_tell(void* source) -{ - FileStream *file = static_cast(source); - return file->tell(); -} - -#endif \ No newline at end of file diff --git a/src/framework/sound/oggsoundfile.h b/src/framework/sound/oggsoundfile.h deleted file mode 100644 index cc230fe..0000000 --- a/src/framework/sound/oggsoundfile.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef OGGSOUNDFILE_H -#define OGGSOUNDFILE_H - -#include "soundfile.h" - -#include - -class OggSoundFile : public SoundFile -{ -public: - OggSoundFile(const FileStreamPtr& fileStream); - virtual ~OggSoundFile(); - - bool prepareOgg(); - - int read(void *buffer, int bufferSize); - void reset(); - -private: - static size_t cb_read(void* ptr, size_t size, size_t nmemb, void* source); - static int cb_seek(void* source, ogg_int64_t offset, int whence); - static int cb_close(void* source); - static long cb_tell(void* source); - - OggVorbis_File m_vorbisFile; -}; - -#endif - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundbuffer.cpp b/src/framework/sound/soundbuffer.cpp deleted file mode 100644 index b021987..0000000 --- a/src/framework/sound/soundbuffer.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#include "soundbuffer.h" -#include "soundfile.h" - -SoundBuffer::SoundBuffer() -{ - m_bufferId = 0; - alGenBuffers(1, &m_bufferId); - VALIDATE(alGetError() == AL_NO_ERROR); -} - -SoundBuffer::~SoundBuffer() -{ - alDeleteBuffers(1, &m_bufferId); - VALIDATE(alGetError() == AL_NO_ERROR); -} - -bool SoundBuffer::fillBuffer(const SoundFilePtr& soundFile) -{ - ALenum format = soundFile->getSampleFormat(); - if(format == AL_UNDETERMINED) { - g_logger.error(stdext::format("unable to determine sample format for '%s'", soundFile->getName())); - return false; - } - - DataBuffer samples(soundFile->getSize()); - int read = soundFile->read(&samples[0], soundFile->getSize()); - if(read == 0) { - g_logger.error(stdext::format("unable to fill audio buffer data for '%s'", soundFile->getName())); - return false; - } - - return fillBuffer(format, samples, samples.size(), soundFile->getRate()); -} - -bool SoundBuffer::fillBuffer(ALenum sampleFormat, const DataBuffer& data, int size, int rate) -{ - alBufferData(m_bufferId, sampleFormat, &data[0], size, rate); - ALenum err = alGetError(); - if(err != AL_NO_ERROR) { - g_logger.error(stdext::format("unable to fill audio buffer data: %s", alGetString(err))); - return false; - } - return true; -} - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundbuffer.h b/src/framework/sound/soundbuffer.h deleted file mode 100644 index 5f7738d..0000000 --- a/src/framework/sound/soundbuffer.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef SOUNDBUFFER_H -#define SOUNDBUFFER_H - -#include "declarations.h" - -#include - -class SoundBuffer : public stdext::shared_object -{ -public: - SoundBuffer(); - ~SoundBuffer(); - - bool fillBuffer(const SoundFilePtr& soundFile); - bool fillBuffer(ALenum sampleFormat, const DataBuffer& data, int size, int rate); - - uint getBufferId() { return m_bufferId; } - -private: - uint m_bufferId; -}; - -#endif - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundchannel.cpp b/src/framework/sound/soundchannel.cpp deleted file mode 100644 index 445e53b..0000000 --- a/src/framework/sound/soundchannel.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#include "soundchannel.h" -#include "streamsoundsource.h" -#include "soundmanager.h" - -SoundSourcePtr SoundChannel::play(const std::string& filename, float fadetime, float gain) -{ - if(!g_sounds.isAudioEnabled() || !m_enabled) - return nullptr; - - if(m_currentSource) - m_currentSource->stop(); - - m_currentSource = g_sounds.play(filename, fadetime, m_gain*gain); - return m_currentSource; -} - -void SoundChannel::stop(float fadetime) -{ - m_queue.clear(); - - if(m_currentSource) { - if(fadetime > 0) - m_currentSource->setFading(StreamSoundSource::FadingOff, fadetime); - else { - m_currentSource->stop(); - m_currentSource = nullptr; - } - } -} - -void SoundChannel::enqueue(const std::string& filename, float fadetime, float gain) -{ - static std::random_device rd; - static std::mt19937 g(rd()); - - if(gain == 0) - gain = 1.0f; - m_queue.push_back(QueueEntry{g_sounds.resolveSoundFile(filename), fadetime, gain}); - std::shuffle(m_queue.begin(), m_queue.end(), g); - //update(); -} - -void SoundChannel::update() -{ - if(m_currentSource && !m_currentSource->isPlaying()) - m_currentSource = nullptr; - - if(!m_currentSource && !m_queue.empty() && g_sounds.isAudioEnabled() && m_enabled) { - QueueEntry entry = m_queue.front(); - m_queue.pop_front(); - m_queue.push_back(entry); - play(entry.filename, entry.fadetime, entry.gain); - } -} - -void SoundChannel::setEnabled(bool enable) -{ - if(m_enabled == enable) - return; - - if(enable) { - m_enabled = true; - update(); - } else { - m_enabled = false; - if(m_currentSource) { - m_currentSource->stop(); - m_currentSource = nullptr; - } - } -} - -void SoundChannel::setGain(float gain) -{ - if(m_currentSource) - m_currentSource->setGain(gain); - m_gain = gain; -} - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundchannel.h b/src/framework/sound/soundchannel.h deleted file mode 100644 index 972ac38..0000000 --- a/src/framework/sound/soundchannel.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef SHOUNDCHANNEL_H -#define SHOUNDCHANNEL_H - -#include "soundsource.h" - -// @bindclass -class SoundChannel : public LuaObject -{ -public: - SoundChannel(int id) : m_id(id), m_gain(1) { } - - SoundSourcePtr play(const std::string& filename, float fadetime = 0, float gain = 1.0f); - void stop(float fadetime = 0); - void enqueue(const std::string& filename, float fadetime = 0, float gain = 1.0f); - void enable() { setEnabled(true); } - void disable() { setEnabled(false); } - - void setGain(float gain); - float getGain() { return m_gain; } - - void setEnabled(bool enable); - bool isEnabled() { return m_enabled; } - - int getId() { return m_id; } - -protected: - void update(); - friend class SoundManager; - -private: - struct QueueEntry { - std::string filename; - float fadetime; - float gain; - }; - std::deque m_queue; - SoundSourcePtr m_currentSource; - stdext::boolean m_enabled; - int m_id; - float m_gain; -}; - -#endif - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundfile.cpp b/src/framework/sound/soundfile.cpp deleted file mode 100644 index 62e9919..0000000 --- a/src/framework/sound/soundfile.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#include "soundfile.h" -#include "oggsoundfile.h" -#include - -SoundFile::SoundFile(const FileStreamPtr& fileStream) -{ - m_file = fileStream; -} - -SoundFilePtr SoundFile::loadSoundFile(const std::string& filename) -{ - stdext::timer t; - FileStreamPtr file = g_resources.openFile(filename); - if(!file) - stdext::throw_exception(stdext::format("unable to open %s", filename)); - - char magic[4]; - file->read(magic, 4); - file->seek(0); - - SoundFilePtr soundFile; - if(strncmp(magic, "OggS", 4) == 0) { - OggSoundFilePtr oggSoundFile = OggSoundFilePtr(new OggSoundFile(file)); - if(oggSoundFile->prepareOgg()) - soundFile = oggSoundFile; - } else - stdext::throw_exception(stdext::format("unknown sound file format %s", filename)); - - return soundFile; -} - -ALenum SoundFile::getSampleFormat() -{ - if(m_channels == 2) { - if(m_bps == 16) - return AL_FORMAT_STEREO16; - else if(m_bps == 8) - return AL_FORMAT_STEREO8; - } else if(m_channels == 1) { - if(m_bps == 16) - return AL_FORMAT_MONO16; - else if(m_bps == 8) - return AL_FORMAT_MONO8; - } - return AL_UNDETERMINED; -} - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundfile.h b/src/framework/sound/soundfile.h deleted file mode 100644 index dc4b165..0000000 --- a/src/framework/sound/soundfile.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef SOUNDFILE_H -#define SOUNDFILE_H - -#include "declarations.h" -#include - -class SoundFile : public stdext::shared_object -{ -public: - SoundFile(const FileStreamPtr& fileStream); - virtual ~SoundFile() { } - static SoundFilePtr loadSoundFile(const std::string& filename); - - virtual int read(void *buffer, int bufferSize) { return -1; } - virtual void reset() { } - bool eof() { return m_file->eof(); } - - ALenum getSampleFormat(); - - int getChannels() { return m_channels; } - int getRate() { return m_rate; } - int getBps() { return m_bps; } - int getSize() { return m_size; } - std::string getName() { return m_file ? m_file->name() : std::string(); } - -protected: - FileStreamPtr m_file; - int m_channels; - int m_rate; - int m_bps; - int m_size; -}; - -#endif - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundmanager.cpp b/src/framework/sound/soundmanager.cpp deleted file mode 100644 index 385b0f0..0000000 --- a/src/framework/sound/soundmanager.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#include "soundmanager.h" -#include "soundsource.h" -#include "soundbuffer.h" -#include "soundfile.h" -#include "streamsoundsource.h" -#include "combinedsoundsource.h" - -#include -#include -#include -#include -#include -#include - -SoundManager g_sounds; - -void SoundManager::init() -{ - m_device = alcOpenDevice(NULL); - if(!m_device) { - g_logger.error("unable to open audio device"); - return; - } - - m_context = alcCreateContext(m_device, NULL); - if(!m_context) { - g_logger.error(stdext::format("unable to create audio context: %s", alcGetString(m_device, alcGetError(m_device)))); - return; - } - - if(alcMakeContextCurrent(m_context) != ALC_TRUE) { - g_logger.error(stdext::format("unable to make context current: %s", alcGetString(m_device, alcGetError(m_device)))); - return; - } -} - -void SoundManager::terminate() -{ - ensureContext(); - - for(auto it = m_streamFiles.begin(); it != m_streamFiles.end();++it) { - auto& future = it->second; - future.wait(); - } - m_streamFiles.clear(); - - m_sources.clear(); - m_buffers.clear(); - m_channels.clear(); - - m_audioEnabled = false; - - alcMakeContextCurrent(nullptr); - - if(m_context) { - alcDestroyContext(m_context); - m_context = nullptr; - } - - if(m_device) { - alcCloseDevice(m_device); - m_device = nullptr; - } -} - -void SoundManager::poll() -{ - AutoStat s(STATS_MAIN, "PollSounds"); - - static ticks_t lastUpdate = 0; - ticks_t now = g_clock.millis(); - - if(now - lastUpdate < POLL_DELAY) - return; - - lastUpdate = now; - - ensureContext(); - - for(auto it = m_streamFiles.begin(); it != m_streamFiles.end();) { - StreamSoundSourcePtr source = it->first; - auto& future = it->second; - - if(future.valid()) { - SoundFilePtr sound = future.get(); - if(sound) - source->setSoundFile(sound); - else - source->stop(); - it = m_streamFiles.erase(it); - } else { - ++it; - } - } - - for(auto it = m_sources.begin(); it != m_sources.end();) { - SoundSourcePtr source = *it; - - source->update(); - - if(!source->isPlaying()) - it = m_sources.erase(it); - else - ++it; - } - - for(auto it : m_channels) { - it.second->update(); - } - - if(m_context) { - alcProcessContext(m_context); - } -} - -void SoundManager::setAudioEnabled(bool enable) -{ - if(m_audioEnabled == enable) - return; - - m_audioEnabled = enable; - if(!enable) { - ensureContext(); - for(const SoundSourcePtr& source : m_sources) { - source->stop(); - } - } -} - -void SoundManager::preload(std::string filename) -{ - filename = resolveSoundFile(filename); - - auto it = m_buffers.find(filename); - if(it != m_buffers.end()) - return; - - ensureContext(); - SoundFilePtr soundFile = SoundFile::loadSoundFile(filename); - - // only keep small files - if(!soundFile || soundFile->getSize() > MAX_CACHE_SIZE) - return; - - SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer); - if(buffer->fillBuffer(soundFile)) - m_buffers[filename] = buffer; -} - -SoundSourcePtr SoundManager::play(std::string filename, float fadetime, float gain) -{ - if(!m_audioEnabled) - return nullptr; - - ensureContext(); - - filename = resolveSoundFile(filename); - SoundSourcePtr soundSource = createSoundSource(filename); - if(!soundSource) { - g_logger.error(stdext::format("unable to play '%s'", filename)); - return nullptr; - } - - soundSource->setName(filename); - soundSource->setRelative(true); - soundSource->setGain(gain); - - if(fadetime > 0) - soundSource->setFading(StreamSoundSource::FadingOn, fadetime); - - soundSource->play(); - - m_sources.push_back(soundSource); - - return soundSource; -} - -SoundChannelPtr SoundManager::getChannel(int channel) -{ - ensureContext(); - if(!m_channels[channel]) - m_channels[channel] = SoundChannelPtr(new SoundChannel(channel)); - return m_channels[channel]; -} - -void SoundManager::stopAll() -{ - ensureContext(); - for(const SoundSourcePtr& source : m_sources) { - source->stop(); - } - - for(auto it : m_channels) { - it.second->stop(); - } -} - -SoundSourcePtr SoundManager::createSoundSource(const std::string& filename) -{ - SoundSourcePtr source; - - try { - auto it = m_buffers.find(filename); - if(it != m_buffers.end()) { - source = SoundSourcePtr(new SoundSource); - source->setBuffer(it->second); - } else { -#if defined __linux && !defined OPENGL_ES - // due to OpenAL implementation bug, stereo buffers are always downmixed to mono on linux systems - // this is hack to work around the issue - // solution taken from http://opensource.creative.com/pipermail/openal/2007-April/010355.html - CombinedSoundSourcePtr combinedSource(new CombinedSoundSource); - StreamSoundSourcePtr streamSource; - - streamSource = StreamSoundSourcePtr(new StreamSoundSource); - streamSource->downMix(StreamSoundSource::DownMixLeft); - streamSource->setRelative(true); - streamSource->setPosition(Point(-128, 0)); - combinedSource->addSource(streamSource); - m_streamFiles[streamSource] = g_asyncDispatcher.schedule([=]() -> SoundFilePtr { - stdext::timer a; - try { - return SoundFile::loadSoundFile(filename); - } catch(std::exception& e) { - g_logger.error(e.what()); - return nullptr; - } - }); - - streamSource = StreamSoundSourcePtr(new StreamSoundSource); - streamSource->downMix(StreamSoundSource::DownMixRight); - streamSource->setRelative(true); - streamSource->setPosition(Point(128,0)); - combinedSource->addSource(streamSource); - m_streamFiles[streamSource] = g_asyncDispatcher.schedule([=]() -> SoundFilePtr { - try { - return SoundFile::loadSoundFile(filename); - } catch(std::exception& e) { - g_logger.error(e.what()); - return nullptr; - } - }); - - source = combinedSource; -#else - StreamSoundSourcePtr streamSource(new StreamSoundSource); - m_streamFiles[streamSource] = g_asyncDispatcher.schedule([=]() -> SoundFilePtr { - try { - return SoundFile::loadSoundFile(filename); - } catch(std::exception& e) { - g_logger.error(e.what()); - return nullptr; - } - }); - source = streamSource; -#endif - } - } catch(std::exception& e) { - g_logger.error(stdext::format("failed to load sound source: '%s'", e.what())); - return nullptr; - } - - return source; -} - -std::string SoundManager::resolveSoundFile(std::string file) -{ - file = g_resources.guessFilePath(file, "ogg"); - file = g_resources.resolvePath(file); - return file; -} - -void SoundManager::ensureContext() -{ - if(m_context) - alcMakeContextCurrent(m_context); -} - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundmanager.h b/src/framework/sound/soundmanager.h deleted file mode 100644 index cbace85..0000000 --- a/src/framework/sound/soundmanager.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef SOUNDMANAGER_H -#define SOUNDMANAGER_H - -#include "declarations.h" -#include "soundchannel.h" - -//@bindsingleton g_sounds -class SoundManager -{ - enum { - MAX_CACHE_SIZE = 100000, - POLL_DELAY = 100 - }; -public: - void init(); - void terminate(); - void poll(); - - void setAudioEnabled(bool enable); - bool isAudioEnabled() { return m_device && m_context && m_audioEnabled ; } - void enableAudio() { setAudioEnabled(true); } - void disableAudio() { setAudioEnabled(true); } - void stopAll(); - - void preload(std::string filename); - SoundSourcePtr play(std::string filename, float fadetime = 0, float gain = 0); - SoundChannelPtr getChannel(int channel); - - std::string resolveSoundFile(std::string file); - void ensureContext(); - -private: - SoundSourcePtr createSoundSource(const std::string& filename); - - ALCdevice *m_device; - ALCcontext *m_context; - - std::map> m_streamFiles; - std::unordered_map m_buffers; - std::vector m_sources; - stdext::boolean m_audioEnabled; - std::unordered_map m_channels; -}; - -extern SoundManager g_sounds; - -#endif - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundsource.cpp b/src/framework/sound/soundsource.cpp deleted file mode 100644 index b4cb249..0000000 --- a/src/framework/sound/soundsource.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#include "soundsource.h" -#include "soundbuffer.h" - -#include - -SoundSource::SoundSource() -{ - m_sourceId = 0; - m_channel = 0; - m_fadeState = NoFading; - m_fadeTime = 0; - m_fadeStartTime = 0; - m_fadeGain = 0; - m_gain = 1.0f; - - alGenSources(1, &m_sourceId); - VALIDATE(alGetError() == AL_NO_ERROR); - setReferenceDistance(128); -} - -SoundSource::~SoundSource() -{ - if(m_sourceId != 0) { - stop(); - alDeleteSources(1, &m_sourceId); - VALIDATE(alGetError() == AL_NO_ERROR); - } -} - -void SoundSource::play() -{ - alSourcePlay(m_sourceId); - VALIDATE(alGetError() == AL_NO_ERROR); -} - -void SoundSource::stop() -{ - alSourceStop(m_sourceId); - VALIDATE(alGetError() == AL_NO_ERROR); - if(m_buffer) { - alSourcei(m_sourceId, AL_BUFFER, AL_NONE); - VALIDATE(alGetError() == AL_NO_ERROR); - m_buffer = nullptr; - } -} - -bool SoundSource::isBuffering() -{ - int state = AL_PLAYING; - alGetSourcei(m_sourceId, AL_SOURCE_STATE, &state); - return state != AL_STOPPED; -} - -void SoundSource::setBuffer(const SoundBufferPtr& buffer) -{ - alSourcei(m_sourceId, AL_BUFFER, buffer->getBufferId()); - VALIDATE(alGetError() == AL_NO_ERROR); - m_buffer = buffer; -} - -void SoundSource::setLooping(bool looping) -{ - alSourcei(m_sourceId, AL_LOOPING, looping ? AL_TRUE : AL_FALSE); -} - -void SoundSource::setRelative(bool relative) -{ - alSourcei(m_sourceId, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE); -} - -void SoundSource::setReferenceDistance(float distance) -{ - alSourcef(m_sourceId, AL_REFERENCE_DISTANCE, distance); -} - -void SoundSource::setGain(float gain) -{ - alSourcef(m_sourceId, AL_GAIN, gain); - m_gain = gain; -} - -void SoundSource::setPitch(float pitch) -{ - alSourcef(m_sourceId, AL_PITCH, pitch); -} - -void SoundSource::setPosition(const Point& pos) -{ - alSource3f(m_sourceId, AL_POSITION, pos.x, pos.y, 0); -} - -void SoundSource::setVelocity(const Point& velocity) -{ - alSource3f(m_sourceId, AL_VELOCITY, velocity.x, velocity.y, 0); -} - -void SoundSource::setFading(FadeState state, float fadeTime) -{ - float now = stdext::millis() / 1000.0f; - if(m_fadeState != NoFading) { - float elapsed = now - m_fadeStartTime; - float add; - if(m_fadeState == FadingOn) - add = -(1-(elapsed / m_fadeTime))*fadeTime; - else - add = -(elapsed / m_fadeTime)*fadeTime; - m_fadeStartTime = now + add; - } else - m_fadeStartTime = now; - - m_fadeState = state; - m_fadeTime = fadeTime; - m_fadeGain = m_gain; - - if(m_fadeState == FadingOn) - setGain(0.0); -} - -void SoundSource::update() -{ - float now = stdext::millis() / 1000.0f; - if(m_fadeState == FadingOn) { - float elapsed = now - m_fadeStartTime; - if(elapsed >= m_fadeTime) { - m_fadeState = NoFading; - } else { - setGain((elapsed / m_fadeTime) * m_fadeGain); - } - } else if(m_fadeState == FadingOff) { - float elapsed = now - m_fadeStartTime; - if(elapsed >= m_fadeTime) { - setGain(m_fadeGain); - stop(); - m_fadeState = NoFading; - } else { - setGain(((m_fadeTime - elapsed) / m_fadeTime) * m_fadeGain); - } - } -} - -#endif \ No newline at end of file diff --git a/src/framework/sound/soundsource.h b/src/framework/sound/soundsource.h deleted file mode 100644 index 4124239..0000000 --- a/src/framework/sound/soundsource.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef SOUNDSOURCE_H -#define SOUNDSOURCE_H - -#include "declarations.h" -#include "soundbuffer.h" -#include - -class SoundSource : public LuaObject -{ -protected: - SoundSource(uint sourceId) : m_sourceId(sourceId) { } - -public: - enum FadeState { NoFading, FadingOn, FadingOff }; - - SoundSource(); - virtual ~SoundSource(); - - virtual void play(); - virtual void stop(); - - virtual bool isBuffering(); - virtual bool isPlaying() { return isBuffering(); } - - void setName(const std::string& name) { m_name = name; } - virtual void setLooping(bool looping); - virtual void setRelative(bool relative); - virtual void setReferenceDistance(float distance); - virtual void setGain(float gain); - virtual void setPitch(float pitch); - virtual void setPosition(const Point& pos); - virtual void setVelocity(const Point& velocity); - virtual void setFading(FadeState state, float fadetime); - - std::string getName() { return m_name; } - uchar getChannel() { return m_channel; } - float getGain() { return m_gain; } - -protected: - void setBuffer(const SoundBufferPtr& buffer); - void setChannel(uchar channel) { m_channel = channel; } - - virtual void update(); - friend class SoundManager; - friend class CombinedSoundSource; - - uint m_sourceId; - uchar m_channel; - std::string m_name; - SoundBufferPtr m_buffer; - FadeState m_fadeState; - float m_fadeStartTime; - float m_fadeTime; - float m_fadeGain; - float m_gain; -}; - -#endif - -#endif \ No newline at end of file diff --git a/src/framework/sound/streamsoundsource.cpp b/src/framework/sound/streamsoundsource.cpp deleted file mode 100644 index 08061cc..0000000 --- a/src/framework/sound/streamsoundsource.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#include "streamsoundsource.h" -#include "soundbuffer.h" -#include "soundfile.h" - -#include -#include - -StreamSoundSource::StreamSoundSource() -{ - for(auto& buffer : m_buffers) - buffer = SoundBufferPtr(new SoundBuffer); - m_downMix = NoDownMix; -} - -StreamSoundSource::~StreamSoundSource() -{ - stop(); -} - -void StreamSoundSource::setSoundFile(const SoundFilePtr& soundFile) -{ - m_soundFile = soundFile; - if(m_waitingFile) { - m_waitingFile = false; - play(); - } -} - -void StreamSoundSource::play() -{ - m_playing = true; - - if(!m_soundFile) { - m_waitingFile = true; - return; - } - - if(m_eof) { - m_soundFile->reset(); - m_eof = false; - } - - queueBuffers(); - - SoundSource::play(); -} - -void StreamSoundSource::stop() -{ - m_playing = false; - - if(m_waitingFile) - return; - - SoundSource::stop(); - unqueueBuffers(); -} - -void StreamSoundSource::queueBuffers() -{ - int queued; - alGetSourcei(m_sourceId, AL_BUFFERS_QUEUED, &queued); - for(int i = 0; i < STREAM_FRAGMENTS - queued; ++i) { - if(!fillBufferAndQueue(m_buffers[i]->getBufferId())) - break; - } -} - -void StreamSoundSource::unqueueBuffers() -{ - int queued; - alGetSourcei(m_sourceId, AL_BUFFERS_QUEUED, &queued); - for(int i = 0; i < queued; ++i) { - uint buffer; - alSourceUnqueueBuffers(m_sourceId, 1, &buffer); - } -} - -void StreamSoundSource::update() -{ - if(m_waitingFile) - return; - - SoundSource::update(); - - int processed = 0; - alGetSourcei(m_sourceId, AL_BUFFERS_PROCESSED, &processed); - for(int i = 0; i < processed; ++i) { - uint buffer; - alSourceUnqueueBuffers(m_sourceId, 1, &buffer); - //SoundManager::check_al_error("Couldn't unqueue audio buffer: "); - - if(!fillBufferAndQueue(buffer)) - break; - } - - if(!isBuffering() && m_playing) { - if(!m_looping && m_eof) { - stop(); - } else if(processed == 0) { - g_logger.traceError("audio buffer underrun"); - play(); - } else if(m_looping) { - play(); - } - } -} - -bool StreamSoundSource::fillBufferAndQueue(uint buffer) -{ - if(m_waitingFile) - return false; - - // fill buffer - static DataBuffer bufferData(2*STREAM_FRAGMENT_SIZE); - ALenum format = m_soundFile->getSampleFormat(); - - int maxRead = STREAM_FRAGMENT_SIZE; - if(m_downMix != NoDownMix) - maxRead *= 2; - - int bytesRead = 0; - do { - bytesRead += m_soundFile->read(&bufferData[bytesRead], maxRead - bytesRead); - - // end of sound file - if(bytesRead < maxRead) { - if(m_looping) - m_soundFile->reset(); - else { - m_eof = true; - break; - } - } - } while(bytesRead < maxRead); - - if(bytesRead > 0) { - if(m_downMix != NoDownMix) { - if(format == AL_FORMAT_STEREO16) { - VALIDATE(bytesRead % 2 == 0); - bytesRead /= 2; - uint16_t *data = (uint16_t*)bufferData.data(); - for(int i=0;igetRate()); - ALenum err = alGetError(); - if(err != AL_NO_ERROR) - g_logger.error(stdext::format("unable to refill audio buffer for '%s': %s", m_soundFile->getName(), alGetString(err))); - - alSourceQueueBuffers(m_sourceId, 1, &buffer); - err = alGetError(); - if(err != AL_NO_ERROR) - g_logger.error(stdext::format("unable to queue audio buffer for '%s': %s", m_soundFile->getName(), alGetString(err))); - } - - // return false if there aren't more buffers to fill - return (bytesRead >= STREAM_FRAGMENT_SIZE && !m_eof); -} - -void StreamSoundSource::downMix(StreamSoundSource::DownMix downMix) -{ - m_downMix = downMix; -} - -#endif \ No newline at end of file diff --git a/src/framework/sound/streamsoundsource.h b/src/framework/sound/streamsoundsource.h deleted file mode 100644 index 7aa2c1f..0000000 --- a/src/framework/sound/streamsoundsource.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifdef FW_SOUND - -#ifndef STREAMSOUNDSOURCE_H -#define STREAMSOUNDSOURCE_H - -#include "soundsource.h" - -class StreamSoundSource : public SoundSource -{ - enum { - STREAM_BUFFER_SIZE = 1024 * 400, - STREAM_FRAGMENTS = 4, - STREAM_FRAGMENT_SIZE = STREAM_BUFFER_SIZE / STREAM_FRAGMENTS - }; - -public: - enum DownMix { NoDownMix, DownMixLeft, DownMixRight }; - - StreamSoundSource(); - virtual ~StreamSoundSource(); - - void play(); - void stop(); - - bool isPlaying() { return m_playing; } - - void setSoundFile(const SoundFilePtr& soundFile); - - void downMix(DownMix downMix); - - void update(); - -private: - void queueBuffers(); - void unqueueBuffers(); - bool fillBufferAndQueue(uint buffer); - - SoundFilePtr m_soundFile; - std::array m_buffers; - DownMix m_downMix; - stdext::boolean m_looping; - stdext::boolean m_playing; - stdext::boolean m_eof; - stdext::boolean m_waitingFile; -}; - -#endif - -#endif diff --git a/src/framework/stdext/any.h b/src/framework/stdext/any.h deleted file mode 100644 index 11a6a44..0000000 --- a/src/framework/stdext/any.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_ANY_H -#define STDEXT_ANY_H - -#include -#include - -namespace stdext { - -class any { -public: - struct placeholder { - virtual ~placeholder() { } - virtual const std::type_info& type() const = 0; - virtual placeholder* clone() const = 0; - }; - - template - struct holder : public placeholder { - holder(const T& value) : held(value) { } - const std::type_info& type() const { return typeid(T); } - placeholder* clone() const { return new holder(held); } - T held; - private: - holder& operator=(const holder &); - }; - - placeholder* content; - - any() : content(nullptr) { } - any(const any& other) : content(other.content ? other.content->clone() : nullptr) { } - template any(const T& value) : content(new holder(value)) { } - ~any() { if(content) delete content; } - - any& swap(any& rhs) { std::swap(content, rhs.content); return *this; } - - template any& operator=(const T& rhs) { any(rhs).swap(*this); return *this; } - any& operator=(any rhs) { rhs.swap(*this); return *this; } - - bool empty() const { return !content; } - template const T& cast() const; - const std::type_info & type() const { return content ? content->type() : typeid(void); } -}; - -template -const T& any_cast(const any& operand) { - VALIDATE(operand.type() == typeid(T)); - return static_cast*>(operand.content)->held; -} - -template const T& any::cast() const { return any_cast(*this); } - -} - -#endif diff --git a/src/framework/stdext/boolean.h b/src/framework/stdext/boolean.h deleted file mode 100644 index 5f0f981..0000000 --- a/src/framework/stdext/boolean.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef BOOLEAN_H -#define BOOLEAN_H - -namespace stdext { - -template -struct boolean { - boolean() : v(def) { } - operator bool &() { return v; } - operator bool const &() const { return v; } - bool& operator=(const bool& o) { v = o; return v; } -private: - bool v; -}; - -} - -#endif diff --git a/src/framework/stdext/cast.h b/src/framework/stdext/cast.h deleted file mode 100644 index 918d033..0000000 --- a/src/framework/stdext/cast.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_CAST_H -#define STDEXT_CAST_H - -#include "exception.h" -#include "demangle.h" - -#include -#include -#include - -namespace stdext { - -// cast a type to another type -template -bool cast(const T& in, R& out) { - std::stringstream ss; - ss << in; - ss >> out; - return !!ss && ss.eof(); -} - -// cast a type to string -template -bool cast(const T& in, std::string& out) { - std::stringstream ss; - ss << in; - out = ss.str(); - return true; -} - -// cast string to string -template<> -inline bool cast(const std::string& in, std::string& out) { - out = in; - return true; -} - -// special cast from string to boolean -template<> -inline bool cast(const std::string& in, bool& b) { - if(in == "true") - b = true; - else if(in == "false") - b = false; - else - return false; - return true; -} - -// special cast from string to char -template<> -inline bool cast(const std::string& in, char& c) { - if(in.length() != 1) - return false; - c = in[0]; - return true; -} - -// special cast from string to long -template<> -inline bool cast(const std::string& in, long& l) { - if(in.find_first_not_of("-0123456789") != std::string::npos) - return false; - std::size_t t = in.find_last_of('-'); - if(t != std::string::npos && t != 0) - return false; - l = atol(in.c_str()); - return true; -} - -// special cast from string to int -template<> -inline bool cast(const std::string& in, int& i) { - long l; - if(cast(in, l)) { - i=l; - return true; - } - return false; -} - -// special cast from string to double -template<> -inline bool cast(const std::string& in, double& d) { - if(in.find_first_not_of("-0123456789.") != std::string::npos) - return false; - std::size_t t = in.find_last_of('-'); - if(t != std::string::npos && t != 0) - return false; - t = in.find_first_of('.'); - if(t != std::string::npos && (t == 0 || t == in.length()-1 || in.find_first_of('.', t+1) != std::string::npos)) - return false; - d = atof(in.c_str()); - return true; -} - -// special cast from string to float -template<> -inline bool cast(const std::string& in, float& f) { - double d; - if(cast(in, d)) { - f=(float)d; - return true; - } - return false; -} - -// special cast from boolean to string -template<> -inline bool cast(const bool& in, std::string& out) { - out = (in ? "true" : "false"); - return true; -} - -// used by safe_cast -class cast_exception : public exception { -public: - virtual ~cast_exception() throw() { } - template - void update_what() { - std::stringstream ss; - ss << "failed to cast value of type '" << demangle_type() << "' to type '" << demangle_type() << "'"; - m_what = ss.str(); - } - virtual const char* what() const throw() { return m_what.c_str(); } -private: - std::string m_what; -}; - -// cast a type to another type, any error throws a cast_exception -template -R safe_cast(const T& t) { - R r; - if(!cast(t, r)) { - cast_exception e; - e.update_what(); - throw e; - } - return r; -} - -// cast a type to another type, cast errors are ignored -template -R unsafe_cast(const T& t, R def = R()) { - try { - return safe_cast(t); - } catch(cast_exception& e) { - std::cerr << "CAST ERROR: " << e.what() << std::endl; - return def; - } -} - -} - -#endif diff --git a/src/framework/stdext/compiler.h b/src/framework/stdext/compiler.h deleted file mode 100644 index 3e27dc1..0000000 --- a/src/framework/stdext/compiler.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_COMPILER_H -#define STDEXT_COMPILER_H - -#ifdef WIN32 -#include -#endif - -#ifdef __clang__ - // clang is supported - #define BUILD_COMPILER "clang " __VERSION__ -#elif defined(__GNUC__) - #if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) - #error "Sorry, you need gcc 4.6 or greater to compile." - #endif - #define BUILD_COMPILER "gcc " __VERSION__ -#elif defined(_MSC_VER) - #if _MSC_VER < 1800 - #error "You need Visual Studio 2013 or greater to compile." - #endif - #pragma warning(disable:4244) // conversion from 'A' to 'B', possible loss of data - #pragma warning(disable:4267) // '?' : conversion from 'A' to 'B', possible loss of data - #pragma warning(disable:4305) // 'initializing' : truncation from 'A' to 'B' - #pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned - #pragma warning(disable:4800) // 'A' : forcing value to bool 'true' or 'false' (performance warning) - - #if _MSC_VER == 1912 || _MSC_VER == 1911 || _MSC_VER == 1910 - #define BUILD_COMPILER "Visual Studio 2017" - #elif _MSC_VER == 1900 - #define BUILD_COMPILER "Visual Studio 2015" - #elif _MSC_VER == 1800 - #define BUILD_COMPILER "Visual Studio 2013" - #else - #define BUILD_COMPILER "Visual Studio" - #endif - - #define __PRETTY_FUNCTION__ __FUNCDNAME__ -#else - #error "Compiler not supported." -#endif - -/// Branch Prediction. See the GCC Manual for more information. -/// NB: These are used when speed is need most; do not use in normal -/// code, they may slow down stuff. -#if defined(__clang__) || defined(__GNUC__) -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) -#else -#define likely(x) (x) -#define unlikely(x) (x) -#endif - -#if !defined(_MSC_VER) && !defined(__GXX_EXPERIMENTAL_CXX0X__) -#error "C++0x is required to compile this application. Try updating your compiler." -#endif - -#endif diff --git a/src/framework/stdext/demangle.cpp b/src/framework/stdext/demangle.cpp deleted file mode 100644 index 59def57..0000000 --- a/src/framework/stdext/demangle.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "demangle.h" - -#ifdef _MSC_VER - -#include -#include - -#pragma warning (push) -#pragma warning (disable:4091) // warning C4091: 'typedef ': ignored on left of '' when no variable is declared -#include -#pragma warning (pop) - -#else - -#include -#include -#include - -#endif - -namespace stdext { - -const char* demangle_name(const char* name) -{ -#ifdef _MSC_VER - static char buffer[1024]; - UnDecorateSymbolName(name, buffer, sizeof(buffer), UNDNAME_COMPLETE); - return buffer; -#else - size_t len; - int status; - static char buffer[1024]; - char* demangled = abi::__cxa_demangle(name, 0, &len, &status); - if(demangled) { - strcpy(buffer, demangled); - free(demangled); - } - return buffer; -#endif -} - -} diff --git a/src/framework/stdext/demangle.h b/src/framework/stdext/demangle.h deleted file mode 100644 index 3c4ed60..0000000 --- a/src/framework/stdext/demangle.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_DEMANGLE_H -#define STDEXT_DEMANGLE_H - -#include -#include - -namespace stdext { - -/// Demangle names for GNU g++ compiler -const char* demangle_name(const char* name); - -/// Returns the name of a class -template std::string demangle_class() { -#ifdef _MSC_VER - return demangle_name(typeid(T).name()) + 6; -#else - return demangle_name(typeid(T).name()); -#endif -} - -/// Returns the name of a type -template std::string demangle_type() { return demangle_name(typeid(T).name()); } - -} - -#endif diff --git a/src/framework/stdext/dumper.h b/src/framework/stdext/dumper.h deleted file mode 100644 index 4dfc7a9..0000000 --- a/src/framework/stdext/dumper.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_DUMPER_H -#define STDEXT_DUMPER_H - -#include - -namespace stdext { - -static struct { - struct dumper_dummy { - ~dumper_dummy() { std::cout << std::endl; } - template dumper_dummy& operator<<(const T& v) { std::cout << v << " "; return *this; } - }; - template dumper_dummy operator<<(const T& v) const { dumper_dummy d; d << v; return d; } -} dump; - -} - -using stdext::dump; - -#endif diff --git a/src/framework/stdext/dynamic_storage.h b/src/framework/stdext/dynamic_storage.h deleted file mode 100644 index 8e8bff1..0000000 --- a/src/framework/stdext/dynamic_storage.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_DYNAMICSTORAGE_H -#define STDEXT_DYNAMICSTORAGE_H - -#include "types.h" -#include "any.h" -#include - -namespace stdext { - -template -class dynamic_storage { -public: - template void set(const Key& k, const T& value) { - if(m_data.size() <= k) - m_data.resize(k+1); - m_data[k] = value; - } - bool remove(const Key& k) { - if(m_data.size() < k) - return false; - if(m_data[k].empty()) - return false; - m_data[k] = any(); - return true; - } - template T get(const Key& k) const { return has(k) ? any_cast(m_data[k]) : T(); } - bool has(const Key& k) const { return k < m_data.size() && !m_data[k].empty(); } - - std::size_t size() const { - std::size_t count = 0; - for(std::size_t i=0;i m_data; -}; - -} - -#endif diff --git a/src/framework/stdext/exception.h b/src/framework/stdext/exception.h deleted file mode 100644 index 3cbd022..0000000 --- a/src/framework/stdext/exception.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_EXCEPTION_H -#define STDEXT_EXCEPTION_H - -#include -#include - -namespace stdext { - -class exception : public std::exception -{ -public: - exception() { } - exception(const std::string& what) : m_what(what) { } - virtual ~exception() throw() { }; - virtual const char* what() const throw() { return m_what.c_str(); } -protected: - std::string m_what; -}; - -/// Throws a generic exception -inline void throw_exception(const std::string& what) { throw exception(what); } - -} - -#endif diff --git a/src/framework/stdext/fastrand.h b/src/framework/stdext/fastrand.h deleted file mode 100644 index 200f119..0000000 --- a/src/framework/stdext/fastrand.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -namespace stdext { - -static int fastrand() -{ - static int g_seed = (214013 + 2531011); - g_seed = (214013 * g_seed + 2531011); - return (g_seed >> 16) & 0x7FFF; -}; - -} \ No newline at end of file diff --git a/src/framework/stdext/format.h b/src/framework/stdext/format.h deleted file mode 100644 index 2625c81..0000000 --- a/src/framework/stdext/format.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_FORMAT_H -#define STDEXT_FORMAT_H - -#include "traits.h" - -#include -#include -#include -#include -#include -#include - -namespace stdext { - -template void print_ostream(std::ostringstream& stream, const T& last) { stream << last; } -template -void print_ostream(std::ostringstream& stream, const T& first, const Args&... rest) { stream << "\t" << first; print_ostream(stream, rest...); } -template - -// Utility for printing variables just like lua -void print(const T&... args) { std::ostringstream buf; print_ostream(buf, args...); std::cout << buf.str() << std::endl; } - -template -typename std::enable_if::value || - std::is_pointer::value || - std::is_floating_point::value || - std::is_enum::value, T>::type sprintf_cast(const T& t) { return t; } -inline const char *sprintf_cast(const char *s) { return s; } -inline const char *sprintf_cast(const std::string& s) { return s.c_str(); } - -template struct expand_snprintf { - template static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) { - return expand_snprintf::call(s, maxlen, format, tuple, sprintf_cast(std::get(tuple)), args...); }}; -template<> struct expand_snprintf<0> { - template static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) { -#ifdef _MSC_VER - return _snprintf(s, maxlen, format, args...); -#else - return snprintf(s, maxlen, format, args...); -#endif - } -}; - -// Improved snprintf that accepts std::string and other types -template -int snprintf(char *s, size_t maxlen, const char *format, const Args&... args) { - std::tuple::type...> tuple(args...); - return expand_snprintf::value>::call(s, maxlen, format, tuple); -} - -template -inline int snprintf(char *s, size_t maxlen, const char *format) { - std::strncpy(s, format, maxlen); - s[maxlen-1] = 0; - return strlen(s); -} - -template -inline std::string format() { return std::string(); } - -template -inline std::string format(const std::string& format) { return format; } - -// Format strings with the sprintf style, accepting std::string and string convertible types for %s -template -std::string format(const std::string& format, const Args&... args) { - int n = snprintf(NULL, 0, format.c_str(), args...); - VALIDATE(n != -1); - std::string buffer(n + 1, '\0'); - n = snprintf(&buffer[0], buffer.size(), format.c_str(), args...); - VALIDATE(n != -1); - buffer.resize(n); - return buffer; -} - -} - -#endif diff --git a/src/framework/stdext/math.cpp b/src/framework/stdext/math.cpp deleted file mode 100644 index ffc877c..0000000 --- a/src/framework/stdext/math.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "math.h" -#include - -#ifdef _MSC_VER - #pragma warning(disable:4267) // '?' : conversion from 'A' to 'B', possible loss of data -#endif - -namespace stdext { - -uint32_t adler32(const uint8_t *buffer, size_t size) { - size_t a = 1, b = 0, tlen; - while(size > 0) { - tlen = size > 5552 ? 5552 : size; - size -= tlen; - do { - a += *buffer++; - b += a; - } while (--tlen); - - a %= 65521; - b %= 65521; - } - return (b << 16) | a; -} - -long random_range(long min, long max) -{ - static std::random_device rd; - static std::mt19937 gen(rd()); - static std::uniform_int_distribution dis(0, 2147483647); - return min + (dis(gen) % (max - min + 1)); -} - -float random_range(float min, float max) -{ - static std::random_device rd; - static std::mt19937 gen(rd()); - static std::uniform_real_distribution dis(0.0, 1.0); - return min + (max - min)*dis(gen); -} - -double round(double r) -{ - return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); -} - -} \ No newline at end of file diff --git a/src/framework/stdext/math.h b/src/framework/stdext/math.h deleted file mode 100644 index 7744eb8..0000000 --- a/src/framework/stdext/math.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_MATH_H -#define STDEXT_MATH_H - -#include -#include "types.h" - -namespace stdext { - -inline bool is_power_of_two(size_t v) { return ((v != 0) && !(v & (v - 1))); } -inline size_t to_power_of_two(size_t v) { if(v == 0) return 0; size_t r = 1; while(r < v && r != 0xffffffff) r <<= 1; return r; } - -inline uint16_t readULE16(const uchar *addr) { return (uint16_t)addr[1] << 8 | addr[0]; } -inline uint32_t readULE32(const uchar *addr) { return (uint32_t)readULE16(addr + 2) << 16 | readULE16(addr); } -inline uint64_t readULE64(const uchar *addr) { return (uint64_t)readULE32(addr + 4) << 32 | readULE32(addr); } - -inline void writeULE16(uchar *addr, uint16_t value) { addr[1] = value >> 8; addr[0] = (uint8_t)value; } -inline void writeULE32(uchar *addr, uint32_t value) { writeULE16(addr + 2, value >> 16); writeULE16(addr, (uint16_t)value); } -inline void writeULE64(uchar *addr, uint64_t value) { writeULE32(addr + 4, value >> 32); writeULE32(addr, (uint32_t)value); } - -inline int16_t readSLE16(const uchar *addr) { return (int16_t)addr[1] << 8 | addr[0]; } -inline int32_t readSLE32(const uchar *addr) { return (int32_t)readSLE16(addr + 2) << 16 | readSLE16(addr); } -inline int64_t readSLE64(const uchar *addr) { return (int64_t)readSLE32(addr + 4) << 32 | readSLE32(addr); } - -inline void writeSLE16(uchar *addr, int16_t value) { addr[1] = value >> 8; addr[0] = (int8_t)value; } -inline void writeSLE32(uchar *addr, int32_t value) { writeSLE16(addr + 2, value >> 16); writeSLE16(addr, (int16_t)value); } -inline void writeSLE64(uchar *addr, int64_t value) { writeSLE32(addr + 4, value >> 32); writeSLE32(addr, (int32_t)value); } - -uint32_t adler32(const uint8_t *buffer, size_t size); - -long random_range(long min, long max); -float random_range(float min, float max); - -double round(double r); - -template -T clamp(T x, T min, T max) { return std::max(min, std::min(x, max)); } - -} - -#endif diff --git a/src/framework/stdext/net.cpp b/src/framework/stdext/net.cpp deleted file mode 100644 index 7cb7c5b..0000000 --- a/src/framework/stdext/net.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "net.h" -#include -#include -#include - -namespace stdext { - -std::string ip_to_string(uint32 ip) -{ - ip = boost::asio::detail::socket_ops::network_to_host_long(ip); - boost::asio::ip::address_v4 address_v4 = boost::asio::ip::address_v4(ip); - return address_v4.to_string(); -} - -uint32 string_to_ip(const std::string& string) -{ - boost::asio::ip::address_v4 address_v4 = boost::asio::ip::address_v4::from_string(string); - return boost::asio::detail::socket_ops::host_to_network_long(address_v4.to_ulong()); -} - -std::vector listSubnetAddresses(uint32 address, uint8 mask) -{ - std::vector list; - if(mask < 32) { - uint32 bitmask = (0xFFFFFFFF >> mask); - for(uint32 i = 0; i <= bitmask; i++) { - uint32 ip = boost::asio::detail::socket_ops::host_to_network_long((boost::asio::detail::socket_ops::network_to_host_long(address) & (~bitmask)) | i); - if((ip >> 24) != 0 && (ip >> 24) != 0xFF) - list.push_back(ip); - } - } - else - list.push_back(address); - - return list; -} - -} diff --git a/src/framework/stdext/net.h b/src/framework/stdext/net.h deleted file mode 100644 index 2993f2b..0000000 --- a/src/framework/stdext/net.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_NET_H -#define STDEXT_NET_H - -#include "types.h" -#include -#include - -namespace stdext { - std::string ip_to_string(uint32 ip); - uint32 string_to_ip(const std::string& string); - std::vector listSubnetAddresses(uint32 address, uint8 mask); -} - -#endif diff --git a/src/framework/stdext/packed_any.h b/src/framework/stdext/packed_any.h deleted file mode 100644 index 28802a8..0000000 --- a/src/framework/stdext/packed_any.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_PACKEDANY_H -#define STDEXT_PACKEDANY_H - -#include -#include -#include -#include - -namespace stdext { - -// disable memory alignment -#pragma pack(push,1) - -template -struct can_pack_in_any : std::integral_constant::value)> {}; - -// improved to use less memory -class packed_any { -public: - struct placeholder { - virtual ~placeholder() { } - virtual const std::type_info& type() const = 0; - virtual placeholder* clone() const = 0; - }; - - template - struct holder : public placeholder { - holder(const T& value) : held(value) { } - const std::type_info& type() const { return typeid(T); } - placeholder* clone() const { return new holder(held); } - T held; - private: - holder& operator=(const holder &); - }; - - placeholder* content; - bool scalar; - - packed_any() : - content(nullptr), scalar(false) { } - packed_any(const packed_any& other) : - content(!other.scalar && other.content ? other.content->clone() : other.content), - scalar(other.scalar) { } - template - packed_any(const T& value, typename std::enable_if<(can_pack_in_any::value)>::type* = nullptr) : - content(reinterpret_cast(static_cast(value))), scalar(true) { } - template - packed_any(const T& value, typename std::enable_if::value)>::type* = nullptr) : - content(new holder(value)), scalar(false) { } - ~packed_any() - { if(!scalar && content) delete content; } - - packed_any& swap(packed_any& rhs) { std::swap(content, rhs.content); std::swap(scalar, rhs.scalar); return *this; } - - template packed_any& operator=(const T& rhs) { packed_any(rhs).swap(*this); return *this; } - packed_any& operator=(packed_any rhs) { rhs.swap(*this); return *this; } - - bool empty() const { return !scalar && !content; } - template T cast() const; - const std::type_info& type() const { - if(!scalar) - return content ? content->type() : typeid(void); - else - return typeid(std::size_t); - } -}; - -template -typename std::enable_if::value, T>::type -packed_any_cast(const packed_any& operand) { - VALIDATE(operand.scalar); - union { - T v; - packed_any::placeholder* content; - }; - content = operand.content; - return v; -} - -template -typename std::enable_if::value, T>::type -packed_any_cast(const packed_any& operand) { - VALIDATE(operand.type() == typeid(T)); - return static_cast*>(operand.content)->held; -} - -template T packed_any::cast() const { return packed_any_cast(*this); } - -// restore memory alignment -#pragma pack(pop) - -} - -#endif diff --git a/src/framework/stdext/packed_storage.h b/src/framework/stdext/packed_storage.h deleted file mode 100644 index 38b26d2..0000000 --- a/src/framework/stdext/packed_storage.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_PACKEDSTORAGE_H -#define STDEXT_PACKEDSTORAGE_H - -#include "types.h" -#include "packed_any.h" - -namespace stdext { - -// disable memory alignment -#pragma pack(push,1) - -// this class was designed to use less memory as possible -template -class packed_storage { - struct value_pair { - Key id; - packed_any value; - }; - -public: - packed_storage() : m_values(nullptr), m_size(0) { } - ~packed_storage() { if(m_values) delete[] m_values; } - - template - void set(Key id, const T& value) { - for(SizeType i=0;i 0) { - std::copy(m_values, m_values + m_size, tmp); - delete[] m_values; - } - m_values = tmp; - m_values[m_size++] = { id, packed_any(value) }; - } - - bool remove(Key id) { - auto begin = m_values; - auto end = m_values + m_size; - auto it = std::find_if(begin, end, [=](const value_pair& pair) -> bool { return pair.id == id; } ); - if(it == end) - return false; - int pos = it - begin; - auto tmp = new value_pair[m_size-1]; - std::copy(begin, begin + pos, tmp); - std::copy(begin + pos + 1, end, tmp + pos); - delete[] m_values; - m_values = tmp; - m_size--; - return true; - } - - template - T get(Key id) const { - for(SizeType i=0;i(m_values[i].value); - return T(); - } - - bool has(Key id) const { - for(SizeType i=0;i - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_SHARED_OBJECT_H -#define STDEXT_SHARED_OBJECT_H - -#include "types.h" -#include -#include -#include -#include - -namespace stdext { - -template -class shared_object_ptr; - -class shared_object -{ -public: - shared_object() : refs(0) { } - virtual ~shared_object() { } - void add_ref() { ++refs; } - void dec_ref() { if(--refs == 0) delete this; } - refcount_t ref_count() { return refs; } - - template stdext::shared_object_ptr static_self_cast() { return stdext::shared_object_ptr(static_cast(this)); } - template stdext::shared_object_ptr dynamic_self_cast() { return stdext::shared_object_ptr(dynamic_cast(this)); } - template stdext::shared_object_ptr const_self_cast() { return stdext::shared_object_ptr(const_cast(this)); } - -private: - std::atomic refs; -}; - -template -class shared_object_ptr -{ -public: - typedef T element_type; - - shared_object_ptr(): px(nullptr) { } - shared_object_ptr(T* p, bool add_ref = true) : px(p) { - static_assert(std::is_base_of::value, "classes using shared_object_ptr must be a derived of stdext::shared_object"); - if(px != nullptr && add_ref) - this->add_ref(); - } - shared_object_ptr(shared_object_ptr const& rhs): px(rhs.px) { if(px != nullptr) add_ref(); } - template - shared_object_ptr(shared_object_ptr const& rhs, typename std::enable_if::value, U*>::type = nullptr) : px(rhs.get()) { if(px != nullptr) add_ref(); } - ~shared_object_ptr() { if(px != nullptr) dec_ref(); } - - void reset() { shared_object_ptr().swap(*this); } - void reset(T* rhs) { shared_object_ptr(rhs).swap(*this); } - void swap(shared_object_ptr& rhs) { std::swap(px, rhs.px); } - T* get() const { return px; } - - refcount_t use_count() const { return ((shared_object*)px)->ref_count(); } - bool is_unique() const { return use_count() == 1; } - - template shared_object_ptr& operator=(shared_object_ptr const& rhs) { shared_object_ptr(rhs).swap(*this); return *this; } - - T& operator*() const { VALIDATE(px != nullptr); return *px; } - T* operator->() const { VALIDATE(px != nullptr); return px; } - - shared_object_ptr& operator=(shared_object_ptr const& rhs) { shared_object_ptr(rhs).swap(*this); return *this; } - shared_object_ptr& operator=(T* rhs) { shared_object_ptr(rhs).swap(*this); return *this; } - - // implicit conversion to bool - typedef T* shared_object_ptr::*unspecified_bool_type; - operator unspecified_bool_type() const { return px == nullptr ? nullptr : &shared_object_ptr::px; } - bool operator!() const { return px == nullptr; } - - // std::move support - shared_object_ptr(shared_object_ptr&& rhs): px(rhs.px) { rhs.px = nullptr; } - shared_object_ptr& operator=(shared_object_ptr&& rhs) { shared_object_ptr(static_cast(rhs)).swap(*this); return *this; } - -private: - void add_ref() { ((shared_object*)px)->add_ref(); } - void dec_ref() { ((shared_object*)px)->dec_ref(); } - - T* px; -}; - -template bool operator==(shared_object_ptr const& a, shared_object_ptr const& b) { return a.get() == b.get(); } -template bool operator!=(shared_object_ptr const& a, shared_object_ptr const& b) { return a.get() != b.get(); } -template bool operator==(shared_object_ptr const& a, U* b) { return a.get() == b; } -template bool operator!=(shared_object_ptr const& a, U* b) { return a.get() != b; } -template bool operator==(T * a, shared_object_ptr const& b) { return a == b.get(); } -template bool operator!=(T * a, shared_object_ptr const& b) { return a != b.get(); } -template bool operator<(shared_object_ptr const& a, shared_object_ptr const& b) { return std::less()(a.get(), b.get()); } - -template T* get_pointer(shared_object_ptr const& p) { return p.get(); } -template shared_object_ptr static_pointer_cast(shared_object_ptr const& p) { return static_cast(p.get()); } -template shared_object_ptr const_pointer_cast(shared_object_ptr const& p) { return const_cast(p.get()); } -template shared_object_ptr dynamic_pointer_cast(shared_object_ptr const& p) { return dynamic_cast(p.get()); } -template stdext::shared_object_ptr make_shared_object(Args... args) { return stdext::shared_object_ptr(new T(args...)); } - -// operator<< support -template std::basic_ostream& operator<<(std::basic_ostream& os, shared_object_ptr const& p) { os << p.get(); return os; } - -} - -namespace std { - -// hash, for unordered_map support -template struct hash> { size_t operator()(const stdext::shared_object_ptr& p) const { return std::hash()(p.get()); } }; - -// swap support -template void swap(stdext::shared_object_ptr& lhs, stdext::shared_object_ptr& rhs) { lhs.swap(rhs); } - -} - -#endif diff --git a/src/framework/stdext/stdext.h b/src/framework/stdext/stdext.h deleted file mode 100644 index 5e4d1e4..0000000 --- a/src/framework/stdext/stdext.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_H -#define STDEXT_H - -#include "compiler.h" -#include "dumper.h" -#include "types.h" -#include "exception.h" -#include "demangle.h" -#include "cast.h" -#include "math.h" -#include "string.h" -#include "time.h" -#include "boolean.h" -#include "shared_object.h" -#include "any.h" -#include "packed_any.h" -#include "dynamic_storage.h" -#include "packed_storage.h" -#include "format.h" - -#endif diff --git a/src/framework/stdext/string.cpp b/src/framework/stdext/string.cpp deleted file mode 100644 index f50b69d..0000000 --- a/src/framework/stdext/string.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "string.h" -#include "format.h" -#include -#include -#include - -#ifdef _MSC_VER - #pragma warning(disable:4267) // '?' : conversion from 'A' to 'B', possible loss of data -#endif - -namespace stdext { - -std::string resolve_path(const std::string& filePath, std::string sourcePath) -{ - if (filePath.empty()) - return ""; - if(stdext::starts_with(filePath, "/")) - return filePath; - if(!stdext::ends_with(sourcePath, "/")) { - std::size_t slashPos = sourcePath.find_last_of("/"); - if(slashPos == std::string::npos) - throw_exception(format("invalid source path '%s', for file '%s'", sourcePath, filePath)); - sourcePath = sourcePath.substr(0, slashPos + 1); - } - return sourcePath + filePath; -} - -std::string date_time_string() -{ - char date[32]; - std::time_t tnow; - std::time(&tnow); - std::tm* ts = std::localtime(&tnow); - std::strftime(date, 32, "%b %d %Y %H:%M:%S", ts); - return std::string(date); -} - -std::string timestamp_to_date(time_t tnow) -{ - char date[32]; - std::tm* ts = std::localtime(&tnow); - std::strftime(date, 32, "%b %d %Y %H:%M:%S", ts); - return std::string(date); -} - -std::string dec_to_hex(uint32_t num) -{ - std::string str; - std::ostringstream o; - o << std::setw(8) << std::setfill('0') << std::hex << num; - str = o.str(); - return str; -} - -std::string dec_to_hex(uint64_t num) -{ - std::string str; - std::ostringstream o; - o << std::setw(16) << std::setfill('0') << std::hex << num; - str = o.str(); - return str; -} - -uint64_t hex_to_dec(const std::string& str) -{ - uint64_t num; - std::istringstream i(str); - i >> std::hex >> num; - return num; -} - -bool is_valid_utf8(const std::string& src) -{ - const unsigned char *bytes = (const unsigned char *)src.c_str(); - while(*bytes) { - if( (// ASCII - // use bytes[0] <= 0x7F to allow ASCII control characters - bytes[0] == 0x09 || - bytes[0] == 0x0A || - bytes[0] == 0x0D || - (0x20 <= bytes[0] && bytes[0] <= 0x7E) - ) - ) { - bytes += 1; - continue; - } - if( (// non-overlong 2-byte - (0xC2 <= bytes[0] && bytes[0] <= 0xDF) && - (0x80 <= bytes[1] && bytes[1] <= 0xBF) - ) - ) { - bytes += 2; - continue; - } - if( (// excluding overlongs - bytes[0] == 0xE0 && - (0xA0 <= bytes[1] && bytes[1] <= 0xBF) && - (0x80 <= bytes[2] && bytes[2] <= 0xBF) - ) || - (// straight 3-byte - ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) || - bytes[0] == 0xEE || - bytes[0] == 0xEF) && - (0x80 <= bytes[1] && bytes[1] <= 0xBF) && - (0x80 <= bytes[2] && bytes[2] <= 0xBF) - ) || - (// excluding surrogates - bytes[0] == 0xED && - (0x80 <= bytes[1] && bytes[1] <= 0x9F) && - (0x80 <= bytes[2] && bytes[2] <= 0xBF) - ) - ) { - bytes += 3; - continue; - } - if( (// planes 1-3 - bytes[0] == 0xF0 && - (0x90 <= bytes[1] && bytes[1] <= 0xBF) && - (0x80 <= bytes[2] && bytes[2] <= 0xBF) && - (0x80 <= bytes[3] && bytes[3] <= 0xBF) - ) || - (// planes 4-15 - (0xF1 <= bytes[0] && bytes[0] <= 0xF3) && - (0x80 <= bytes[1] && bytes[1] <= 0xBF) && - (0x80 <= bytes[2] && bytes[2] <= 0xBF) && - (0x80 <= bytes[3] && bytes[3] <= 0xBF) - ) || - (// plane 16 - bytes[0] == 0xF4 && - (0x80 <= bytes[1] && bytes[1] <= 0x8F) && - (0x80 <= bytes[2] && bytes[2] <= 0xBF) && - (0x80 <= bytes[3] && bytes[3] <= 0xBF) - ) - ) { - bytes += 4; - continue; - } - return false; - } - return true; -} - -std::string utf8_to_latin1(const std::string& src) -{ - std::string out; - for(uint i=0;i= 32 && c < 128) || c == 0x0d || c == 0x0a || c == 0x09) - out += c; - else if(c == 0xc2 || c == 0xc3) { - uchar c2 = src[i++]; - if(c == 0xc2) { - if(c2 > 0xa1 && c2 < 0xbb) - out += c2; - } else if(c == 0xc3) - out += 64 + c2; - } else if(c >= 0xc4 && c <= 0xdf) - i += 1; - else if(c >= 0xe0 && c <= 0xed) - i += 2; - else if(c >= 0xf0 && c <= 0xf4) - i += 3; - } - return out; -} - -std::string latin1_to_utf8(const std::string& src) -{ - std::string out; - for(uchar c : src) { - if((c >= 32 && c < 128) || c == 0x0d || c == 0x0a || c == 0x09) - out += c; - else { - out += 0xc2 + (c > 0xbf); - out += 0x80 + (c & 0x3f); - } - } - return out; -} - -#ifdef WIN32 -#include -#include -std::wstring utf8_to_utf16(const std::string& src) -{ - std::wstring res; - wchar_t out[65536]; - if(MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, out, 65536)) - res = out; - return res; -} - -std::string utf16_to_utf8(const std::wstring& src) -{ - std::string res; - char out[65536]; - if(WideCharToMultiByte(CP_UTF8, 0, src.c_str(), -1, out, 65536, NULL, NULL)) - res = out; - return res; -} - -std::wstring latin1_to_utf16(const std::string& src) -{ - return utf8_to_utf16(latin1_to_utf8(src)); -} - -std::string utf16_to_latin1(const std::wstring& src) -{ - return utf8_to_latin1(utf16_to_utf8(src)); -} -#endif - -void tolower(std::string& str) -{ - std::transform(str.begin(), str.end(), str.begin(), lochar); -} - -void toupper(std::string& str) -{ - std::transform(str.begin(), str.end(), str.begin(), upchar); -} - -void trim(std::string& str) -{ - boost::trim(str); -} - -char upchar(char c) -{ - if((c >= 97 && c <= 122) || (uchar)c >= 224) - c -= 32; - return c; -} - -char lochar(char c) -{ - if((c >= 65 && c <= 90) || ((uchar)c >= 192 && (uchar)c <= 223)) - c += 32; - return c; -} - -void ucwords(std::string& str) -{ - uint32 strLen = str.length(); - if(strLen == 0) - return; - - str[0] = upchar(str[0]); - for(uint32 i = 1; i < strLen; ++i) { - if(str[i - 1] == ' ') - str[i] = upchar(str[i]); - } -} - -bool ends_with(const std::string& str, const std::string& test) -{ - return boost::ends_with(str, test); -} - -bool starts_with(const std::string& str, const std::string& test) -{ - return boost::starts_with(str, test); -} - -void replace_all(std::string& str, const std::string& search, const std::string& replacement) -{ - return boost::replace_all(str, search, replacement); -} - -std::vector split(const std::string& str, const std::string& separators) -{ - std::vector splitted; - boost::split(splitted, str, boost::is_any_of(std::string(separators))); - return splitted; -} - -} diff --git a/src/framework/stdext/string.h b/src/framework/stdext/string.h deleted file mode 100644 index 250a4a4..0000000 --- a/src/framework/stdext/string.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_STRING_H -#define STDEXT_STRING_H - -#include -#include -#include - -#include "types.h" -#include "cast.h" - -namespace stdext { - -template std::string to_string(const T& t) { return unsafe_cast(t); } -template T from_string(const std::string& str, T def = T()) { return unsafe_cast(str, def); } - -/// Resolve a file path by combining sourcePath with filePath -std::string resolve_path(const std::string& filePath, std::string sourcePath); -/// Get current date and time in a std::string -std::string date_time_string(); -std::string timestamp_to_date(time_t tnow); - -std::string dec_to_hex(uint32_t num); -std::string dec_to_hex(uint64_t num); -uint64_t hex_to_dec(const std::string& str); -void tolower(std::string& str); -void toupper(std::string& str); -void trim(std::string& str); -void ucwords(std::string& str); -char upchar(char c); -char lochar(char c); -bool ends_with(const std::string& str, const std::string& test); -bool starts_with(const std::string& str, const std::string& test); -void replace_all(std::string& str, const std::string& search, const std::string& replacement); - -bool is_valid_utf8(const std::string& src); -std::string utf8_to_latin1(const std::string& src); -std::string latin1_to_utf8(const std::string& src); - -#ifdef WIN32 -std::wstring utf8_to_utf16(const std::string& src); -std::string utf16_to_utf8(const std::wstring& src); -std::string utf16_to_latin1(const std::wstring& src); -std::wstring latin1_to_utf16(const std::string& src); -#endif - -std::vector split(const std::string& str, const std::string& separators = " "); -template std::vector split(const std::string& str, const std::string& separators = " ") { - std::vector splitted = split(str, separators); - std::vector results(splitted.size()); - for(uint i=0;i(splitted[i]); - return results; -} - -} - -#endif diff --git a/src/framework/stdext/thread.h b/src/framework/stdext/thread.h deleted file mode 100644 index 1d4b415..0000000 --- a/src/framework/stdext/thread.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef THREAD_H -#define THREAD_H - -#include -#include -#include - -#endif - diff --git a/src/framework/stdext/time.cpp b/src/framework/stdext/time.cpp deleted file mode 100644 index 8c0462b..0000000 --- a/src/framework/stdext/time.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "time.h" -#include -#include -#include - -namespace stdext { - -const static auto startup_time = std::chrono::high_resolution_clock::now(); - -ticks_t time() { - return std::time(NULL); -} - -ticks_t millis() -{ - return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - startup_time).count(); -} - -ticks_t micros() { - return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - startup_time).count(); -} - -void millisleep(size_t ms) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(ms)); -}; - -void microsleep(size_t us) -{ - std::this_thread::sleep_for(std::chrono::microseconds(us)); -}; - -} diff --git a/src/framework/stdext/time.h b/src/framework/stdext/time.h deleted file mode 100644 index 3451d04..0000000 --- a/src/framework/stdext/time.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_TIME_H -#define STDEXT_TIME_H - -#include "types.h" - -namespace stdext { - -ticks_t time(); -ticks_t millis(); -ticks_t micros(); -void millisleep(size_t ms); -void microsleep(size_t us); - -struct timer { -public: - timer() { restart(); } - float elapsed_seconds() { return (float)((stdext::micros() - m_start)/1000000.0); } - ticks_t elapsed_millis() { return (stdext::micros() - m_start)/1000; } - ticks_t elapsed_micros() { return stdext::micros() - m_start; } - void restart(int shift = 0) { m_start = stdext::micros() - shift; } -private: - ticks_t m_start; -}; - -} - -#endif - diff --git a/src/framework/stdext/traits.h b/src/framework/stdext/traits.h deleted file mode 100644 index 5e896b3..0000000 --- a/src/framework/stdext/traits.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_TRAITS_H -#define STDEXT_TRAITS_H - -#include - -namespace stdext { - -template struct replace_extent { typedef T type; }; -template struct replace_extent { typedef const T* type; }; -template struct replace_extent { typedef const T* type;}; -template struct remove_const_ref { typedef typename std::remove_const::type>::type type; }; - -}; - -#endif diff --git a/src/framework/stdext/types.h b/src/framework/stdext/types.h deleted file mode 100644 index e258170..0000000 --- a/src/framework/stdext/types.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STDEXT_TYPES_H -#define STDEXT_TYPES_H - -#include -#include - -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; - -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint8_t uint8; -typedef int64_t int64; -typedef int32_t int32; -typedef int16_t int16; -typedef int8_t int8; - -typedef int64 ticks_t; -typedef uint_fast32_t refcount_t; - -using std::size_t; -using std::ptrdiff_t; - -#endif diff --git a/src/framework/stdext/uri.cpp b/src/framework/stdext/uri.cpp deleted file mode 100644 index d89dee3..0000000 --- a/src/framework/stdext/uri.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -#include "uri.h" - -ParsedURI parseURI(const std::string& url) -{ - ParsedURI result; - auto value_or = [](const std::string& value, std::string&& deflt) -> std::string { - return (value.empty() ? deflt : value); - }; - // Note: only "http", "https", "ws", and "wss" protocols are supported - static const std::regex PARSE_URL{ R"((([httpsw]{2,5})://)?([^/ :]+)(:(\d+))?(/(.+)?))", - std::regex_constants::ECMAScript | std::regex_constants::icase }; - std::smatch match; - if (std::regex_match(url, match, PARSE_URL) && match.size() == 8) { - result.protocol = value_or(boost::algorithm::to_lower_copy(std::string(match[2])), "http"); - result.domain = match[3]; - const bool is_sequre_protocol = (result.protocol == "https" || result.protocol == "wss"); - result.port = value_or(match[5], (is_sequre_protocol) ? "443" : "80"); - result.query = value_or(match[6], "/"); - } - return result; -} \ No newline at end of file diff --git a/src/framework/stdext/uri.h b/src/framework/stdext/uri.h deleted file mode 100644 index 5363499..0000000 --- a/src/framework/stdext/uri.h +++ /dev/null @@ -1,10 +0,0 @@ -#include - -struct ParsedURI { - std::string protocol; - std::string domain; // only domain must be present - std::string port; - std::string query; // everything after '?', possibly nothing -}; - -ParsedURI parseURI(const std::string& url); \ No newline at end of file diff --git a/src/framework/ui/declarations.h b/src/framework/ui/declarations.h deleted file mode 100644 index 281999a..0000000 --- a/src/framework/ui/declarations.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef FRAMEWORK_UI_DECLARATIONS_H -#define FRAMEWORK_UI_DECLARATIONS_H - -#include - -class UIManager; -class UIWidget; -class UITextEdit; -class UILayout; -class UIBoxLayout; -class UIHorizontalLayout; -class UIVerticalLayout; -class UIGridLayout; -class UIAnchor; -class UIAnchorGroup; -class UIAnchorLayout; - -typedef stdext::shared_object_ptr UIWidgetPtr; -typedef stdext::shared_object_ptr UITextEditPtr; -typedef stdext::shared_object_ptr UILayoutPtr; -typedef stdext::shared_object_ptr UIBoxLayoutPtr; -typedef stdext::shared_object_ptr UIHorizontalLayoutPtr; -typedef stdext::shared_object_ptr UIVerticalLayoutPtr; -typedef stdext::shared_object_ptr UIGridLayoutPtr; -typedef stdext::shared_object_ptr UIAnchorPtr; -typedef stdext::shared_object_ptr UIAnchorGroupPtr; -typedef stdext::shared_object_ptr UIAnchorLayoutPtr; - -typedef std::deque UIWidgetList; -typedef std::vector UIAnchorList; - -#endif diff --git a/src/framework/ui/ui.h b/src/framework/ui/ui.h deleted file mode 100644 index e6d4748..0000000 --- a/src/framework/ui/ui.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UI_H -#define UI_H - -#include "uimanager.h" -#include "uiwidget.h" -#include "uitextedit.h" -#include "uilayout.h" -#include "uihorizontallayout.h" -#include "uiverticallayout.h" -#include "uigridlayout.h" -#include "uianchorlayout.h" - -#endif diff --git a/src/framework/ui/uianchorlayout.cpp b/src/framework/ui/uianchorlayout.cpp deleted file mode 100644 index d9dac12..0000000 --- a/src/framework/ui/uianchorlayout.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uianchorlayout.h" -#include "uiwidget.h" - -UIWidgetPtr UIAnchor::getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget) -{ - // determine hooked widget - UIWidgetPtr hookedWidget; - if(parentWidget) { - if(m_hookedWidgetId == "parent") - hookedWidget = parentWidget; - else if(m_hookedWidgetId == "next") - hookedWidget = parentWidget->getChildAfter(widget); - else if(m_hookedWidgetId == "prev") - hookedWidget = parentWidget->getChildBefore(widget); - else - hookedWidget = parentWidget->getChildById(m_hookedWidgetId); - } - return hookedWidget; -} - -int UIAnchor::getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget) -{ - // determine hooked widget edge point - Rect hookedWidgetRect = hookedWidget->getRect(); - if(hookedWidget == parentWidget) - hookedWidgetRect = parentWidget->getPaddingRect(); - - int point = 0; - switch(m_hookedEdge) { - case Fw::AnchorLeft: - point = hookedWidgetRect.left(); - break; - case Fw::AnchorRight: - point = hookedWidgetRect.right(); - break; - case Fw::AnchorTop: - point = hookedWidgetRect.top(); - break; - case Fw::AnchorBottom: - point = hookedWidgetRect.bottom(); - break; - case Fw::AnchorHorizontalCenter: - point = hookedWidgetRect.horizontalCenter(); - break; - case Fw::AnchorVerticalCenter: - point = hookedWidgetRect.verticalCenter(); - break; - default: - // must never happens - VALIDATE(false); - break; - } - - if(hookedWidget == parentWidget) { - switch(m_hookedEdge) { - case Fw::AnchorLeft: - case Fw::AnchorRight: - case Fw::AnchorHorizontalCenter: - point -= parentWidget->getVirtualOffset().x; - break; - case Fw::AnchorBottom: - case Fw::AnchorTop: - case Fw::AnchorVerticalCenter: - point -= parentWidget->getVirtualOffset().y; - break; - default: - break; - } - } - - return point; -} - -void UIAnchorGroup::addAnchor(const UIAnchorPtr& anchor) -{ - // duplicated anchors must be replaced - for(UIAnchorPtr& other : m_anchors) { - if(other->getAnchoredEdge() == anchor->getAnchoredEdge()) { - other = anchor; - return; - } - } - m_anchors.push_back(anchor); -} - -void UIAnchorLayout::addAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, - const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge) -{ - if(!anchoredWidget) - return; - - VALIDATE(anchoredWidget != getParentWidget()); - - UIAnchorPtr anchor(new UIAnchor(anchoredEdge, hookedWidgetId, hookedEdge)); - UIAnchorGroupPtr& anchorGroup = m_anchorsGroups[anchoredWidget]; - if(!anchorGroup) - anchorGroup = UIAnchorGroupPtr(new UIAnchorGroup); - - anchorGroup->addAnchor(anchor); - - // layout must be updated because a new anchor got in - update(); -} - -void UIAnchorLayout::removeAnchors(const UIWidgetPtr& anchoredWidget) -{ - m_anchorsGroups.erase(anchoredWidget); - update(); -} - -bool UIAnchorLayout::hasAnchors(const UIWidgetPtr& anchoredWidget) -{ - return m_anchorsGroups.find(anchoredWidget) != m_anchorsGroups.end(); -} - -void UIAnchorLayout::centerIn(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId) -{ - addAnchor(anchoredWidget, Fw::AnchorHorizontalCenter, hookedWidgetId, Fw::AnchorHorizontalCenter); - addAnchor(anchoredWidget, Fw::AnchorVerticalCenter, hookedWidgetId, Fw::AnchorVerticalCenter); -} - -void UIAnchorLayout::fill(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId) -{ - addAnchor(anchoredWidget, Fw::AnchorLeft, hookedWidgetId, Fw::AnchorLeft); - addAnchor(anchoredWidget, Fw::AnchorRight, hookedWidgetId, Fw::AnchorRight); - addAnchor(anchoredWidget, Fw::AnchorTop, hookedWidgetId, Fw::AnchorTop); - addAnchor(anchoredWidget, Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom); -} - -void UIAnchorLayout::addWidget(const UIWidgetPtr& widget) -{ - update(); -} - -void UIAnchorLayout::removeWidget(const UIWidgetPtr& widget) -{ - removeAnchors(widget); -} - -bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, const UIAnchorGroupPtr& anchorGroup, UIWidgetPtr first) -{ - UIWidgetPtr parentWidget = getParentWidget(); - if(!parentWidget) - return false; - - if(first == widget) { - g_logger.error(stdext::format("child '%s' of parent widget '%s' is recursively anchored to itself, please fix this", widget->getId(), parentWidget->getId())); - return false; - } - - if(!first) - first = widget; - - Rect newRect = widget->getRect(); - bool verticalMoved = false; - bool horizontalMoved = false; - - // calculates new rect based on anchors - for(const UIAnchorPtr& anchor : anchorGroup->getAnchors()) { - // skip invalid anchors - if(anchor->getHookedEdge() == Fw::AnchorNone) - continue; - - // determine hooked widget - UIWidgetPtr hookedWidget = anchor->getHookedWidget(widget, parentWidget); - - // skip invalid anchors - if(!hookedWidget) - continue; - - if(hookedWidget != getParentWidget()) { - // update this hooked widget anchors - auto it = m_anchorsGroups.find(hookedWidget); - if(it != m_anchorsGroups.end()) { - const UIAnchorGroupPtr& hookedAnchorGroup = it->second; - if(!hookedAnchorGroup->isUpdated()) - updateWidget(hookedWidget, hookedAnchorGroup, first); - } - } - - int point = anchor->getHookedPoint(hookedWidget, parentWidget); - - switch(anchor->getAnchoredEdge()) { - case Fw::AnchorHorizontalCenter: - newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight()); - horizontalMoved = true; - break; - case Fw::AnchorLeft: - if(!horizontalMoved) { - newRect.moveLeft(point + widget->getMarginLeft()); - horizontalMoved = true; - } else - newRect.setLeft(point + widget->getMarginLeft()); - break; - case Fw::AnchorRight: - if(!horizontalMoved) { - newRect.moveRight(point - widget->getMarginRight()); - horizontalMoved = true; - } else - newRect.setRight(point - widget->getMarginRight()); - break; - case Fw::AnchorVerticalCenter: - newRect.moveVerticalCenter(point + widget->getMarginTop() - widget->getMarginBottom()); - verticalMoved = true; - break; - case Fw::AnchorTop: - if(!verticalMoved) { - newRect.moveTop(point + widget->getMarginTop()); - verticalMoved = true; - } else - newRect.setTop(point + widget->getMarginTop()); - break; - case Fw::AnchorBottom: - if(!verticalMoved) { - newRect.moveBottom(point - widget->getMarginBottom()); - verticalMoved = true; - } else - newRect.setBottom(point - widget->getMarginBottom()); - break; - default: - break; - } - } - - bool changed = false; - if(widget->setRect(newRect)) - changed = true; - anchorGroup->setUpdated(true); - return changed; -} - -bool UIAnchorLayout::internalUpdate() -{ - bool changed = false; - - // reset all anchors groups update state - for(auto& it : m_anchorsGroups) { - const UIAnchorGroupPtr& anchorGroup = it.second; - anchorGroup->setUpdated(false); - } - - // update all anchors - for(auto& it : m_anchorsGroups) { - const UIWidgetPtr& widget = it.first; - const UIAnchorGroupPtr& anchorGroup = it.second; - if(!anchorGroup->isUpdated()) { - if(updateWidget(widget, anchorGroup)) - changed = true; - } - } - - return changed; -} diff --git a/src/framework/ui/uianchorlayout.h b/src/framework/ui/uianchorlayout.h deleted file mode 100644 index b129232..0000000 --- a/src/framework/ui/uianchorlayout.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIANCHORLAYOUT_H -#define UIANCHORLAYOUT_H - -#include "uilayout.h" - -class UIAnchor : public stdext::shared_object -{ -public: - UIAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge) : - m_anchoredEdge(anchoredEdge), m_hookedEdge(hookedEdge), m_hookedWidgetId(hookedWidgetId) { } - - Fw::AnchorEdge getAnchoredEdge() const { return m_anchoredEdge; } - Fw::AnchorEdge getHookedEdge() const { return m_hookedEdge; } - - virtual UIWidgetPtr getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget); - virtual int getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget); - -protected: - Fw::AnchorEdge m_anchoredEdge; - Fw::AnchorEdge m_hookedEdge; - std::string m_hookedWidgetId; -}; - -class UIAnchorGroup : public stdext::shared_object -{ -public: - UIAnchorGroup() : m_updated(true) { } - - void addAnchor(const UIAnchorPtr& anchor); - const UIAnchorList& getAnchors() { return m_anchors; } - bool isUpdated() { return m_updated; } - void setUpdated(bool updated) { m_updated = updated; } - -private: - UIAnchorList m_anchors; - bool m_updated; -}; - -// @bindclass -class UIAnchorLayout : public UILayout -{ -public: - UIAnchorLayout(UIWidgetPtr parentWidget) : UILayout(parentWidget) { } - - void addAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, - const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge); - void removeAnchors(const UIWidgetPtr& anchoredWidget); - bool hasAnchors(const UIWidgetPtr& anchoredWidget); - void centerIn(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId); - void fill(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId); - - void addWidget(const UIWidgetPtr& widget); - void removeWidget(const UIWidgetPtr& widget); - - bool isUIAnchorLayout() { return true; } - -protected: - virtual bool internalUpdate(); - virtual bool updateWidget(const UIWidgetPtr& widget, const UIAnchorGroupPtr& anchorGroup, UIWidgetPtr first = nullptr); - std::unordered_map m_anchorsGroups; -}; - -#endif diff --git a/src/framework/ui/uiboxlayout.cpp b/src/framework/ui/uiboxlayout.cpp deleted file mode 100644 index b64f7b8..0000000 --- a/src/framework/ui/uiboxlayout.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiboxlayout.h" -#include "uiwidget.h" - -UIBoxLayout::UIBoxLayout(UIWidgetPtr parentWidget) : UILayout(parentWidget) -{ - m_spacing = 0; -} - -void UIBoxLayout::applyStyle(const OTMLNodePtr& styleNode) -{ - UILayout::applyStyle(styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "spacing") - setSpacing(node->value()); - else if(node->tag() == "fit-children") - setFitChildren(node->value()); - } -} - diff --git a/src/framework/ui/uiboxlayout.h b/src/framework/ui/uiboxlayout.h deleted file mode 100644 index 1fb93c6..0000000 --- a/src/framework/ui/uiboxlayout.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIBOXLAYOUT_H -#define UIBOXLAYOUT_H - -#include "uilayout.h" - -// @bindclass -class UIBoxLayout : public UILayout -{ -public: - UIBoxLayout(UIWidgetPtr parentWidget); - - void applyStyle(const OTMLNodePtr& styleNode); - void addWidget(const UIWidgetPtr& widget) { update(); } - void removeWidget(const UIWidgetPtr& widget) { update(); } - - void setSpacing(int spacing) { m_spacing = spacing; update(); } - void setFitChildren(bool fitParent) { m_fitChildren = fitParent; update(); } - - bool isUIBoxLayout() { return true; } - -protected: - stdext::boolean m_fitChildren; - int m_spacing; -}; - -#endif diff --git a/src/framework/ui/uigridlayout.cpp b/src/framework/ui/uigridlayout.cpp deleted file mode 100644 index eed81c3..0000000 --- a/src/framework/ui/uigridlayout.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uigridlayout.h" -#include "uiwidget.h" - -#include - -UIGridLayout::UIGridLayout(UIWidgetPtr parentWidget): UILayout(parentWidget) -{ - m_cellSize = Size(16,16); - m_cellSpacing = 0; - m_numColumns = 1; - m_numLines = 0; -} - -void UIGridLayout::applyStyle(const OTMLNodePtr& styleNode) -{ - UILayout::applyStyle(styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "cell-size") - setCellSize(node->value()); - else if(node->tag() == "cell-width") - setCellWidth(node->value()); - else if(node->tag() == "cell-height") - setCellHeight(node->value()); - else if(node->tag() == "cell-spacing") - setCellSpacing(node->value()); - else if(node->tag() == "num-columns") - setNumColumns(node->value()); - else if(node->tag() == "num-lines") - setNumLines(node->value()); - else if(node->tag() == "fit-children") - setFitChildren(node->value()); - else if(node->tag() == "auto-spacing") - setAutoSpacing(node->value()); - else if(node->tag() == "flow") - setFlow(node->value()); - } -} - -void UIGridLayout::removeWidget(const UIWidgetPtr& widget) -{ - update(); -} - -void UIGridLayout::addWidget(const UIWidgetPtr& widget) -{ - update(); -} - -bool UIGridLayout::internalUpdate() -{ - bool changed = false; - UIWidgetPtr parentWidget = getParentWidget(); - if(!parentWidget) - return false; - - UIWidgetList widgets = parentWidget->getChildren(); - - Rect clippingRect = parentWidget->getPaddingRect(); - Point topLeft = clippingRect.topLeft(); - - int numColumns = m_numColumns; - if(m_flow && m_cellSize.width() > 0) { - numColumns = (clippingRect.width() + m_cellSpacing) / (m_cellSize.width() + m_cellSpacing); - if(numColumns > 0) { - m_numColumns = numColumns; - m_numLines = std::ceil(widgets.size() / (float)numColumns); - } - } - - if(numColumns <= 0) - numColumns = 1; - - int cellSpacing = m_cellSpacing; - if(m_autoSpacing && numColumns > 1) - cellSpacing = (clippingRect.width() - numColumns * m_cellSize.width()) / (numColumns - 1); - - int index = 0; - int preferredHeight = 0; - for(const UIWidgetPtr& widget : widgets) { - if(!widget->isExplicitlyVisible()) - continue; - - int line = index / numColumns; - int column = index % numColumns; - Point virtualPos = Point(column * (m_cellSize.width() + cellSpacing), line * (m_cellSize.height() + cellSpacing)); - preferredHeight = virtualPos.y + m_cellSize.height(); - Point pos = topLeft + virtualPos - parentWidget->getVirtualOffset(); - Rect dest = Rect(pos, m_cellSize); - dest.expand(-widget->getMarginTop(), -widget->getMarginRight(), -widget->getMarginBottom(), -widget->getMarginLeft()); - - if(widget->setRect(dest)) - changed = true; - - index++; - - if(m_numLines > 0 && index >= m_numColumns * m_numLines) - break; - } - preferredHeight += parentWidget->getPaddingTop() + parentWidget->getPaddingBottom(); - - if(m_fitChildren && preferredHeight != parentWidget->getHeight()) { - // must set the preferred height later - g_dispatcher.addEvent([=] { - parentWidget->setHeight(preferredHeight); - }); - } - - return changed; -} diff --git a/src/framework/ui/uigridlayout.h b/src/framework/ui/uigridlayout.h deleted file mode 100644 index 535f9c8..0000000 --- a/src/framework/ui/uigridlayout.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIGRIDLAYOUT_H -#define UIGRIDLAYOUT_H - -#include "uilayout.h" - -// @bindclass -class UIGridLayout : public UILayout -{ -public: - UIGridLayout(UIWidgetPtr parentWidget); - - void applyStyle(const OTMLNodePtr& styleNode); - void removeWidget(const UIWidgetPtr& widget); - void addWidget(const UIWidgetPtr& widget); - - void setCellSize(const Size& size) { m_cellSize = size; update(); } - void setCellWidth(int width) { m_cellSize.setWidth(width); update(); } - void setCellHeight(int height) { m_cellSize.setHeight(height); update(); } - void setCellSpacing(int spacing) { m_cellSpacing = spacing; update(); } - void setNumColumns(int columns) { m_numColumns = columns; update(); } - void setNumLines(int lines) { m_numLines = lines; update(); } - void setAutoSpacing(bool enable) { m_autoSpacing = enable; update(); } - void setFitChildren(bool enable) { m_fitChildren = enable; update(); } - void setFlow(bool enable) { m_flow = enable; update(); } - - Size getCellSize() { return m_cellSize; } - int getCellSpacing() { return m_cellSpacing; } - int getNumColumns() { return m_numColumns; } - int getNumLines() { return m_numLines; } - - virtual bool isUIGridLayout() { return true; } - -protected: - bool internalUpdate(); - -private: - Size m_cellSize; - int m_cellSpacing; - int m_numColumns; - int m_numLines; - stdext::boolean m_autoSpacing; - stdext::boolean m_fitChildren; - stdext::boolean m_flow; -}; - -#endif diff --git a/src/framework/ui/uihorizontallayout.cpp b/src/framework/ui/uihorizontallayout.cpp deleted file mode 100644 index 078fc52..0000000 --- a/src/framework/ui/uihorizontallayout.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uihorizontallayout.h" -#include "uiwidget.h" -#include - - -void UIHorizontalLayout::applyStyle(const OTMLNodePtr& styleNode) -{ - UIBoxLayout::applyStyle(styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "align-right") - setAlignRight(node->value()); - } -} - -bool UIHorizontalLayout::internalUpdate() -{ - UIWidgetPtr parentWidget = getParentWidget(); - if(!parentWidget) - return false; - UIWidgetList widgets = parentWidget->getChildren(); - - if(m_alignRight) - std::reverse(widgets.begin(), widgets.end()); - - bool changed = false; - Rect paddingRect = parentWidget->getPaddingRect(); - Point pos = (m_alignRight) ? paddingRect.topRight() : paddingRect.topLeft(); - int preferredWidth = 0; - int gap; - - for(const UIWidgetPtr& widget : widgets) { - if(!widget->isExplicitlyVisible()) - continue; - - Size size = widget->getSize(); - - gap = (m_alignRight) ? -(widget->getMarginRight()+widget->getWidth()) : widget->getMarginLeft(); - pos.x += gap; - preferredWidth += gap; - - if(widget->isFixedSize()) { - if(widget->getTextAlign() & Fw::AlignTop) { - pos.y = paddingRect.top() + widget->getMarginTop(); - } else if(widget->getTextAlign() & Fw::AlignBottom) { - pos.y = paddingRect.bottom() - widget->getHeight() - widget->getMarginBottom(); - pos.y = std::max(pos.y, paddingRect.top()); - } else { // center it - pos.y = paddingRect.top() + (paddingRect.height() - (widget->getMarginTop() + widget->getHeight() + widget->getMarginBottom()))/2; - pos.y = std::max(pos.y, paddingRect.top()); - } - } else { - // expand height - size.setHeight(paddingRect.height() - (widget->getMarginTop() + widget->getMarginBottom())); - pos.y = paddingRect.top() + (paddingRect.height() - size.height())/2; - } - - if(widget->setRect(Rect(pos - parentWidget->getVirtualOffset(), size))) - changed = true; - - gap = (m_alignRight) ? -widget->getMarginLeft() : (widget->getWidth() + widget->getMarginRight()); - gap += m_spacing; - pos.x += gap; - preferredWidth += gap; - } - - preferredWidth -= m_spacing; - preferredWidth += parentWidget->getPaddingLeft() + parentWidget->getPaddingRight(); - - if(m_fitChildren && preferredWidth != parentWidget->getWidth()) { - // must set the preferred width later - g_dispatcher.addEvent([=] { - parentWidget->setWidth(preferredWidth); - }); - } - - return changed; -} diff --git a/src/framework/ui/uihorizontallayout.h b/src/framework/ui/uihorizontallayout.h deleted file mode 100644 index 312955d..0000000 --- a/src/framework/ui/uihorizontallayout.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIHORIZONTALLAYOUT_H -#define UIHORIZONTALLAYOUT_H - -#include "uiboxlayout.h" - -class UIHorizontalLayout : public UIBoxLayout -{ -public: - UIHorizontalLayout(UIWidgetPtr parentWidget) : UIBoxLayout(parentWidget) { } - - void applyStyle(const OTMLNodePtr& styleNode); - - void setAlignRight(bool aliginRight) { m_alignRight = aliginRight; update(); } - - bool isUIHorizontalLayout() { return true; } - -protected: - bool internalUpdate(); - - Fw::AlignmentFlag m_alignChidren; - stdext::boolean m_alignRight; -}; - -#endif diff --git a/src/framework/ui/uilayout.cpp b/src/framework/ui/uilayout.cpp deleted file mode 100644 index 63d7c95..0000000 --- a/src/framework/ui/uilayout.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uilayout.h" -#include "uiwidget.h" - -#include - -void UILayout::update() -{ - //logTraceCounter(); - if(!m_parentWidget) - return; - - /* - UIWidgetPtr parent = parentWidget; - do { - UILayoutPtr ownerLayout = parent->getLayout(); - if(ownerLayout && ownerLayout->isUpdateDisabled()) - return; - parent = parent->getParent(); - } while(parent); - */ - - if(m_updateDisabled) - return; - - if(m_updating) { - updateLater(); - return; - } - - m_updating = true; - internalUpdate(); - m_parentWidget->onLayoutUpdate(); - m_updating = false; -} - -void UILayout::updateLater() -{ - if(m_updateDisabled || m_updateScheduled) - return; - - if(!getParentWidget()) - return; - - auto self = static_self_cast(); - g_dispatcher.addEvent([self] { - self->m_updateScheduled = false; - self->update(); - }); - m_updateScheduled = true; -} diff --git a/src/framework/ui/uilayout.h b/src/framework/ui/uilayout.h deleted file mode 100644 index f1eea74..0000000 --- a/src/framework/ui/uilayout.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UILAYOUT_H -#define UILAYOUT_H - -#include "declarations.h" -#include -#include - -// @bindclass -class UILayout : public LuaObject -{ -public: - UILayout(UIWidgetPtr parentWidget) : m_parentWidget(parentWidget) { m_updateDisabled = 0; } - - void update(); - void updateLater(); - - virtual void applyStyle(const OTMLNodePtr& styleNode) { } - virtual void addWidget(const UIWidgetPtr& widget) { } - virtual void removeWidget(const UIWidgetPtr& widget) { } - void disableUpdates() { m_updateDisabled++; } - void enableUpdates() { m_updateDisabled = std::max(m_updateDisabled-1,0); } - - void setParent(UIWidgetPtr parentWidget) { m_parentWidget = parentWidget; } - UIWidgetPtr getParentWidget() { return m_parentWidget; } - - bool isUpdateDisabled() { return m_updateDisabled > 0; } - bool isUpdating() { return m_updating; } - - virtual bool isUIAnchorLayout() { return false; } - virtual bool isUIBoxLayout() { return false; } - virtual bool isUIHorizontalLayout() { return false; } - virtual bool isUIVerticalLayout() { return false; } - virtual bool isUIGridLayout() { return false; } - -protected: - virtual bool internalUpdate() { return false; } - - int m_updateDisabled; - stdext::boolean m_updating; - stdext::boolean m_updateScheduled; - UIWidgetPtr m_parentWidget; -}; - -#endif diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp deleted file mode 100644 index 5fc9e7b..0000000 --- a/src/framework/ui/uimanager.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uimanager.h" -#include "ui.h" - -#include -#include -#include -#include -#include -#include -#include - -UIManager g_ui; - -void UIManager::init() -{ - // creates root widget - m_rootWidget = UIWidgetPtr(new UIWidget); - m_rootWidget->setId("root"); - m_mouseReceiver = m_rootWidget; - m_keyboardReceiver = m_rootWidget; -} - -void UIManager::terminate() -{ - // destroy root widget and its children - m_rootWidget->destroy(); - m_mouseReceiver = nullptr; - m_keyboardReceiver = nullptr; - m_rootWidget = nullptr; - m_draggingWidget = nullptr; - m_hoveredWidget = nullptr; - m_pressedWidget = nullptr; - m_styles.clear(); - m_destroyedWidgets.clear(); - m_checkEvent = nullptr; -} - -void UIManager::render(Fw::DrawPane drawPane) -{ - m_rootWidget->draw(m_rootWidget->getRect(), drawPane); -} - -void UIManager::resize(const Size& size) -{ - m_rootWidget->setSize(size); -} - -void UIManager::inputEvent(const InputEvent& event) -{ - UIWidgetList widgetList; - switch(event.type) { - case Fw::KeyTextInputEvent: - m_keyboardReceiver->propagateOnKeyText(event.keyText); - break; - case Fw::KeyDownInputEvent: - m_keyboardReceiver->propagateOnKeyDown(event.keyCode, event.keyboardModifiers); - break; - case Fw::KeyPressInputEvent: - m_keyboardReceiver->propagateOnKeyPress(event.keyCode, event.keyboardModifiers, event.autoRepeatTicks); - break; - case Fw::KeyUpInputEvent: - m_keyboardReceiver->propagateOnKeyUp(event.keyCode, event.keyboardModifiers); - break; - case Fw::MousePressInputEvent: - if(event.mouseButton == Fw::MouseLeftButton && m_mouseReceiver->isVisible()) { - UIWidgetPtr pressedWidget = m_mouseReceiver->recursiveGetChildByPos(event.mousePos, false); - if(pressedWidget && !pressedWidget->isEnabled()) - pressedWidget = nullptr; - updatePressedWidget(pressedWidget, event.mousePos); - } - - m_mouseReceiver->propagateOnMouseEvent(event.mousePos, widgetList); - for(const UIWidgetPtr& widget : widgetList) { - widget->recursiveFocus(Fw::MouseFocusReason); - if(widget->onMousePress(event.mousePos, event.mouseButton)) - break; - } - - break; - case Fw::MouseReleaseInputEvent: { - // release dragging widget - bool accepted = false; - if(m_draggingWidget && event.mouseButton == Fw::MouseLeftButton) - accepted = updateDraggingWidget(nullptr, event.mousePos); - - if(!accepted) { - m_mouseReceiver->propagateOnMouseEvent(event.mousePos, widgetList); - - // mouse release is always fired first on the pressed widget - if(m_pressedWidget) { - auto it = std::find(widgetList.begin(), widgetList.end(), m_pressedWidget); - if(it != widgetList.end()) - widgetList.erase(it); - widgetList.push_front(m_pressedWidget); - } - - for(const UIWidgetPtr& widget : widgetList) { - if(widget->onMouseRelease(event.mousePos, event.mouseButton)) - break; - } - } - - if(m_pressedWidget && event.mouseButton == Fw::MouseLeftButton) - updatePressedWidget(nullptr, event.mousePos, !accepted); - break; - } - case Fw::MouseMoveInputEvent: { - // start dragging when moving a pressed widget - if(m_pressedWidget && m_pressedWidget->isDraggable() && m_draggingWidget != m_pressedWidget) { - // only drags when moving more than 4 pixels - if((event.mousePos - m_pressedWidget->getLastClickPosition()).length() >= 4) - updateDraggingWidget(m_pressedWidget, event.mousePos - event.mouseMoved); - } - - // mouse move can change hovered widgets - updateHoveredWidget(true); - - // first fire dragging move - if(m_draggingWidget) { - if(m_draggingWidget->onDragMove(event.mousePos, event.mouseMoved)) - break; - } - - if (m_pressedWidget) { - if (m_pressedWidget->onMouseMove(event.mousePos, event.mouseMoved)) { - break; - } - } - - //m_mouseReceiver->propagateOnMouseMove(event.mousePos, event.mouseMoved, widgetList); - m_rootWidget->propagateOnMouseMove(event.mousePos, event.mouseMoved, widgetList); - for(const UIWidgetPtr& widget : widgetList) { - if(widget->onMouseMove(event.mousePos, event.mouseMoved)) - break; - } - break; - } - case Fw::MouseWheelInputEvent: - m_rootWidget->propagateOnMouseEvent(event.mousePos, widgetList); - for(const UIWidgetPtr& widget : widgetList) { - if(widget->onMouseWheel(event.mousePos, event.wheelDirection)) - break; - } - break; - default: - break; - }; -} - -void UIManager::updatePressedWidget(const UIWidgetPtr& newPressedWidget, const Point& clickedPos, bool fireClicks) -{ - UIWidgetPtr oldPressedWidget = m_pressedWidget; - m_pressedWidget = newPressedWidget; - - // when releasing mouse inside pressed widget area send onClick event - if(fireClicks && oldPressedWidget && oldPressedWidget->isEnabled() && oldPressedWidget->containsPoint(clickedPos)) - oldPressedWidget->onClick(clickedPos); - - if(newPressedWidget) - newPressedWidget->updateState(Fw::PressedState); - - if(oldPressedWidget) - oldPressedWidget->updateState(Fw::PressedState); -} - -bool UIManager::updateDraggingWidget(const UIWidgetPtr& draggingWidget, const Point& clickedPos) -{ - bool accepted = false; - - UIWidgetPtr oldDraggingWidget = m_draggingWidget; - m_draggingWidget = nullptr; - if(oldDraggingWidget) { - UIWidgetPtr droppedWidget; - if(!clickedPos.isNull()) { - auto clickedChildren = m_rootWidget->recursiveGetChildrenByPos(clickedPos); - for(const UIWidgetPtr& child : clickedChildren) { - if(child->onDrop(oldDraggingWidget, clickedPos)) { - droppedWidget = child; - break; - } - } - } - - accepted = oldDraggingWidget->onDragLeave(droppedWidget, clickedPos); - oldDraggingWidget->updateState(Fw::DraggingState); - } - - if(draggingWidget) { - if(draggingWidget->onDragEnter(clickedPos)) { - m_draggingWidget = draggingWidget; - draggingWidget->updateState(Fw::DraggingState); - accepted = true; - } - } - - return accepted; -} - -void UIManager::updateHoveredWidget(bool now) -{ - if(m_hoverUpdateScheduled && !now) - return; - - auto func = [this] { - if(!m_rootWidget) - return; - - m_hoverUpdateScheduled = false; - UIWidgetPtr hoveredWidget; - //if(!g_window.isMouseButtonPressed(Fw::MouseLeftButton) && !g_window.isMouseButtonPressed(Fw::MouseRightButton)) { - hoveredWidget = m_rootWidget->recursiveGetChildByPos(g_window.getMousePosition(), false); - if(hoveredWidget && !hoveredWidget->isEnabled()) - hoveredWidget = nullptr; - //} - - if(hoveredWidget != m_hoveredWidget) { - UIWidgetPtr oldHovered = m_hoveredWidget; - m_hoveredWidget = hoveredWidget; - if(oldHovered) { - oldHovered->updateState(Fw::HoverState); - oldHovered->onHoverChange(false); - } - if(hoveredWidget) { - hoveredWidget->updateState(Fw::HoverState); - hoveredWidget->onHoverChange(true); - } - } - }; - - if(now) - func(); - else { - m_hoverUpdateScheduled = true; - g_dispatcher.addEvent(func); - } -} - -void UIManager::onWidgetAppear(const UIWidgetPtr& widget) -{ - if(widget->containsPoint(g_window.getMousePosition())) - updateHoveredWidget(); -} - -void UIManager::onWidgetDisappear(const UIWidgetPtr& widget) -{ - if(widget->containsPoint(g_window.getMousePosition())) - updateHoveredWidget(); -} - -void UIManager::onWidgetDestroy(const UIWidgetPtr& widget) -{ - AutoStat s(STATS_MAIN, "UIManager::onWidgetDestroy", stdext::format("%s (%s)", widget->getId(), widget->getParent() ? widget->getParent()->getId() : "")); - - // release input grabs - if(m_keyboardReceiver == widget) - resetKeyboardReceiver(); - - if(m_mouseReceiver == widget) - resetMouseReceiver(); - - if(m_hoveredWidget == widget) - updateHoveredWidget(); - - if(m_pressedWidget == widget) - updatePressedWidget(nullptr); - - if(m_draggingWidget == widget) - updateDraggingWidget(nullptr); - - if (!g_extras.debugWidgets) - return; - - if(widget == m_rootWidget || !m_rootWidget) - return; - - m_destroyedWidgets.push_back(widget); - - if(m_checkEvent && !m_checkEvent->isExecuted()) - return; - - m_checkEvent = g_dispatcher.scheduleEvent([this] { - g_lua.collectGarbage(); - UIWidgetList backupList(std::move(m_destroyedWidgets)); - m_destroyedWidgets.clear(); - g_dispatcher.scheduleEvent([backupList] { - g_lua.collectGarbage(); - for(const UIWidgetPtr& widget : backupList) { - if(widget->ref_count() != 1) - g_logger.warning(stdext::format("widget '%s' (parent: '%s' (%s), source: '%s') destroyed but still have %d reference(s) left", widget->getId(), widget->getParent() ? widget->getParent()->getId() : "", widget->getParentId(), widget->getSource(), widget->getUseCount()-1)); - } - }, 1); - }, 1000); -} - -void UIManager::clearStyles() -{ - m_styles.clear(); -} - -bool UIManager::importStyle(std::string file) -{ - try { - file = g_resources.guessFilePath(file, "otui"); - - OTMLDocumentPtr doc = OTMLDocument::parse(file); - - for(const OTMLNodePtr& styleNode : doc->children()) - importStyleFromOTML(styleNode); - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Failed to import UI styles from '%s': %s", file, e.what())); - return false; - } -} - -bool UIManager::importStyleFromString(std::string data) -{ - try { - OTMLDocumentPtr doc = OTMLDocument::parseString(data, g_lua.getCurrentSourcePath()); - for(const OTMLNodePtr& styleNode : doc->children()) - importStyleFromOTML(styleNode); - return true; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Failed to import UI styles from '%s': %s", g_lua.getCurrentSourcePath(), e.what())); - return false; - } -} - -void UIManager::importStyleFromOTML(const OTMLNodePtr& styleNode) -{ - std::string tag = styleNode->tag(); - std::vector split = stdext::split(tag, "<"); - if(split.size() != 2) - throw OTMLException(styleNode, "not a valid style declaration"); - - std::string name = split[0]; - std::string base = split[1]; - bool unique = false; - - stdext::trim(name); - stdext::trim(base); - - if(name[0] == '#') { - name = name.substr(1); - unique = true; - - styleNode->setTag(name); - styleNode->writeAt("__unique", true); - } - - OTMLNodePtr oldStyle = m_styles[name]; - - // Warn about redefined styles - /* - if(!g_app.isRunning() && (oldStyle && !oldStyle->valueAt("__unique", false))) { - auto it = m_styles.find(name); - if(it != m_styles.end()) - g_logger.warning(stdext::format("style '%s' is being redefined", name)); - } - */ - - if(!oldStyle || !oldStyle->valueAt("__unique", false) || unique) { - OTMLNodePtr originalStyle = getStyle(base); - if(!originalStyle) - stdext::throw_exception(stdext::format("base style '%s', is not defined", base)); - OTMLNodePtr style = originalStyle->clone(); - style->merge(styleNode); - style->setTag(name); - m_styles[name] = style; - } -} - -OTMLNodePtr UIManager::getStyle(const std::string& styleName) -{ - auto it = m_styles.find(styleName); - if(it != m_styles.end()) - return m_styles[styleName]; - - // styles starting with UI are automatically defined - if(stdext::starts_with(styleName, "UI")) { - OTMLNodePtr node = OTMLNode::create(styleName); - node->writeAt("__class", styleName); - m_styles[styleName] = node; - return node; - } - - return nullptr; -} - -std::string UIManager::getStyleClass(const std::string& styleName) -{ - OTMLNodePtr style = getStyle(styleName); - if(style && style->get("__class")) - return style->valueAt("__class"); - return ""; -} - - -UIWidgetPtr UIManager::loadUIFromString(const std::string& data, const UIWidgetPtr& parent) -{ - try { - std::stringstream sstream; - sstream.clear(std::ios::goodbit); - sstream.write(&data[0], data.length()); - sstream.seekg(0, std::ios::beg); - OTMLDocumentPtr doc = OTMLDocument::parse(sstream, "(string)"); - UIWidgetPtr widget; - for (const OTMLNodePtr& node : doc->children()) { - std::string tag = node->tag(); - - // import styles in these files too - if (tag.find("<") != std::string::npos) - importStyleFromOTML(node); - else { - if (widget) - stdext::throw_exception("cannot have multiple main widgets in otui files"); - widget = createWidgetFromOTML(node, parent); - } - } - - return widget; - } catch (stdext::exception& e) { - g_logger.error(stdext::format("failed to load UI from string: %s", e.what())); - return nullptr; - } -} - -UIWidgetPtr UIManager::loadUI(std::string file, const UIWidgetPtr& parent) -{ - try { - file = g_resources.guessFilePath(file, "otui"); - - OTMLDocumentPtr doc = OTMLDocument::parse(file); - UIWidgetPtr widget; - for(const OTMLNodePtr& node : doc->children()) { - std::string tag = node->tag(); - - // import styles in these files too - if(tag.find("<") != std::string::npos) - importStyleFromOTML(node); - else { - if(widget) - stdext::throw_exception("cannot have multiple main widgets in otui files"); - widget = createWidgetFromOTML(node, parent); - } - } - - return widget; - } catch(stdext::exception& e) { - g_logger.error(stdext::format("failed to load UI from '%s': %s", file, e.what())); - return nullptr; - } -} - -UIWidgetPtr UIManager::createWidget(const std::string& styleName, const UIWidgetPtr& parent) -{ - OTMLNodePtr node = OTMLNode::create(styleName); - try { - return createWidgetFromOTML(node, parent); - } catch(stdext::exception& e) { - g_logger.error(stdext::format("failed to create widget from style '%s': %s", styleName, e.what())); - return nullptr; - } -} - -UIWidgetPtr UIManager::createWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent) -{ - OTMLNodePtr originalStyleNode = getStyle(widgetNode->tag()); - if(!originalStyleNode) - stdext::throw_exception(stdext::format("'%s' is not a defined style", widgetNode->tag())); - - OTMLNodePtr styleNode = originalStyleNode->clone(); - styleNode->merge(widgetNode); - - std::string widgetType = styleNode->valueAt("__class"); - - // call widget creation from lua - UIWidgetPtr widget = g_lua.callGlobalField(widgetType, "create"); - if(parent) - parent->addChild(widget); - - if(widget) { - widget->callLuaField("onCreate"); - - widget->setStyleFromNode(styleNode); - - for(const OTMLNodePtr& childNode : styleNode->children()) { - if(!childNode->isUnique()) { - createWidgetFromOTML(childNode, widget); - styleNode->removeChild(childNode); - } - } - } else - stdext::throw_exception(stdext::format("unable to create widget of type '%s'", widgetType)); - - widget->callLuaField("onSetup"); - - return widget; -} diff --git a/src/framework/ui/uimanager.h b/src/framework/ui/uimanager.h deleted file mode 100644 index a90e7b6..0000000 --- a/src/framework/ui/uimanager.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIMANAGER_H -#define UIMANAGER_H - -#include "declarations.h" -#include "uiwidget.h" -#include -#include - -//@bindsingleton g_ui -class UIManager -{ -public: - void init(); - void terminate(); - - void render(Fw::DrawPane drawPane); - void resize(const Size& size); - void inputEvent(const InputEvent& event); - - void updatePressedWidget(const UIWidgetPtr& newPressedWidget, const Point& clickedPos = Point(), bool fireClicks = true); - bool updateDraggingWidget(const UIWidgetPtr& draggingWidget, const Point& clickedPos = Point()); - void updateHoveredWidget(bool now = false); - - void clearStyles(); - bool importStyle(std::string file); - bool importStyleFromString(std::string data); - void importStyleFromOTML(const OTMLNodePtr& styleNode); - OTMLNodePtr getStyle(const std::string& styleName); - std::string getStyleClass(const std::string& styleName); - - UIWidgetPtr loadUIFromString(const std::string& data, const UIWidgetPtr& parent); - UIWidgetPtr loadUI(std::string file, const UIWidgetPtr& parent); - UIWidgetPtr displayUI(const std::string& file) { return loadUI(file, m_rootWidget); } - UIWidgetPtr createWidget(const std::string& styleName, const UIWidgetPtr& parent); - UIWidgetPtr createWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent); - - void setMouseReceiver(const UIWidgetPtr& widget) { m_mouseReceiver = widget; } - void setKeyboardReceiver(const UIWidgetPtr& widget) { m_keyboardReceiver = widget; } - void setDebugBoxesDrawing(bool enabled) { m_drawDebugBoxes = enabled; } - void resetMouseReceiver() { m_mouseReceiver = m_rootWidget; } - void resetKeyboardReceiver() { m_keyboardReceiver = m_rootWidget; } - UIWidgetPtr getMouseReceiver() { return m_mouseReceiver; } - UIWidgetPtr getKeyboardReceiver() { return m_keyboardReceiver; } - UIWidgetPtr getDraggingWidget() { return m_draggingWidget; } - UIWidgetPtr getHoveredWidget() { return m_hoveredWidget; } - UIWidgetPtr getPressedWidget() { return m_pressedWidget; } - UIWidgetPtr getRootWidget() { return m_rootWidget; } - bool isMouseGrabbed() { return m_mouseReceiver != m_rootWidget; } - bool isKeyboardGrabbed() { return m_keyboardReceiver != m_rootWidget; } - - bool isDrawingDebugBoxes() { return m_drawDebugBoxes; } - -protected: - void onWidgetAppear(const UIWidgetPtr& widget); - void onWidgetDisappear(const UIWidgetPtr& widget); - void onWidgetDestroy(const UIWidgetPtr& widget); - - friend class UIWidget; - -private: - UIWidgetPtr m_rootWidget; - UIWidgetPtr m_mouseReceiver; - UIWidgetPtr m_keyboardReceiver; - UIWidgetPtr m_draggingWidget; - UIWidgetPtr m_hoveredWidget; - UIWidgetPtr m_pressedWidget; - stdext::boolean m_hoverUpdateScheduled; - stdext::boolean m_drawDebugBoxes; - std::unordered_map m_styles; - UIWidgetList m_destroyedWidgets; - ScheduledEventPtr m_checkEvent; - -}; - -extern UIManager g_ui; - -#endif diff --git a/src/framework/ui/uitextedit.cpp b/src/framework/ui/uitextedit.cpp deleted file mode 100644 index 1b41651..0000000 --- a/src/framework/ui/uitextedit.cpp +++ /dev/null @@ -1,931 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uitextedit.h" -#include "uimanager.h" -#include -#include -#include -#include -#include -#include -#include - -UITextEdit::UITextEdit() -{ - m_cursorPos = 0; - m_textAlign = Fw::AlignTopLeft; - m_textHidden = false; - m_shiftNavigation = false; - m_multiline = false; -#ifdef ANDROID - m_cursorVisible = false; -#else - m_cursorVisible = true; -#endif - m_cursorInRange = true; - m_maxLength = 0; - m_editable = true; - m_selectable = true; - m_autoScroll = true; - m_autoSubmit = false; - m_changeCursorImage = true; - m_selectionReference = 0; - m_selectionStart = 0; - m_selectionEnd = 0; - m_updatesEnabled = true; - m_selectionColor = Color::white; - m_selectionBackgroundColor = Color::black; - m_glyphsMustRecache = true; - blinkCursor(); -} - -void UITextEdit::drawSelf(Fw::DrawPane drawPane) -{ - if(drawPane != Fw::ForegroundPane) - return; - - drawBackground(m_rect); - drawBorder(m_rect); - drawImage(m_rect); - drawIcon(m_rect); - - int textLength = m_glyphsCoords.size(); - const TexturePtr& texture = m_font->getTexture(); - if(!texture) - return; - - bool glyphsMustRecache = m_glyphsMustRecache; - if(glyphsMustRecache) - m_glyphsMustRecache = false; - - if(m_color != Color::alpha) { - if(glyphsMustRecache) { - m_glyphsTextCoordsBuffer.clear(); - for(int i=0;iaddTextureCoords(m_glyphsTextCoordsBuffer, texture, m_color); - } - - if(hasSelection()) { - if(glyphsMustRecache) { - m_glyphsSelectCoordsBuffer.clear(); - for(int i=m_selectionStart;iaddFillCoords(m_glyphsSelectCoordsBuffer, m_selectionBackgroundColor); - g_drawQueue->addTextureCoords(m_glyphsSelectCoordsBuffer, texture, m_selectionColor); - } - - // render cursor - if(isExplicitlyEnabled() && m_cursorVisible && m_cursorInRange && isActive() && m_cursorPos >= 0) { - VALIDATE(m_cursorPos <= textLength); - // draw every 333ms - const int delay = 333; - int elapsed = g_clock.millis() - m_cursorTicks; - if(elapsed <= delay) { - Rect cursorRect; - // when cursor is at 0 - if(m_cursorPos == 0) - cursorRect = Rect(m_rect.left()+m_padding.left, m_rect.top()+m_padding.top, 1, m_font->getGlyphHeight()); - else - cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight()); - - if (hasSelection() && m_cursorPos >= m_selectionStart && m_cursorPos <= m_selectionEnd) - g_drawQueue->addFilledRect(cursorRect, m_selectionColor); - else - g_drawQueue->addFilledRect(cursorRect, m_color); - } else if(elapsed >= 2*delay) { - m_cursorTicks = g_clock.millis(); - } - } -} - -void UITextEdit::update(bool focusCursor) -{ - if(!m_updatesEnabled) - return; - - std::string text = getDisplayedText(); - m_drawText = text; - int textLength = text.length(); - - // prevent glitches - if(m_rect.isEmpty()) - return; - - // recache coords buffers - recacheGlyphs(); - - // map glyphs positions - Size textBoxSize; - const std::vector& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize); - const Rect *glyphsTextureCoords = m_font->getGlyphsTextureCoords(); - const Size *glyphsSize = m_font->getGlyphsSize(); - int glyph; - - // update rect size - if(!m_rect.isValid() || m_textHorizontalAutoResize || m_textVerticalAutoResize) { - textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom) + m_textOffset.toSize(); - Size size = getSize(); - if(size.width() <= 0 || (m_textHorizontalAutoResize && !m_textWrap)) - size.setWidth(textBoxSize.width()); - if(size.height() <= 0 || m_textVerticalAutoResize) - size.setHeight(textBoxSize.height()); - setSize(size); - } - - // resize just on demand - if(textLength != (int)m_glyphsCoords.size()) { - m_glyphsCoords.resize(textLength); - m_glyphsTexCoords.resize(textLength); - } - - Point oldTextAreaOffset = m_textVirtualOffset; - - if(textBoxSize.width() <= getPaddingRect().width()) - m_textVirtualOffset.x = 0; - if(textBoxSize.height() <= getPaddingRect().height()) - m_textVirtualOffset.y = 0; - - // readjust start view area based on cursor position - m_cursorInRange = false; - if(focusCursor && m_autoScroll) { - if(m_cursorPos > 0 && textLength > 0) { - VALIDATE(m_cursorPos <= textLength); - Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(m_padding.left+m_padding.right, 0)); // previous rendered virtual rect - int pos = m_cursorPos - 1; // element before cursor - glyph = (uchar)text[pos]; // glyph of the element before cursor - Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]); - - // if the cursor is not on the previous rendered virtual rect we need to update it - if(!virtualRect.contains(glyphRect.topLeft()) || !virtualRect.contains(glyphRect.bottomRight())) { - // calculate where is the first glyph visible - Point startGlyphPos; - startGlyphPos.y = std::max(glyphRect.bottom() - virtualRect.height(), 0); - startGlyphPos.x = std::max(glyphRect.right() - virtualRect.width(), 0); - - // find that glyph - for(pos = 0; pos < textLength; ++pos) { - glyph = (uchar)text[pos]; - glyphRect = Rect(glyphsPositions[pos], glyphsSize[glyph]); - glyphRect.setTop(std::max(glyphRect.top() - m_font->getYOffset() - m_font->getGlyphSpacing().height(), 0)); - glyphRect.setLeft(std::max(glyphRect.left() - m_font->getGlyphSpacing().width(), 0)); - - // first glyph entirely visible found - if(glyphRect.topLeft().x >= startGlyphPos.x && glyphRect.topLeft().y >= startGlyphPos.y) { - m_textVirtualOffset.x = glyphsPositions[pos].x; - m_textVirtualOffset.y = glyphsPositions[pos].y - m_font->getYOffset(); - break; - } - } - } - } else { - m_textVirtualOffset = Point(0,0); - } - m_cursorInRange = true; - } else { - if(m_cursorPos > 0 && textLength > 0) { - Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(2*m_padding.left+m_padding.right, 0) ); // previous rendered virtual rect - int pos = m_cursorPos - 1; // element before cursor - glyph = (uchar)text[pos]; // glyph of the element before cursor - Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]); - if(virtualRect.contains(glyphRect.topLeft()) && virtualRect.contains(glyphRect.bottomRight())) - m_cursorInRange = true; - } else { - m_cursorInRange = true; - } - } - - bool fireAreaUpdate = false; - if(oldTextAreaOffset != m_textVirtualOffset) - fireAreaUpdate = true; - - Rect textScreenCoords = m_rect; - textScreenCoords.expandLeft(-m_padding.left); - textScreenCoords.expandRight(-m_padding.right); - textScreenCoords.expandBottom(-m_padding.bottom); - textScreenCoords.expandTop(-m_padding.top); - m_drawArea = textScreenCoords; - - if(textScreenCoords.size() != m_textVirtualSize) { - m_textVirtualSize = textScreenCoords.size(); - fireAreaUpdate = true; - } - - Size totalSize = textBoxSize; - if(totalSize.width() < m_textVirtualSize.width()) - totalSize.setWidth(m_textVirtualSize.height()); - if(totalSize.height() < m_textVirtualSize.height()) - totalSize.setHeight(m_textVirtualSize.height()); - if(m_textTotalSize != totalSize) { - m_textTotalSize = totalSize; - fireAreaUpdate = true; - } - - if(m_textAlign & Fw::AlignBottom) { - m_drawArea.translate(0, textScreenCoords.height() - textBoxSize.height()); - } else if(m_textAlign & Fw::AlignVerticalCenter) { - m_drawArea.translate(0, (textScreenCoords.height() - textBoxSize.height()) / 2); - } else { // AlignTop - } - - if(m_textAlign & Fw::AlignRight) { - m_drawArea.translate(textScreenCoords.width() - textBoxSize.width(), 0); - } else if(m_textAlign & Fw::AlignHorizontalCenter) { - m_drawArea.translate((textScreenCoords.width() - textBoxSize.width()) / 2, 0); - } else { // AlignLeft - - } - - for(int i = 0; i < textLength; ++i) { - glyph = (uchar)text[i]; - m_glyphsCoords[i].clear(); - - // skip invalid glyphs - if(glyph < 32 && glyph != (uchar)'\n') - continue; - - // calculate initial glyph rect and texture coords - Rect glyphScreenCoords(glyphsPositions[i], glyphsSize[glyph]); - Rect glyphTextureCoords = glyphsTextureCoords[glyph]; - - // first translate to align position - if(m_textAlign & Fw::AlignBottom) { - glyphScreenCoords.translate(0, textScreenCoords.height() - textBoxSize.height()); - } else if(m_textAlign & Fw::AlignVerticalCenter) { - glyphScreenCoords.translate(0, (textScreenCoords.height() - textBoxSize.height()) / 2); - } else { // AlignTop - // nothing to do - } - - if(m_textAlign & Fw::AlignRight) { - glyphScreenCoords.translate(textScreenCoords.width() - textBoxSize.width(), 0); - } else if(m_textAlign & Fw::AlignHorizontalCenter) { - glyphScreenCoords.translate((textScreenCoords.width() - textBoxSize.width()) / 2, 0); - } else { // AlignLeft - // nothing to do - } - - // only render glyphs that are after startRenderPosition - if(glyphScreenCoords.bottom() < m_textVirtualOffset.y || glyphScreenCoords.right() < m_textVirtualOffset.x) - continue; - - // bound glyph topLeft to startRenderPosition - if(glyphScreenCoords.top() < m_textVirtualOffset.y) { - glyphTextureCoords.setTop(glyphTextureCoords.top() + (m_textVirtualOffset.y - glyphScreenCoords.top())); - glyphScreenCoords.setTop(m_textVirtualOffset.y); - } - if(glyphScreenCoords.left() < m_textVirtualOffset.x) { - glyphTextureCoords.setLeft(glyphTextureCoords.left() + (m_textVirtualOffset.x - glyphScreenCoords.left())); - glyphScreenCoords.setLeft(m_textVirtualOffset.x); - } - - // subtract startInternalPos - glyphScreenCoords.translate(-m_textVirtualOffset); - - // translate rect to screen coords - glyphScreenCoords.translate(textScreenCoords.topLeft()); - - // only render if glyph rect is visible on screenCoords - if(!textScreenCoords.intersects(glyphScreenCoords)) - continue; - - // bound glyph bottomRight to screenCoords bottomRight - if(glyphScreenCoords.bottom() > textScreenCoords.bottom()) { - glyphTextureCoords.setBottom(glyphTextureCoords.bottom() + (textScreenCoords.bottom() - glyphScreenCoords.bottom())); - glyphScreenCoords.setBottom(textScreenCoords.bottom()); - } - if(glyphScreenCoords.right() > textScreenCoords.right()) { - glyphTextureCoords.setRight(glyphTextureCoords.right() + (textScreenCoords.right() - glyphScreenCoords.right())); - glyphScreenCoords.setRight(textScreenCoords.right()); - } - - // render glyph - m_glyphsCoords[i] = glyphScreenCoords; - m_glyphsTexCoords[i] = glyphTextureCoords; - } - - if(fireAreaUpdate) - onTextAreaUpdate(m_textVirtualOffset, m_textVirtualSize, m_textTotalSize); -} - -void UITextEdit::setCursorPos(int pos) -{ - if(pos < 0) - pos = m_text.length(); - - if(pos != m_cursorPos) { - if(pos < 0) - m_cursorPos = 0; - else if((uint)pos >= m_text.length()) - m_cursorPos = m_text.length(); - else - m_cursorPos = pos; - update(true); - } -} - -void UITextEdit::setSelection(int start, int end) -{ - if(start == m_selectionStart && end == m_selectionEnd) - return; - - if(start > end) - std::swap(start, end); - - if(end == -1) - end = m_text.length(); - - m_selectionStart = stdext::clamp(start, 0, (int)m_text.length()); - m_selectionEnd = stdext::clamp(end, 0, (int)m_text.length()); - recacheGlyphs(); -} - -void UITextEdit::setTextHidden(bool hidden) -{ - m_textHidden = true; - update(true); -} - -void UITextEdit::setTextVirtualOffset(const Point& offset) -{ - m_textVirtualOffset = offset; - update(); -} - -void UITextEdit::appendText(std::string text) -{ - if(hasSelection()) - del(); - - if(m_cursorPos >= 0) { - // replace characters that are now allowed - if(!m_multiline) - stdext::replace_all(text, "\n", " "); - stdext::replace_all(text, "\r", ""); - stdext::replace_all(text, "\t", " "); - - if(text.length() > 0) { - // only add text if textedit can add it - if(m_maxLength > 0 && m_text.length() + text.length() > m_maxLength) - return; - - // only ignore text append if it contains invalid characters - if(m_validCharacters.size() > 0) { - for(uint i = 0; i < text.size(); ++i) { - if(m_validCharacters.find(text[i]) == std::string::npos) - return; - } - } - - std::string tmp = m_text; - tmp.insert(m_cursorPos, text); - m_cursorPos += text.length(); - setText(tmp); - } - } -} - -void UITextEdit::appendCharacter(char c) -{ - if((c == '\n' && !m_multiline) || c == '\r') - return; - - if(hasSelection()) - del(); - - if(m_cursorPos >= 0) { - if(m_maxLength > 0 && m_text.length() + 1 > m_maxLength) - return; - - if(m_validCharacters.size() > 0 && m_validCharacters.find(c) == std::string::npos) - return; - - std::string tmp; - tmp = c; - std::string tmp2 = m_text; - tmp2.insert(m_cursorPos, tmp); - m_cursorPos++; - setText(tmp2); - } -} - -void UITextEdit::removeCharacter(bool right) -{ - std::string tmp = m_text; - if(m_cursorPos >= 0 && tmp.length() > 0) { - if((uint)m_cursorPos >= tmp.length()) { - tmp.erase(tmp.begin() + (--m_cursorPos)); - } else { - if(right) - tmp.erase(tmp.begin() + m_cursorPos); - else if(m_cursorPos > 0) - tmp.erase(tmp.begin() + --m_cursorPos); - } - setText(tmp); - } -} - -void UITextEdit::blinkCursor() -{ - m_cursorTicks = g_clock.millis(); -} - -void UITextEdit::del(bool right) -{ - if(hasSelection()) { - std::string tmp = m_text; - tmp.erase(m_selectionStart, m_selectionEnd - m_selectionStart); - - setCursorPos(m_selectionStart); - clearSelection(); - setText(tmp); - } else - removeCharacter(right); -} - -void UITextEdit::paste(const std::string& text) -{ - if(hasSelection()) - del(); - appendText(text); -} - -std::string UITextEdit::copy() -{ - std::string text; - if(hasSelection()) { - text = getSelection(); - g_window.setClipboardText(text); - } - return text; -} - -std::string UITextEdit::cut() -{ - std::string text = copy(); - del(); - return text; -} - -void UITextEdit::wrapText() -{ - setText(m_font->wrapText(m_text, getPaddingRect().width() - m_textOffset.x)); -} - -void UITextEdit::moveCursorHorizontally(bool right) -{ - if(right) { - if((uint)m_cursorPos+1 <= m_text.length()) - m_cursorPos++; - else - m_cursorPos = 0; - } else { - if(m_cursorPos-1 >= 0) - m_cursorPos--; - else - m_cursorPos = m_text.length(); - } - - blinkCursor(); - update(true); -} - -void UITextEdit::moveCursorVertically(bool up) -{ - if (up) { - int shifted = 0; - int i = m_cursorPos - 1; - int limit = 0; - bool nextLine = false; - for (; i > 0; --i) { - if (m_text[i] == '\n') { - if (nextLine) { - i += 1; - break; - } - nextLine = true; - limit = i; - } else if(!nextLine) { - shifted++; - } - } - i += shifted; - m_cursorPos = std::min(limit, i); - } else { - int shifted = 0; - int i = m_cursorPos - 1; - for (; i >= 0; --i) { - if (m_text[i] == '\n') { - break; - } else { - shifted++; - } - } - i = m_cursorPos; - - bool nextLine = false; - int limit = m_text.size(); - int moveTo = m_text.size(); - for (; i < (int)m_text.size(); ++i) { - if (m_text[i] == '\n') { - if (nextLine) { - limit = i; - break; - } - nextLine = true; - moveTo = i + 1; - } - } - moveTo += shifted; - m_cursorPos = std::min(limit, moveTo); - } - blinkCursor(); - update(true); -} - -int UITextEdit::getTextPos(Point pos) -{ - int textLength = m_text.length(); - - // find any glyph that is actually on the - int candidatePos = -1; - Rect firstGlyphRect, lastGlyphRect; - for(int i=0;igetYOffset() + m_font->getGlyphSpacing().height()); - clickGlyphRect.expandLeft(m_font->getGlyphSpacing().width()+1); - if(clickGlyphRect.contains(pos)) { - candidatePos = i; - break; - } - else if(pos.y >= clickGlyphRect.top() && pos.y <= clickGlyphRect.bottom()) { - if(pos.x <= clickGlyphRect.left()) { - candidatePos = i; - break; - } else if(pos.x >= clickGlyphRect.right()) - candidatePos = i+1; - } - } - - if(textLength > 0) { - if(pos.y < firstGlyphRect.top()) - return 0; - else if(pos.y > lastGlyphRect.bottom()) - return textLength; - } - - return candidatePos; -} - -std::string UITextEdit::getDisplayedText() -{ - std::string text; - if(m_textHidden) - text = std::string(m_text.length(), '*'); - else - text = m_text; - - if(m_textWrap && m_rect.isValid()) - text = m_font->wrapText(text, getPaddingRect().width() - m_textOffset.x); - - return text; -} - -std::string UITextEdit::getSelection() -{ - if(!hasSelection()) - return std::string(); - return m_text.substr(m_selectionStart, m_selectionEnd - m_selectionStart); -} - -void UITextEdit::updateText() -{ - if(m_cursorPos > (int)m_text.length()) - m_cursorPos = m_text.length(); - - // any text changes reset the selection - if(m_selectable) { - m_selectionEnd = 0; - m_selectionStart = 0; - } - - blinkCursor(); - update(true); -} - -void UITextEdit::onHoverChange(bool hovered) -{ - if(m_changeCursorImage) { - if(hovered && !g_mouse.isCursorChanged()) - g_mouse.pushCursor("text"); - else - g_mouse.popCursor("text"); - } -} - -void UITextEdit::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - UIWidget::onStyleApply(styleName, styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "text") { - setText(node->value()); - setCursorPos(m_text.length()); - } else if(node->tag() == "text-hidden") - setTextHidden(node->value()); - else if(node->tag() == "shift-navigation") - setShiftNavigation(node->value()); - else if(node->tag() == "multiline") - setMultiline(node->value()); - else if(node->tag() == "max-length") - setMaxLength(node->value()); - else if(node->tag() == "editable") - setEditable(node->value()); - else if(node->tag() == "selectable") - setSelectable(node->value()); - else if(node->tag() == "selection-color") - setSelectionColor(node->value()); - else if(node->tag() == "selection-background-color") - setSelectionBackgroundColor(node->value()); - else if(node->tag() == "selection") { - Point selectionRange = node->value(); - setSelection(selectionRange.x, selectionRange.y); - } - else if(node->tag() == "cursor-visible") - setCursorVisible(node->value()); - else if(node->tag() == "change-cursor-image") - setChangeCursorImage(node->value()); - else if (node->tag() == "auto-scroll") - setAutoScroll(node->value()); - else if (node->tag() == "text-auto-submit") - setAutoSubmit(node->value()); - } -} - -void UITextEdit::onGeometryChange(const Rect& oldRect, const Rect& newRect) -{ - update(true); - UIWidget::onGeometryChange(oldRect, newRect); -} - -void UITextEdit::onFocusChange(bool focused, Fw::FocusReason reason) -{ - if(focused) { - if(reason == Fw::KeyboardFocusReason) - setCursorPos(m_text.length()); - else - blinkCursor(); - update(true); - } else if(m_selectable) - clearSelection(); - UIWidget::onFocusChange(focused, reason); -} - -bool UITextEdit::onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks) -{ - if(UIWidget::onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks)) - return true; - - if(keyboardModifiers == Fw::KeyboardNoModifier) { - if(keyCode == Fw::KeyDelete && m_editable) { // erase right character - if(hasSelection() || !m_text.empty()) { - del(true); - return true; - } - } else if(keyCode == Fw::KeyBackspace && m_editable) { // erase left character - if(hasSelection() || !m_text.empty()) { - del(false); - return true; - } - } else if(keyCode == Fw::KeyRight && !m_shiftNavigation) { // move cursor right - clearSelection(); - moveCursorHorizontally(true); - return true; - } else if(keyCode == Fw::KeyLeft && !m_shiftNavigation) { // move cursor left - clearSelection(); - moveCursorHorizontally(false); - return true; - } else if(keyCode == Fw::KeyHome) { // move cursor to first character - if(m_cursorPos != 0) { - clearSelection(); - setCursorPos(0); - return true; - } - } else if(keyCode == Fw::KeyEnd) { // move cursor to last character - if(m_cursorPos != (int)m_text.length()) { - clearSelection(); - setCursorPos(m_text.length()); - return true; - } - } else if(keyCode == Fw::KeyTab && !m_shiftNavigation) { - if (m_multiline) { - appendText(" "); - } else { - clearSelection(); - if (UIWidgetPtr parent = getParent()) - parent->focusNextChild(Fw::KeyboardFocusReason, true); - } - return true; - } else if(keyCode == Fw::KeyEnter && m_multiline && m_editable) { - appendCharacter('\n'); - return true; - } else if(keyCode == Fw::KeyUp && !m_shiftNavigation && m_multiline) { - moveCursorVertically(true); - return true; - } else if(keyCode == Fw::KeyDown && !m_shiftNavigation && m_multiline) { - moveCursorVertically(false); - return true; - } - } else if(keyboardModifiers == Fw::KeyboardCtrlModifier) { - if(keyCode == Fw::KeyV && m_editable) { - paste(g_window.getClipboardText()); - return true; - } else if(keyCode == Fw::KeyX && m_editable && m_selectable) { - if(hasSelection()) { - cut(); - return true; - } - } else if(keyCode == Fw::KeyC && m_selectable) { - if(hasSelection()) { - copy(); - return true; - } - } else if(keyCode == Fw::KeyA && m_selectable) { - if(m_text.length() > 0) { - selectAll(); - return true; - } - } - } else if(keyboardModifiers == Fw::KeyboardShiftModifier) { - if(keyCode == Fw::KeyTab && !m_shiftNavigation) { - if(UIWidgetPtr parent = getParent()) - parent->focusPreviousChild(Fw::KeyboardFocusReason, true); - return true; - } else if(keyCode == Fw::KeyRight || keyCode == Fw::KeyLeft || ((keyCode == Fw::KeyUp || keyCode == Fw::KeyDown) && m_multiline)) { - - int oldCursorPos = m_cursorPos; - - if(keyCode == Fw::KeyRight) // move cursor right - moveCursorHorizontally(true); - else if(keyCode == Fw::KeyLeft) // move cursor left - moveCursorHorizontally(false); - else if (keyCode == Fw::KeyUp && !m_shiftNavigation && m_multiline) - moveCursorVertically(true); - else if (keyCode == Fw::KeyDown && !m_shiftNavigation && m_multiline) - moveCursorVertically(false); - - if(m_shiftNavigation) - clearSelection(); - else { - if(!hasSelection()) - m_selectionReference = oldCursorPos; - setSelection(m_selectionReference, m_cursorPos); - } - return true; - } else if(keyCode == Fw::KeyHome) { // move cursor to first character - if(m_cursorPos != 0) { - setSelection(m_cursorPos, 0); - setCursorPos(0); - return true; - } - } else if(keyCode == Fw::KeyEnd) { // move cursor to last character - if(m_cursorPos != (int)m_text.length()) { - setSelection(m_cursorPos, m_text.length()); - setCursorPos(m_text.length()); - return true; - } - } - } - - return false; -} - -bool UITextEdit::onKeyText(const std::string& keyText) -{ - if(m_editable) { -#ifdef ANDROID - setText(keyText); - if (m_autoSubmit) { - InputEvent event; - event.reset(Fw::KeyDownInputEvent); - event.keyCode = Fw::KeyEnter; - g_ui.inputEvent(event); - event.reset(Fw::KeyUpInputEvent); - event.keyCode = Fw::KeyEnter; - g_ui.inputEvent(event); - } -#else - appendText(keyText); -#endif - return true; - } - return false; -} - -bool UITextEdit::onMousePress(const Point& mousePos, Fw::MouseButton button) -{ - if(UIWidget::onMousePress(mousePos, button)) - return true; - - if(button == Fw::MouseLeftButton) { -#ifdef ANDROID - if (m_editable) { - g_window.showTextEditor("Edit text", "", m_text, m_multiline ? 1 : 0); - return true; - } -#else - int pos = getTextPos(mousePos); - if(pos >= 0) { - setCursorPos(pos); - - if(m_selectable) { - m_selectionReference = pos; - setSelection(pos, pos); - } - } -#endif - return true; - } - return false; -} - -bool UITextEdit::onMouseRelease(const Point& mousePos, Fw::MouseButton button) -{ - return UIWidget::onMouseRelease(mousePos, button); -} - -bool UITextEdit::onMouseMove(const Point& mousePos, const Point& mouseMoved) -{ - if(UIWidget::onMouseMove(mousePos, mouseMoved)) - return true; - - if(m_selectable && isPressed()) { - int pos = getTextPos(mousePos); - if(pos >= 0 && m_selectionReference != -1) { - setSelection(m_selectionReference, pos); - setCursorPos(pos); - } - return true; - } - return false; -} - -bool UITextEdit::onDoubleClick(const Point& mousePos) -{ - if(UIWidget::onDoubleClick(mousePos)) - return true; - - int pos = getTextPos(mousePos); - if (m_selectable && pos >= 0 && m_text.length() > 0) { - m_selectionReference = -1; - int firstSpace = 0; - int lastSpace = m_text.length(); - for (int i = 0; i < pos && i < (int)m_text.length(); ++i) { - if (m_text[i] == ' ' || m_text[i] == '\t' || m_text[i] == '\n') { - firstSpace = i + 1; - } - } - for (int i = pos; i < (int)m_text.length(); ++i) { - if (m_text[i] == ' ' || m_text[i] == '\t' || m_text[i] == '\n') { - lastSpace = i; - break; - } - } - setSelection(firstSpace, lastSpace); - return true; - } - - return false; -} - -void UITextEdit::onTextAreaUpdate(const Point& offset, const Size& visibleSize, const Size& totalSize) -{ - callLuaField("onTextAreaUpdate", offset, visibleSize, totalSize); -} diff --git a/src/framework/ui/uitextedit.h b/src/framework/ui/uitextedit.h deleted file mode 100644 index 9c9a485..0000000 --- a/src/framework/ui/uitextedit.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UITEXTEDIT_H -#define UITEXTEDIT_H - -#include "uiwidget.h" - -// @bindclass -class UITextEdit : public UIWidget -{ -public: - UITextEdit(); - - void drawSelf(Fw::DrawPane drawPane); - -private: - void update(bool focusCursor = false); - -public: - void setCursorPos(int pos); - void setSelection(int start, int end); - void setCursorVisible(bool enable) { m_cursorVisible = enable; } - void setChangeCursorImage(bool enable) { m_changeCursorImage = enable; } - void setTextHidden(bool hidden); - void setValidCharacters(const std::string validCharacters) { m_validCharacters = validCharacters; } - void setShiftNavigation(bool enable) { m_shiftNavigation = enable; } - void setMultiline(bool enable) { m_multiline = enable; } - void setMaxLength(uint maxLength) { m_maxLength = maxLength; } - void setTextVirtualOffset(const Point& offset); - void setEditable(bool editable) { m_editable = editable; } - void setSelectable(bool selectable) { m_selectable = selectable; } - void setSelectionColor(const Color& color) { m_selectionColor = color; } - void setSelectionBackgroundColor(const Color& color) { m_selectionBackgroundColor = color; } - void setAutoScroll(bool autoScroll) { m_autoScroll = autoScroll; } - void setAutoSubmit(bool autoSubmit) { m_autoSubmit = autoSubmit; } - - void moveCursorHorizontally(bool right); - void moveCursorVertically(bool up); - void appendText(std::string text); - void appendCharacter(char c); - void removeCharacter(bool right); - void blinkCursor(); - - void del(bool right = false); - void paste(const std::string& text); - std::string copy(); - std::string cut(); - void selectAll() { setSelection(0, m_text.length()); } - void clearSelection() { setSelection(0, 0); } - - void wrapText(); - std::string getDisplayedText(); - std::string getSelection(); - int getTextPos(Point pos); - int getCursorPos() { return m_cursorPos; } - Point getTextVirtualOffset() { return m_textVirtualOffset; } - Size getTextVirtualSize() { return m_textVirtualSize; } - Size getTextTotalSize() { return m_textTotalSize; } - uint getMaxLength() { return m_maxLength; } - int getSelectionStart() { return m_selectionStart; } - int getSelectionEnd() { return m_selectionEnd; } - Color getSelectionColor() { return m_selectionColor; } - Color getSelectionBackgroundColor() { return m_selectionBackgroundColor; } - bool hasSelection() { return m_selectionEnd - m_selectionStart > 0; } - bool isCursorVisible() { return m_cursorVisible; } - bool isChangingCursorImage() { return m_changeCursorImage; } - bool isTextHidden() { return m_textHidden; } - bool isShiftNavigation() { return m_shiftNavigation; } - bool isMultiline() { return m_multiline; } - bool isEditable() { return m_editable; } - bool isSelectable() { return m_selectable; } - bool isAutoScrolling() { return m_autoScroll; } - -protected: - void updateText(); - - virtual void onHoverChange(bool hovered); - virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect); - virtual void onFocusChange(bool focused, Fw::FocusReason reason); - virtual bool onKeyText(const std::string& keyText); - virtual bool onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks); - virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button); - virtual bool onMouseRelease(const Point& mousePos, Fw::MouseButton button); - virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved); - virtual bool onDoubleClick(const Point& mousePos); - virtual void onTextAreaUpdate(const Point& vitualOffset, const Size& virtualSize, const Size& totalSize); - -private: - void disableUpdates() { m_updatesEnabled = false; } - void enableUpdates() { m_updatesEnabled = true; } - void recacheGlyphs() { m_glyphsMustRecache = true; } - - Rect m_drawArea; - int m_cursorPos; - Point m_textVirtualOffset; - Size m_textVirtualSize; - Size m_textTotalSize; - ticks_t m_cursorTicks; - bool m_textHidden; - bool m_shiftNavigation; - bool m_multiline; - bool m_cursorInRange; - bool m_cursorVisible; - bool m_editable; - bool m_changeCursorImage; - std::string m_validCharacters; - uint m_maxLength; - bool m_updatesEnabled; - bool m_autoScroll; - bool m_autoSubmit; - - bool m_selectable; - int m_selectionReference; - int m_selectionStart; - int m_selectionEnd; - - Color m_selectionColor; - Color m_selectionBackgroundColor; - - std::vector m_glyphsCoords; - std::vector m_glyphsTexCoords; - - CoordsBuffer m_glyphsTextCoordsBuffer; - CoordsBuffer m_glyphsSelectCoordsBuffer; - bool m_glyphsMustRecache; -}; - -#endif diff --git a/src/framework/ui/uitranslator.cpp b/src/framework/ui/uitranslator.cpp deleted file mode 100644 index abb9b8e..0000000 --- a/src/framework/ui/uitranslator.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uitranslator.h" -#include -#include - -Fw::AlignmentFlag Fw::translateAlignment(std::string aligment) -{ - boost::to_lower(aligment); - boost::erase_all(aligment, " "); - if(aligment == "topleft") - return Fw::AlignTopLeft; - else if(aligment == "topright") - return Fw::AlignTopRight; - else if(aligment == "bottomleft") - return Fw::AlignBottomLeft; - else if(aligment == "bottomright") - return Fw::AlignBottomRight; - else if(aligment == "left") - return Fw::AlignLeftCenter; - else if(aligment == "right") - return Fw::AlignRightCenter; - else if(aligment == "top") - return Fw::AlignTopCenter; - else if(aligment == "bottom") - return Fw::AlignBottomCenter; - else if(aligment == "center") - return Fw::AlignCenter; - return Fw::AlignNone; -} - -Fw::AnchorEdge Fw::translateAnchorEdge(std::string anchorEdge) -{ - boost::to_lower(anchorEdge); - boost::erase_all(anchorEdge, " "); - if(anchorEdge == "left") - return Fw::AnchorLeft; - else if(anchorEdge == "right") - return Fw::AnchorRight; - else if(anchorEdge == "top") - return Fw::AnchorTop; - else if(anchorEdge == "bottom") - return Fw::AnchorBottom; - else if(anchorEdge == "horizontalcenter") - return Fw::AnchorHorizontalCenter; - else if(anchorEdge == "verticalcenter") - return Fw::AnchorVerticalCenter; - return Fw::AnchorNone; -} - -Fw::WidgetState Fw::translateState(std::string state) -{ - boost::to_lower(state); - boost::trim(state); - if(state == "active") - return Fw::ActiveState; - else if(state == "focus") - return Fw::FocusState; - else if(state == "hover") - return Fw::HoverState; - else if(state == "pressed") - return Fw::PressedState; - else if(state == "checked") - return Fw::CheckedState; - else if(state == "disabled") - return Fw::DisabledState; - else if(state == "on") - return Fw::OnState; - else if(state == "first") - return Fw::FirstState; - else if(state == "middle") - return Fw::MiddleState; - else if(state == "last") - return Fw::LastState; - else if(state == "alternate") - return Fw::AlternateState; - else if(state == "dragging") - return Fw::DraggingState; - else if (state == "hidden") - return Fw::HiddenState; - else if (state == "mobile") - return Fw::MobileState; - return Fw::InvalidState; -} - -Fw::AutoFocusPolicy Fw::translateAutoFocusPolicy(std::string policy) -{ - boost::to_lower(policy); - boost::trim(policy); - if(policy == "first") - return Fw::AutoFocusFirst; - else if(policy == "last") - return Fw::AutoFocusLast; - return Fw::AutoFocusNone; -} diff --git a/src/framework/ui/uitranslator.h b/src/framework/ui/uitranslator.h deleted file mode 100644 index 1c15836..0000000 --- a/src/framework/ui/uitranslator.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef TRANSLATOR_H -#define TRANSLATOR_H - -#include "../const.h" -#include - -namespace Fw { - -AlignmentFlag translateAlignment(std::string aligment); -AnchorEdge translateAnchorEdge(std::string anchorEdge); -WidgetState translateState(std::string state); -AutoFocusPolicy translateAutoFocusPolicy(std::string policy); - -}; - -#endif diff --git a/src/framework/ui/uiverticallayout.cpp b/src/framework/ui/uiverticallayout.cpp deleted file mode 100644 index 28e420a..0000000 --- a/src/framework/ui/uiverticallayout.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiverticallayout.h" -#include "uiwidget.h" -#include - -void UIVerticalLayout::applyStyle(const OTMLNodePtr& styleNode) -{ - UIBoxLayout::applyStyle(styleNode); - - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "align-bottom") - setAlignBottom(node->value()); - } -} - -bool UIVerticalLayout::internalUpdate() -{ - bool changed = false; - - UIWidgetPtr parentWidget = getParentWidget(); - if(!parentWidget) - return false; - - UIWidgetList widgets = parentWidget->getChildren(); - - if(m_alignBottom) - std::reverse(widgets.begin(), widgets.end()); - - Rect paddingRect = parentWidget->getPaddingRect(); - Point pos = (m_alignBottom) ? paddingRect .bottomLeft() : paddingRect.topLeft(); - int preferredHeight = 0; - int gap; - - for(const UIWidgetPtr& widget : widgets) { - if(!widget->isExplicitlyVisible()) - continue; - - Size size = widget->getSize(); - - gap = (m_alignBottom) ? -(widget->getMarginBottom()+widget->getHeight()) : widget->getMarginTop(); - pos.y += gap; - preferredHeight += gap; - - if(widget->isFixedSize()) { - // center it - if(widget->getTextAlign() & Fw::AlignLeft) { - pos.x = paddingRect.left() + widget->getMarginLeft(); - } else if(widget->getTextAlign() & Fw::AlignLeft) { - pos.x = paddingRect.bottom() - widget->getHeight() - widget->getMarginBottom(); - pos.x = std::max(pos.x, paddingRect.left()); - } else { - pos.x = paddingRect.left() + (paddingRect.width() - (widget->getMarginLeft() + widget->getWidth() + widget->getMarginRight()))/2; - pos.x = std::max(pos.x, paddingRect.left()); - } - } else { - // expand width - size.setWidth(paddingRect.width() - (widget->getMarginLeft() + widget->getMarginRight())); - pos.x = paddingRect.left() + (paddingRect.width() - size.width())/2; - } - - if(widget->setRect(Rect(pos - parentWidget->getVirtualOffset(), size))) - changed = true; - - gap = (m_alignBottom) ? -widget->getMarginTop() : (widget->getHeight() + widget->getMarginBottom()); - gap += m_spacing; - pos.y += gap; - preferredHeight += gap; - } - - preferredHeight -= m_spacing; - preferredHeight += parentWidget->getPaddingTop() + parentWidget->getPaddingBottom(); - - if(m_fitChildren && preferredHeight != parentWidget->getHeight()) { - // must set the preferred width later - g_dispatcher.addEvent([=] { - parentWidget->setHeight(preferredHeight); - }); - } - - return changed; -} diff --git a/src/framework/ui/uiverticallayout.h b/src/framework/ui/uiverticallayout.h deleted file mode 100644 index 64d2c31..0000000 --- a/src/framework/ui/uiverticallayout.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIVERTICALLAYOUT_H -#define UIVERTICALLAYOUT_H - -#include "uiboxlayout.h" - -// @bindclass -class UIVerticalLayout : public UIBoxLayout -{ -public: - UIVerticalLayout(UIWidgetPtr parentWidget) : UIBoxLayout(parentWidget) { } - - void applyStyle(const OTMLNodePtr& styleNode); - - void setAlignBottom(bool aliginBottom) { m_alignBottom = aliginBottom; update(); } - bool isAlignBottom() { return m_alignBottom; } - - bool isUIVerticalLayout() { return true; } - -protected: - bool internalUpdate(); - - stdext::boolean m_alignBottom; -}; - -#endif diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp deleted file mode 100644 index fc1326b..0000000 --- a/src/framework/ui/uiwidget.cpp +++ /dev/null @@ -1,1772 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiwidget.h" -#include "uimanager.h" -#include "uianchorlayout.h" -#include "uitranslator.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -UIWidget::UIWidget() -{ - // source for stats - m_source = g_lua.getSource(2); - // find correct source - int level = 3; - while((m_source.find("corelib") != std::string::npos || m_source.find("gamelib") != std::string::npos || m_source.find("[C]") != std::string::npos) && level < 8) { - std::string tmp_src = g_lua.getSource(level); - if (tmp_src.length() <= 3) break; - m_source = tmp_src; - level += 1; - } - - m_lastFocusReason = Fw::ActiveFocusReason; - m_states = Fw::DefaultState; - m_autoFocusPolicy = Fw::AutoFocusLast; - m_clickTimer.stop(); - m_autoRepeatDelay = 500; - - initBaseStyle(); - initText(); - initImage(); - - g_stats.addWidget(this); -} - -UIWidget::~UIWidget() -{ -#ifndef NDEBUG - VALIDATE(!g_app.isTerminated()); - if(!m_destroyed) - g_logger.warning(stdext::format("widget '%s' was not explicitly destroyed", m_id)); -#endif - - g_stats.removeWidget(this); -} - -void UIWidget::draw(const Rect& visibleRect, Fw::DrawPane drawPane) -{ - size_t drawQueueStart = g_drawQueue->size(); - - drawSelf(drawPane); - if (m_clipping) { - g_drawQueue->setClip(drawQueueStart, visibleRect); - } - - if(m_children.size() > 0) { - size_t drawQueueChildStart = g_drawQueue->size(); - drawChildren(visibleRect, drawPane); - if (m_clipping) { - g_drawQueue->setClip(drawQueueChildStart, visibleRect.intersection(getPaddingRect())); - } - } - - if (getOpacity() < 0.99f) { - g_drawQueue->setOpacity(drawQueueStart, getOpacity()); - } - - if (m_rotation < -0.1f || m_rotation > 0.1f) { - g_drawQueue->setRotation(drawQueueStart, m_rect.center(), m_rotation * (Fw::pi / 180.0)); - } -} - -void UIWidget::drawSelf(Fw::DrawPane drawPane) -{ - if(drawPane != Fw::ForegroundPane) - return; - - // draw style components in order - if(m_backgroundColor.aF() > Fw::MIN_ALPHA) { - Rect backgroundDestRect = m_rect; - backgroundDestRect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left); - drawBackground(m_rect); - } - - drawImage(m_rect); - drawIcon(m_rect); - drawText(m_rect); - drawBorder(m_rect); -} - -void UIWidget::drawChildren(const Rect& visibleRect, Fw::DrawPane drawPane) -{ - // draw children - for(const UIWidgetPtr& child : m_children) { - // render only visible children with a valid rect inside parent rect - if(!child->isExplicitlyVisible() || !child->getRect().isValid() || child->getOpacity() < Fw::MIN_ALPHA) - continue; - - Rect childVisibleRect = visibleRect.intersection(child->getRect()); - if(!childVisibleRect.isValid()) - continue; - - child->draw(childVisibleRect, drawPane); - - // debug draw box - if(g_ui.isDrawingDebugBoxes() && drawPane == Fw::ForegroundPane) { - g_drawQueue->addBoundingRect(child->getRect(), 1, Color::green); - if (m_font) { - m_font->drawText(child->getId(), child->getPosition() + Point(2, 0), Color::red); - } - } - } -} - -void UIWidget::addChild(const UIWidgetPtr& child) -{ - if(!child) { - g_logger.traceWarning("attempt to add a null child into a UIWidget"); - return; - } - - if(child->isDestroyed()) { - g_logger.traceWarning("attemp to add a destroyed child into a UIWidget"); - return; - } - - if(hasChild(child)) { - g_logger.traceWarning("attempt to add a child again into a UIWidget"); - return; - } - - UIWidgetPtr oldLastChild = getLastChild(); - - m_children.push_back(child); - child->setParent(static_self_cast()); - - // create default layout - if(!m_layout) - m_layout = UIAnchorLayoutPtr(new UIAnchorLayout(static_self_cast())); - - // add to layout and updates it - m_layout->addWidget(child); - - // update new child states - child->updateStates(); - - // update old child index states - if(oldLastChild) { - oldLastChild->updateState(Fw::MiddleState); - oldLastChild->updateState(Fw::LastState); - } - - g_ui.onWidgetAppear(child); -} - -void UIWidget::onChildIdChange(const UIWidgetPtr& child) -{ - if (!hasChild(child)) { - g_logger.traceWarning("onChildIdChange: invalid child"); - return; - } -} - -void UIWidget::insertChild(int index, const UIWidgetPtr& child) -{ - if(!child) { - g_logger.traceWarning("attempt to insert a null child into a UIWidget"); - return; - } - - if(hasChild(child)) { - g_logger.traceWarning("attempt to insert a child again into a UIWidget"); - return; - } - - index = index <= 0 ? (m_children.size() + index) : index-1; - - if(!(index >= 0 && (uint)index <= m_children.size())) { - //g_logger.traceWarning("attempt to insert a child UIWidget into an invalid index, using nearest index..."); - index = stdext::clamp(index, 0, (int)m_children.size()); - } - - // retrieve child by index - auto it = m_children.begin() + index; - m_children.insert(it, child); - child->setParent(static_self_cast()); - - // create default layout if needed - if(!m_layout) - m_layout = UIAnchorLayoutPtr(new UIAnchorLayout(static_self_cast())); - - // add to layout and updates it - m_layout->addWidget(child); - - // update new child states - child->updateStates(); - updateChildrenIndexStates(); - - g_ui.onWidgetAppear(child); -} - -void UIWidget::removeChild(UIWidgetPtr child) -{ - // remove from children list - if(hasChild(child)) { - // defocus if needed - bool focusAnother = false; - if(m_focusedChild == child) { - focusChild(nullptr, Fw::ActiveFocusReason); - focusAnother = true; - } - - if(isChildLocked(child)) - unlockChild(child); - - auto it = std::find(m_children.begin(), m_children.end(), child); - m_children.erase(it); - - // reset child parent - VALIDATE(child->getParent() == static_self_cast()); - child->setParent(nullptr); - - m_layout->removeWidget(child); - - // update child states - child->updateStates(); - updateChildrenIndexStates(); - - if(m_autoFocusPolicy != Fw::AutoFocusNone && focusAnother && !m_focusedChild) - focusPreviousChild(Fw::ActiveFocusReason, true); - - g_ui.onWidgetDisappear(child); - } else - g_logger.traceError("attempt to remove an unknown child from a UIWidget"); -} - - -void UIWidget::focusChild(const UIWidgetPtr& child, Fw::FocusReason reason) -{ - if(m_destroyed) - return; - - if(child == m_focusedChild) - return; - - if(child && !hasChild(child)) { - g_logger.error("attempt to focus an unknown child in a UIWidget"); - return; - } - - UIWidgetPtr oldFocused = m_focusedChild; - m_focusedChild = child; - - if(child) { - child->setLastFocusReason(reason); - child->updateState(Fw::FocusState); - child->updateState(Fw::ActiveState); - - child->onFocusChange(true, reason); - } - - if(oldFocused) { - oldFocused->setLastFocusReason(reason); - oldFocused->updateState(Fw::FocusState); - oldFocused->updateState(Fw::ActiveState); - - oldFocused->onFocusChange(false, reason); - } - - onChildFocusChange(child, oldFocused, reason); -} - -void UIWidget::focusNextChild(Fw::FocusReason reason, bool rotate) -{ - if(m_destroyed) - return; - - UIWidgetPtr toFocus; - - if(rotate) { - UIWidgetList rotatedChildren(m_children); - - if(m_focusedChild) { - auto focusedIt = std::find(rotatedChildren.begin(), rotatedChildren.end(), m_focusedChild); - if(focusedIt != rotatedChildren.end()) { - std::rotate(rotatedChildren.begin(), focusedIt, rotatedChildren.end()); - rotatedChildren.pop_front(); - } - } - - // finds next child to focus - for(const UIWidgetPtr& child : rotatedChildren) { - if(child->isFocusable() && child->isExplicitlyEnabled() && child->isVisible()) { - toFocus = child; - break; - } - } - } else { - auto it = m_children.begin(); - if(m_focusedChild) - it = std::find(m_children.begin(), m_children.end(), m_focusedChild); - - for(; it != m_children.end(); ++it) { - const UIWidgetPtr& child = *it; - if(child != m_focusedChild && child->isFocusable() && child->isExplicitlyEnabled() && child->isVisible()) { - toFocus = child; - break; - } - } - } - - if(toFocus && toFocus != m_focusedChild) - focusChild(toFocus, reason); -} - -void UIWidget::focusPreviousChild(Fw::FocusReason reason, bool rotate) -{ - if(m_destroyed) - return; - - UIWidgetPtr toFocus; - if(rotate) { - UIWidgetList rotatedChildren(m_children); - std::reverse(rotatedChildren.begin(), rotatedChildren.end()); - - if(m_focusedChild) { - auto focusedIt = std::find(rotatedChildren.begin(), rotatedChildren.end(), m_focusedChild); - if(focusedIt != rotatedChildren.end()) { - std::rotate(rotatedChildren.begin(), focusedIt, rotatedChildren.end()); - rotatedChildren.pop_front(); - } - } - - // finds next child to focus - for(const UIWidgetPtr& child : rotatedChildren) { - if(child->isFocusable() && child->isExplicitlyEnabled() && child->isVisible()) { - toFocus = child; - break; - } - } - } else { - auto it = m_children.rbegin(); - if(m_focusedChild) - it = std::find(m_children.rbegin(), m_children.rend(), m_focusedChild); - - for(; it != m_children.rend(); ++it) { - const UIWidgetPtr& child = *it; - if(child != m_focusedChild && child->isFocusable() && child->isExplicitlyEnabled() && child->isVisible()) { - toFocus = child; - break; - } - } - } - - if(toFocus && toFocus != m_focusedChild) - focusChild(toFocus, reason); -} - -void UIWidget::lowerChild(UIWidgetPtr child) -{ - if(m_destroyed) - return; - - if(!child) - return; - - // remove and push child again - auto it = std::find(m_children.begin(), m_children.end(), child); - if(it == m_children.end()) { - g_logger.traceError("cannot find child"); - return; - } - - m_children.erase(it); - m_children.push_front(child); - updateChildrenIndexStates(); -} - -void UIWidget::raiseChild(UIWidgetPtr child) -{ - if(m_destroyed) - return; - - if(!child) - return; - - // remove and push child again - auto it = std::find(m_children.begin(), m_children.end(), child); - if(it == m_children.end()) { - g_logger.traceError("cannot find child"); - return; - } - m_children.erase(it); - m_children.push_back(child); - updateChildrenIndexStates(); -} - -void UIWidget::moveChildToIndex(const UIWidgetPtr& child, int index) -{ - if(m_destroyed) - return; - - if(!child) - return; - - if((uint)index - 1 >= m_children.size()) { - g_logger.traceError(stdext::format("moving %s to index %d on %s", child->getId(), index, m_id)); - return; - } - - // remove and push child again - auto it = std::find(m_children.begin(), m_children.end(), child); - if(it == m_children.end()) { - g_logger.traceError("cannot find child"); - return; - } - m_children.erase(it); - if (index >= (int)m_children.size() + 1) { - m_children.push_back(child); - } else { - m_children.insert(m_children.begin() + index - 1, child); - } - - updateChildrenIndexStates(); - updateLayout(); -} - -void UIWidget::reorderChildren(const std::vector& childrens) { - if (m_children.size() != childrens.size()) { - g_logger.error("Invalid parameter for reorderChildren"); - return; - } - - m_children.clear(); - for (size_t i = 0; i < childrens.size(); ++i) { - m_children.push_back(childrens[i]); - } - - updateChildrenIndexStates(); - updateLayout(); -} - -void UIWidget::lockChild(const UIWidgetPtr& child) -{ - if(m_destroyed) - return; - - if(!child) - return; - - if(!hasChild(child)) { - g_logger.traceError("cannot find child"); - return; - } - - // prevent double locks - if(isChildLocked(child)) - unlockChild(child); - - // disable all other children - for(const UIWidgetPtr& otherChild : m_children) { - if(otherChild == child) - child->setEnabled(true); - else - otherChild->setEnabled(false); - } - - m_lockedChildren.push_front(child); - - // lock child focus - if(child->isFocusable()) - focusChild(child, Fw::ActiveFocusReason); -} - -void UIWidget::unlockChild(const UIWidgetPtr& child) -{ - if(m_destroyed) - return; - - if(!child) - return; - - if(!hasChild(child)) { - g_logger.traceError("cannot find child"); - return; - } - - auto it = std::find(m_lockedChildren.begin(), m_lockedChildren.end(), child); - if(it == m_lockedChildren.end()) - return; - - m_lockedChildren.erase(it); - - // find new child to lock - UIWidgetPtr lockedChild; - if(m_lockedChildren.size() > 0) { - lockedChild = m_lockedChildren.front(); - VALIDATE(hasChild(lockedChild)); - } - - for(const UIWidgetPtr& otherChild : m_children) { - // lock new child - if(lockedChild) { - if(otherChild == lockedChild) - lockedChild->setEnabled(true); - else - otherChild->setEnabled(false); - } - // else unlock all - else - otherChild->setEnabled(true); - } - - if(lockedChild) { - if(lockedChild->isFocusable()) - focusChild(lockedChild, Fw::ActiveFocusReason); - } -} - -void UIWidget::mergeStyle(const OTMLNodePtr& styleNode) -{ - applyStyle(styleNode); - std::string name = m_style->tag(); - std::string source = m_style->source(); - m_style->merge(styleNode); - m_style->setTag(name); - m_style->setSource(source); - updateStyle(); -} - -void UIWidget::applyStyle(const OTMLNodePtr& styleNode) -{ - if(m_destroyed) - return; - - if(styleNode->size() == 0) - return; - - m_loadingStyle = true; - try { - // translate ! style tags - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag()[0] == '!') { - std::string tag = node->tag().substr(1); - std::string code = stdext::format("tostring(%s)", node->value()); - std::string origin = std::string("@") + node->source() + ": [" + node->tag() + "]"; - g_lua.evaluateExpression(code, origin); - std::string value = g_lua.popString(); - - node->setTag(tag); - node->setValue(value); - } - } - - onStyleApply(styleNode->tag(), styleNode); - callLuaField("onStyleApply", styleNode->tag(), styleNode); - - if(m_firstOnStyle) { - UIWidgetPtr parent = getParent(); - if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled() && - parent && ((!parent->getFocusedChild() && parent->getAutoFocusPolicy() == Fw::AutoFocusFirst) || - parent->getAutoFocusPolicy() == Fw::AutoFocusLast)) { - focus(); - } - } - - m_firstOnStyle = false; - } catch(stdext::exception& e) { - g_logger.traceError(stdext::format("failed to apply style to widget '%s': %s", m_id, e.what())); - } - m_loadingStyle = false; -} - -void UIWidget::addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge) -{ - if(m_destroyed) - return; - - if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) - anchorLayout->addAnchor(static_self_cast(), anchoredEdge, hookedWidgetId, hookedEdge); - else - g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); -} - -void UIWidget::removeAnchor(Fw::AnchorEdge anchoredEdge) -{ - addAnchor(anchoredEdge, "none", Fw::AnchorNone); -} - -void UIWidget::centerIn(const std::string& hookedWidgetId) -{ - if(m_destroyed) - return; - - if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) { - anchorLayout->addAnchor(static_self_cast(), Fw::AnchorHorizontalCenter, hookedWidgetId, Fw::AnchorHorizontalCenter); - anchorLayout->addAnchor(static_self_cast(), Fw::AnchorVerticalCenter, hookedWidgetId, Fw::AnchorVerticalCenter); - } else - g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); -} - -void UIWidget::fill(const std::string& hookedWidgetId) -{ - if(m_destroyed) - return; - - if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) { - anchorLayout->addAnchor(static_self_cast(), Fw::AnchorLeft, hookedWidgetId, Fw::AnchorLeft); - anchorLayout->addAnchor(static_self_cast(), Fw::AnchorRight, hookedWidgetId, Fw::AnchorRight); - anchorLayout->addAnchor(static_self_cast(), Fw::AnchorTop, hookedWidgetId, Fw::AnchorTop); - anchorLayout->addAnchor(static_self_cast(), Fw::AnchorBottom, hookedWidgetId, Fw::AnchorBottom); - } else - g_logger.traceError(stdext::format("cannot add anchors to widget '%s': the parent doesn't use anchors layout", m_id)); -} - -void UIWidget::breakAnchors() -{ - if(m_destroyed) - return; - - if(UIAnchorLayoutPtr anchorLayout = getAnchoredLayout()) - anchorLayout->removeAnchors(static_self_cast()); -} - -void UIWidget::updateParentLayout() -{ - if(m_destroyed) - return; - - if(UIWidgetPtr parent = getParent()) - parent->updateLayout(); - else - updateLayout(); -} - -void UIWidget::updateLayout() -{ - if(m_destroyed) - return; - - if(m_layout) - m_layout->update(); - - // children can affect the parent layout - if(UIWidgetPtr parent = getParent()) - if(UILayoutPtr parentLayout = parent->getLayout()) - parentLayout->updateLater(); -} - -void UIWidget::lock() -{ - if(m_destroyed) - return; - - if(UIWidgetPtr parent = getParent()) - parent->lockChild(static_self_cast()); -} - -void UIWidget::unlock() -{ - if(m_destroyed) - return; - - if(UIWidgetPtr parent = getParent()) - parent->unlockChild(static_self_cast()); -} - -void UIWidget::focus() -{ - if(m_destroyed) - return; - - if(!m_focusable) - return; - - if(UIWidgetPtr parent = getParent()) - parent->focusChild(static_self_cast(), Fw::ActiveFocusReason); -} - -void UIWidget::recursiveFocus(Fw::FocusReason reason) -{ - if(m_destroyed) - return; - - if(UIWidgetPtr parent = getParent()) { - if(m_focusable) - parent->focusChild(static_self_cast(), reason); - parent->recursiveFocus(reason); - } -} - -void UIWidget::lower() -{ - if(m_destroyed) - return; - - UIWidgetPtr parent = getParent(); - if(parent) - parent->lowerChild(static_self_cast()); -} - -void UIWidget::raise() -{ - if(m_destroyed) - return; - - UIWidgetPtr parent = getParent(); - if(parent) - parent->raiseChild(static_self_cast()); -} - -void UIWidget::grabMouse() -{ - if(m_destroyed) - return; - - g_ui.setMouseReceiver(static_self_cast()); -} - -void UIWidget::ungrabMouse() -{ - if(g_ui.getMouseReceiver() == static_self_cast()) - g_ui.resetMouseReceiver(); -} - -void UIWidget::grabKeyboard() -{ - if(m_destroyed) - return; - - g_ui.setKeyboardReceiver(static_self_cast()); -} - -void UIWidget::ungrabKeyboard() -{ - if(g_ui.getKeyboardReceiver() == static_self_cast()) - g_ui.resetKeyboardReceiver(); -} - -void UIWidget::bindRectToParent() -{ - if(m_destroyed) - return; - - Rect boundRect = m_rect; - UIWidgetPtr parent = getParent(); - if(parent) { - Rect parentRect = parent->getPaddingRect(); - boundRect.bind(parentRect); - } - - setRect(boundRect); -} - -void UIWidget::internalDestroy() -{ - if (!getText().empty()) { - setText("", true); - } - - m_destroyed = true; - m_visible = false; - m_enabled = false; - m_focusedChild = nullptr; - if(m_layout) { - m_layout->setParent(nullptr); - m_layout = nullptr; - } - m_parent = nullptr; - m_lockedChildren.clear(); - - for(const UIWidgetPtr& child : m_children) - child->internalDestroy(); - m_children.clear(); - - callLuaField("onDestroy"); - - releaseLuaFieldsTable(); - - g_ui.onWidgetDestroy(static_self_cast()); -} - -void UIWidget::destroy() -{ - if(m_destroyed) - g_logger.warning(stdext::format("attempt to destroy widget '%s' two times", m_id)); - - // hold itself reference - UIWidgetPtr self = static_self_cast(); - m_destroyed = true; - - // remove itself from parent - if(UIWidgetPtr parent = getParent()) - parent->removeChild(self); - internalDestroy(); -} - -void UIWidget::destroyChildren() -{ - UILayoutPtr layout = getLayout(); - if(layout) - layout->disableUpdates(); - - m_focusedChild = nullptr; - m_lockedChildren.clear(); - while (!m_children.empty()) { - UIWidgetPtr child = m_children.front(); - m_children.pop_front(); - child->setParent(nullptr); - m_layout->removeWidget(child); - child->destroy(); - } - - if(layout) - layout->enableUpdates(); -} - -void UIWidget::setId(const std::string& id) -{ - if(id != m_id) { - m_id = id; - callLuaField("onIdChange", id); - if (m_parent) { - m_parent->onChildIdChange(static_self_cast()); - } - } -} - -void UIWidget::setParent(const UIWidgetPtr& parent) -{ - // remove from old parent - UIWidgetPtr oldParent = getParent(); - - // the parent is already the same - if(oldParent == parent) - return; - - UIWidgetPtr self = static_self_cast(); - if(oldParent && oldParent->hasChild(self)) - oldParent->removeChild(self); - - // reset parent - m_parent.reset(); - - // set new parent - if(parent) { - m_parent = parent; - m_parentId = parent->getId(); - - // add to parent if needed - if(!parent->hasChild(self)) - parent->addChild(self); - } -} - -void UIWidget::setLayout(const UILayoutPtr& layout) -{ - if(!layout) - stdext::throw_exception("attempt to set a nil layout to a widget"); - - if(m_layout) - m_layout->disableUpdates(); - - layout->setParent(static_self_cast()); - layout->disableUpdates(); - - for(const UIWidgetPtr& child : m_children) { - if(m_layout) - m_layout->removeWidget(child); - layout->addWidget(child); - } - - if(m_layout) { - m_layout->enableUpdates(); - m_layout->setParent(nullptr); - m_layout->update(); - } - - layout->enableUpdates(); - m_layout = layout; -} - -bool UIWidget::setRect(const Rect& rect) -{ - /* - if(rect.width() > 8192 || rect.height() > 8192) { - g_logger.error(stdext::format("attempt to set huge rect size (%s) for %s", stdext::to_string(rect), m_id)); - return false; - } - */ - // only update if the rect really changed - Rect oldRect = m_rect; - if(rect == oldRect) - return false; - - m_rect = rect; - - // updates own layout - updateLayout(); - - // avoid massive update events - if(!m_updateEventScheduled) { - UIWidgetPtr self = static_self_cast(); - g_dispatcher.addEvent([self, oldRect]() { - self->m_updateEventScheduled = false; - if(oldRect != self->getRect()) - self->onGeometryChange(oldRect, self->getRect()); - }); - m_updateEventScheduled = true; - } - - // update hovered widget when moved behind mouse area - if(containsPoint(g_window.getMousePosition())) - g_ui.updateHoveredWidget(); - - return true; -} - -void UIWidget::setStyle(const std::string& styleName) -{ - OTMLNodePtr styleNode = g_ui.getStyle(styleName); - if(!styleNode) { - g_logger.traceError(stdext::format("unable to retrieve style '%s': not a defined style", styleName)); - return; - } - styleNode = styleNode->clone(); - applyStyle(styleNode); - m_style = styleNode; - updateStyle(); -} - -void UIWidget::setStyleFromNode(const OTMLNodePtr& styleNode) -{ - applyStyle(styleNode); - m_style = styleNode; - updateStyle(); -} - -void UIWidget::setEnabled(bool enabled) -{ - if(enabled != m_enabled) { - m_enabled = enabled; - - updateState(Fw::DisabledState); - updateState(Fw::ActiveState); - } -} - -void UIWidget::setVisible(bool visible) -{ - if(m_visible != visible) { - m_visible = visible; - - // hiding a widget make it lose focus - if(!visible && isFocused()) { - if(UIWidgetPtr parent = getParent()) - parent->focusPreviousChild(Fw::ActiveFocusReason, true); - } - - // visibility can change change parent layout - updateParentLayout(); - - updateState(Fw::ActiveState); - updateState(Fw::HiddenState); - - // visibility can change the current hovered widget - if(visible) - g_ui.onWidgetAppear(static_self_cast()); - else - g_ui.onWidgetDisappear(static_self_cast()); - } -} - -void UIWidget::setOn(bool on) -{ - setState(Fw::OnState, on); -} - -void UIWidget::setChecked(bool checked) -{ - if(setState(Fw::CheckedState, checked)) - callLuaField("onCheckChange", checked); -} - -void UIWidget::setFocusable(bool focusable) -{ - if(m_focusable != focusable) { - m_focusable = focusable; - - // make parent focus another child - if(UIWidgetPtr parent = getParent()) { - if(!focusable && isFocused()) { - parent->focusPreviousChild(Fw::ActiveFocusReason, true); - } else if(focusable && !parent->getFocusedChild() && parent->getAutoFocusPolicy() != Fw::AutoFocusNone) { - focus(); - } - } - } -} - -void UIWidget::setPhantom(bool phantom) -{ - m_phantom = phantom; -} - -void UIWidget::setDraggable(bool draggable) -{ - m_draggable = draggable; -} - -void UIWidget::setFixedSize(bool fixed) -{ - m_fixedSize = fixed; - updateParentLayout(); -} - -void UIWidget::setLastFocusReason(Fw::FocusReason reason) -{ - m_lastFocusReason = reason; -} - -void UIWidget::setAutoFocusPolicy(Fw::AutoFocusPolicy policy) -{ - m_autoFocusPolicy = policy; -} - -void UIWidget::setVirtualOffset(const Point& offset) -{ - m_virtualOffset = offset; - if(m_layout) - m_layout->update(); -} - -bool UIWidget::isAnchored() -{ - if(UIWidgetPtr parent = getParent()) - if(UIAnchorLayoutPtr anchorLayout = parent->getAnchoredLayout()) - return anchorLayout->hasAnchors(static_self_cast()); - return false; -} - -bool UIWidget::isChildLocked(const UIWidgetPtr& child) -{ - auto it = std::find(m_lockedChildren.begin(), m_lockedChildren.end(), child); - return it != m_lockedChildren.end(); -} - -bool UIWidget::hasChild(const UIWidgetPtr& child) -{ - auto it = std::find(m_children.begin(), m_children.end(), child); - if(it != m_children.end()) - return true; - return false; -} - -int UIWidget::getChildIndex(const UIWidgetPtr& child) -{ - int index = 1; - for(auto it = m_children.begin(); it != m_children.end(); ++it) { - if(*it == child) - return index; - ++index; - } - return -1; -} - -Rect UIWidget::getPaddingRect() -{ - Rect rect = m_rect; - rect.expand(-m_padding.top, -m_padding.right, -m_padding.bottom, -m_padding.left); - return rect; -} - -Rect UIWidget::getMarginRect() -{ - Rect rect = m_rect; - rect.expand(m_margin.top, m_margin.right, m_margin.bottom, m_margin.left); - return rect; -} - -Rect UIWidget::getChildrenRect() -{ - Rect childrenRect; - for(const UIWidgetPtr& child : m_children) { - if(!child->isExplicitlyVisible() || !child->getRect().isValid()) - continue; - Rect marginRect = child->getMarginRect(); - if(!childrenRect.isValid()) - childrenRect = marginRect; - else - childrenRect = childrenRect.united(marginRect); - } - - Rect myClippingRect = getPaddingRect(); - if(!childrenRect.isValid()) - childrenRect = myClippingRect; - else { - if(childrenRect.width() < myClippingRect.width()) - childrenRect.setWidth(myClippingRect.width()); - if(childrenRect.height() < myClippingRect.height()) - childrenRect.setHeight(myClippingRect.height()); - } - return childrenRect; -} - -UIAnchorLayoutPtr UIWidget::getAnchoredLayout() -{ - UIWidgetPtr parent = getParent(); - if(!parent) - return nullptr; - - UILayoutPtr layout = parent->getLayout(); - if(layout->isUIAnchorLayout()) - return layout->static_self_cast(); - return nullptr; -} - -UIWidgetPtr UIWidget::getRootParent() -{ - if(UIWidgetPtr parent = getParent()) - return parent->getRootParent(); - else - return static_self_cast(); -} - -UIWidgetPtr UIWidget::getChildAfter(const UIWidgetPtr& relativeChild) -{ - auto it = std::find(m_children.begin(), m_children.end(), relativeChild); - if(it != m_children.end() && ++it != m_children.end()) - return *it; - return nullptr; -} - -UIWidgetPtr UIWidget::getChildBefore(const UIWidgetPtr& relativeChild) -{ - auto it = std::find(m_children.rbegin(), m_children.rend(), relativeChild); - if(it != m_children.rend() && ++it != m_children.rend()) - return *it; - return nullptr; -} - -UIWidgetPtr UIWidget::getChildById(const std::string& childId) -{ - for(const UIWidgetPtr& child : m_children) { - if(child->getId() == childId) - return child; - } - return nullptr; -} - -UIWidgetPtr UIWidget::getChildByPos(const Point& childPos) -{ - if(!containsPaddingPoint(childPos)) - return nullptr; - - for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { - const UIWidgetPtr& child = (*it); - if(child->isExplicitlyVisible() && child->containsPoint(childPos)) - return child; - } - - return nullptr; -} - -UIWidgetPtr UIWidget::getChildByIndex(int index) -{ - index = index <= 0 ? (m_children.size() + index) : index-1; - if(index >= 0 && (uint)index < m_children.size()) - return m_children.at(index); - return nullptr; -} - -UIWidgetPtr UIWidget::recursiveGetChildById(const std::string& id) -{ - UIWidgetPtr widget = getChildById(id); - if(!widget) { - for(const UIWidgetPtr& child : m_children) { - widget = child->recursiveGetChildById(id); - if(widget) - break; - } - } - return widget; -} - -UIWidgetPtr UIWidget::recursiveGetChildByPos(const Point& childPos, bool wantsPhantom) -{ - if(!containsPaddingPoint(childPos)) - return nullptr; - - for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { - const UIWidgetPtr& child = (*it); - if(child->isExplicitlyVisible() && child->containsPoint(childPos)) { - UIWidgetPtr subChild = child->recursiveGetChildByPos(childPos, wantsPhantom); - if(subChild) - return subChild; - else if(wantsPhantom || !child->isPhantom()) - return child; - } - } - return nullptr; -} - -UIWidgetList UIWidget::recursiveGetChildren() -{ - UIWidgetList children; - for(const UIWidgetPtr& child : m_children) { - UIWidgetList subChildren = child->recursiveGetChildren(); - if(!subChildren.empty()) - children.insert(children.end(), subChildren.begin(), subChildren.end()); - children.push_back(child); - } - return children; -} - -UIWidgetList UIWidget::recursiveGetChildrenByPos(const Point& childPos) -{ - UIWidgetList children; - if(!containsPaddingPoint(childPos)) - return children; - - for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { - const UIWidgetPtr& child = (*it); - if(child->isExplicitlyVisible() && child->containsPoint(childPos)) { - UIWidgetList subChildren = child->recursiveGetChildrenByPos(childPos); - if(!subChildren.empty()) - children.insert(children.end(), subChildren.begin(), subChildren.end()); - children.push_back(child); - } - } - return children; -} - -UIWidgetList UIWidget::recursiveGetChildrenByMarginPos(const Point& childPos) -{ - UIWidgetList children; - if(!containsPaddingPoint(childPos)) - return children; - - for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { - const UIWidgetPtr& child = (*it); - if(child->isExplicitlyVisible() && child->containsMarginPoint(childPos)) { - UIWidgetList subChildren = child->recursiveGetChildrenByMarginPos(childPos); - if(!subChildren.empty()) - children.insert(children.end(), subChildren.begin(), subChildren.end()); - children.push_back(child); - } - } - return children; -} - -UIWidgetPtr UIWidget::backwardsGetWidgetById(const std::string& id) -{ - UIWidgetPtr widget = getChildById(id); - if(!widget) { - if(UIWidgetPtr parent = getParent()) - widget = parent->backwardsGetWidgetById(id); - } - return widget; -} - -bool UIWidget::setState(Fw::WidgetState state, bool on) -{ - if(state == Fw::InvalidState) - return false; - - int oldStates = m_states; - if(on) - m_states |= state; - else - m_states &= ~state; - - if(oldStates != m_states) { - updateStyle(); - return true; - } - return false; -} - -bool UIWidget::hasState(Fw::WidgetState state) -{ - if(state == Fw::InvalidState) - return false; - return (m_states & state); -} - -void UIWidget::updateState(Fw::WidgetState state) -{ - if(m_destroyed) - return; - - bool newStatus = true; - bool oldStatus = hasState(state); - bool updateChildren = false; - - switch(state) { - case Fw::ActiveState: { - UIWidgetPtr widget = static_self_cast(); - UIWidgetPtr parent; - do { - parent = widget->getParent(); - if(!widget->isExplicitlyEnabled() || - ((parent && parent->getFocusedChild() != widget))) { - newStatus = false; - break; - } - } while((widget = parent)); - - updateChildren = newStatus != oldStatus; - break; - } - case Fw::FocusState: { - newStatus = (getParent() && getParent()->getFocusedChild() == static_self_cast()); - break; - } - case Fw::HoverState: { - newStatus = (g_ui.getHoveredWidget() == static_self_cast() && isEnabled()); - break; - } - case Fw::PressedState: { - newStatus = (g_ui.getPressedWidget() == static_self_cast()); - break; - } - case Fw::DraggingState: { - newStatus = (g_ui.getDraggingWidget() == static_self_cast()); - break; - } - case Fw::DisabledState: { - bool enabled = true; - UIWidgetPtr widget = static_self_cast(); - do { - if(!widget->isExplicitlyEnabled()) { - enabled = false; - break; - } - } while((widget = widget->getParent())); - newStatus = !enabled; - updateChildren = newStatus != oldStatus; - break; - } - case Fw::FirstState: { - newStatus = (getParent() && getParent()->getFirstChild() == static_self_cast()); - break; - } - case Fw::MiddleState: { - newStatus = (getParent() && getParent()->getFirstChild() != static_self_cast() && getParent()->getLastChild() != static_self_cast()); - break; - } - case Fw::LastState: { - newStatus = (getParent() && getParent()->getLastChild() == static_self_cast()); - break; - } - case Fw::AlternateState: { - newStatus = (getParent() && (getParent()->getChildIndex(static_self_cast()) % 2) == 1); - break; - } - case Fw::HiddenState: { - bool visible = true; - UIWidgetPtr widget = static_self_cast(); - do { - if(!widget->isExplicitlyVisible()) { - visible = false; - break; - } - } while((widget = widget->getParent())); - newStatus = !visible; - updateChildren = newStatus != oldStatus; - break; - } - case Fw::MobileState: - { - newStatus = g_app.isMobile(); - break; - } - default: - return; - } - - if(updateChildren) { - // do a backup of children list, because it may change while looping it - UIWidgetList children = m_children; - for(const UIWidgetPtr& child : children) - child->updateState(state); - } - - if(setState(state, newStatus)) { - // disabled widgets cannot have hover state - if(state == Fw::DisabledState && !newStatus && isHovered()) { - g_ui.updateHoveredWidget(); - } else if(state == Fw::HiddenState) { - onVisibilityChange(!newStatus); - } - } -} - -void UIWidget::updateStates() -{ - if(m_destroyed) - return; - - for(int state = 1; state != Fw::LastWidgetState; state <<= 1) - updateState((Fw::WidgetState)state); -} - -void UIWidget::updateChildrenIndexStates() -{ - if(m_destroyed) - return; - - for(const UIWidgetPtr& child : m_children) { - child->updateState(Fw::FirstState); - child->updateState(Fw::MiddleState); - child->updateState(Fw::LastState); - child->updateState(Fw::AlternateState); - } -} - -void UIWidget::updateStyle() -{ - if(m_destroyed) - return; - - if(m_loadingStyle && !m_updateStyleScheduled) { - UIWidgetPtr self = static_self_cast(); - g_dispatcher.addEvent([self] { - self->m_updateStyleScheduled = false; - self->updateStyle(); - }); - m_updateStyleScheduled = true; - return; - } - - if(!m_style) - return; - - OTMLNodePtr newStateStyle = OTMLNode::create(); - - // copy only the changed styles from default style - if(m_stateStyle) { - for(OTMLNodePtr node : m_stateStyle->children()) { - if(OTMLNodePtr otherNode = m_style->get(node->tag())) - newStateStyle->addChild(otherNode->clone()); - } - } - - // checks for states combination - for(const OTMLNodePtr& style : m_style->children()) { - if(stdext::starts_with(style->tag(), "$")) { - std::string statesStr = style->tag().substr(1); - std::vector statesSplit = stdext::split(statesStr, " "); - - bool match = true; - for(std::string stateStr : statesSplit) { - if(stateStr.length() == 0) - continue; - - bool notstate = (stateStr[0] == '!'); - if(notstate) - stateStr = stateStr.substr(1); - - bool stateOn = hasState(Fw::translateState(stateStr)); - if((!notstate && !stateOn) || (notstate && stateOn)) - match = false; - } - - // merge states styles - if(match) { - newStateStyle->merge(style); - } - } - } - - //TODO: prevent setting already set proprieties - - applyStyle(newStateStyle); - m_stateStyle = newStateStyle; -} - -void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode) -{ - if(m_destroyed) - return; - - // first set id - if(const OTMLNodePtr& node = styleNode->get("id")) - setId(node->value()); - - parseBaseStyle(styleNode); - parseImageStyle(styleNode); - parseTextStyle(styleNode); -} - -void UIWidget::onGeometryChange(const Rect& oldRect, const Rect& newRect) -{ - if(m_textWrap && oldRect.size() != newRect.size()) - updateText(); - - // move children that is outside the parent rect to inside again - for(const UIWidgetPtr& child : m_children) { - if(!child->isAnchored() && child->isVisible()) - child->bindRectToParent(); - } - - callLuaField("onGeometryChange", oldRect, newRect); -} - -void UIWidget::onLayoutUpdate() -{ - callLuaField("onLayoutUpdate"); -} - -void UIWidget::onFocusChange(bool focused, Fw::FocusReason reason) -{ - callLuaField("onFocusChange", focused, reason); -} - -void UIWidget::onChildFocusChange(const UIWidgetPtr& focusedChild, const UIWidgetPtr& unfocusedChild, Fw::FocusReason reason) -{ - callLuaField("onChildFocusChange", focusedChild, unfocusedChild, reason); -} - -void UIWidget::onHoverChange(bool hovered) -{ - callLuaField("onHoverChange", hovered); -} - -void UIWidget::onVisibilityChange(bool visible) -{ - if(!isAnchored()) - bindRectToParent(); - callLuaField("onVisibilityChange", visible); -} - -bool UIWidget::onDragEnter(const Point& mousePos) -{ - return callLuaField("onDragEnter", mousePos); -} - -bool UIWidget::onDragLeave(UIWidgetPtr droppedWidget, const Point& mousePos) -{ - return callLuaField("onDragLeave", droppedWidget, mousePos); -} - -bool UIWidget::onDragMove(const Point& mousePos, const Point& mouseMoved) -{ - return callLuaField("onDragMove", mousePos, mouseMoved); -} - -bool UIWidget::onDrop(UIWidgetPtr draggedWidget, const Point& mousePos) -{ - return callLuaField("onDrop", draggedWidget, mousePos); -} - -bool UIWidget::onKeyText(const std::string& keyText) -{ - return callLuaField("onKeyText", keyText); -} - -bool UIWidget::onKeyDown(uchar keyCode, int keyboardModifiers) -{ - return callLuaField("onKeyDown", keyCode, keyboardModifiers); -} - -bool UIWidget::onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks) -{ - return callLuaField("onKeyPress", keyCode, keyboardModifiers, autoRepeatTicks); -} - -bool UIWidget::onKeyUp(uchar keyCode, int keyboardModifiers) -{ - return callLuaField("onKeyUp", keyCode, keyboardModifiers); -} - -bool UIWidget::onMousePress(const Point& mousePos, Fw::MouseButton button) -{ - if(button == Fw::MouseLeftButton) { - if(m_clickTimer.running() && m_clickTimer.ticksElapsed() <= 200) { - if(onDoubleClick(mousePos)) - return true; - m_clickTimer.stop(); - } else - m_clickTimer.restart(); - m_lastClickPosition = mousePos; - } - - if (button == Fw::MouseTouch) - return callLuaField("onTouchPress", mousePos, button); - return callLuaField("onMousePress", mousePos, button); -} - -bool UIWidget::onMouseRelease(const Point& mousePos, Fw::MouseButton button) -{ - if (button == Fw::MouseTouch) - return callLuaField("onTouchRelease", mousePos, button); - return callLuaField("onMouseRelease", mousePos, button); -} - -bool UIWidget::onMouseMove(const Point& mousePos, const Point& mouseMoved) -{ - return callLuaField("onMouseMove", mousePos, mouseMoved); -} - -bool UIWidget::onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction) -{ - return callLuaField("onMouseWheel", mousePos, direction); -} - -bool UIWidget::onClick(const Point& mousePos) -{ - return callLuaField("onClick", mousePos); -} - -bool UIWidget::onDoubleClick(const Point& mousePos) -{ - return callLuaField("onDoubleClick", mousePos); -} - -bool UIWidget::propagateOnKeyText(const std::string& keyText) -{ - // do a backup of children list, because it may change while looping it - UIWidgetList children; - for(const UIWidgetPtr& child : m_children) { - // events on hidden or disabled widgets are discarded - if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) - continue; - - // key events go only to containers or focused child - if(child->isFocused()) - children.push_back(child); - } - - for(const UIWidgetPtr& child : children) { - if(child->propagateOnKeyText(keyText)) - return true; - } - - return onKeyText(keyText); -} - -bool UIWidget::propagateOnKeyDown(uchar keyCode, int keyboardModifiers) -{ - // do a backup of children list, because it may change while looping it - UIWidgetList children; - for(const UIWidgetPtr& child : m_children) { - // events on hidden or disabled widgets are discarded - if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) - continue; - - // key events go only to containers or focused child - if(child->isFocused()) - children.push_back(child); - } - - for(const UIWidgetPtr& child : children) { - if(child->propagateOnKeyDown(keyCode, keyboardModifiers)) - return true; - } - - return onKeyDown(keyCode, keyboardModifiers); -} - -bool UIWidget::propagateOnKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks) -{ - // do a backup of children list, because it may change while looping it - UIWidgetList children; - for(const UIWidgetPtr& child : m_children) { - // events on hidden or disabled widgets are discarded - if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) - continue; - - // key events go only to containers or focused child - if(child->isFocused()) - children.push_back(child); - } - - for(const UIWidgetPtr& child : children) { - if(child->propagateOnKeyPress(keyCode, keyboardModifiers, autoRepeatTicks)) - return true; - } - - if(autoRepeatTicks == 0 || autoRepeatTicks >= m_autoRepeatDelay) - return onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks); - else - return false; -} - -bool UIWidget::propagateOnKeyUp(uchar keyCode, int keyboardModifiers) -{ - // do a backup of children list, because it may change while looping it - UIWidgetList children; - for(const UIWidgetPtr& child : m_children) { - // events on hidden or disabled widgets are discarded - if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) - continue; - - // key events go only to focused child - if(child->isFocused()) - children.push_back(child); - } - - for(const UIWidgetPtr& child : children) { - if(child->propagateOnKeyUp(keyCode, keyboardModifiers)) - return true; - } - - return onKeyUp(keyCode, keyboardModifiers); -} - -bool UIWidget::propagateOnMouseEvent(const Point& mousePos, UIWidgetList& widgetList) -{ - bool ret = false; - if(containsPaddingPoint(mousePos)) { - for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) { - const UIWidgetPtr& child = *it; - if(child->isExplicitlyEnabled() && child->isExplicitlyVisible() && child->containsPoint(mousePos)) { - if(child->propagateOnMouseEvent(mousePos, widgetList)) { - ret = true; - break; - } - } - } - } - - widgetList.push_back(static_self_cast()); - - if(!isPhantom()) - ret = true; - return ret; -} - -bool UIWidget::propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved, UIWidgetList& widgetList) -{ - if (containsPaddingPoint(mousePos)) { - for (auto it = m_children.begin(); it != m_children.end(); ++it) { - const UIWidgetPtr& child = *it; - if (child->isExplicitlyVisible() && child->isExplicitlyEnabled() && child->containsPoint(mousePos)) - child->propagateOnMouseMove(mousePos, mouseMoved, widgetList); - - widgetList.push_back(static_self_cast()); - } - } - - return true; -} diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h deleted file mode 100644 index a1ce51d..0000000 --- a/src/framework/ui/uiwidget.h +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UIWIDGET_H -#define UIWIDGET_H - -#include "declarations.h" -#include "uilayout.h" - -#include -#include -#include -#include -#include -#include - -template -struct EdgeGroup { - EdgeGroup() { top = right = bottom = left = T(0); } - void set(T value) { top = right = bottom = left = value; } - T top; - T right; - T bottom; - T left; -}; - -// @bindclass -class UIWidget : public LuaObject -{ -// widget core -public: - UIWidget(); - virtual ~UIWidget(); - - virtual void draw(const Rect& visibleRect, Fw::DrawPane drawPane); - -protected: - virtual void drawSelf(Fw::DrawPane drawPane); - virtual void drawChildren(const Rect& visibleRect, Fw::DrawPane drawPane); - - friend class UIManager; - - std::string m_id; - std::string m_source; - Rect m_rect; - Point m_virtualOffset; - stdext::boolean m_enabled; - stdext::boolean m_visible; - stdext::boolean m_focusable; - stdext::boolean m_fixedSize; - stdext::boolean m_phantom; - stdext::boolean m_draggable; - stdext::boolean m_destroyed; - stdext::boolean m_clipping; - UILayoutPtr m_layout; - UIWidgetPtr m_parent; - std::string m_parentId; - UIWidgetList m_children; - UIWidgetList m_lockedChildren; - std::map m_childrenShortcuts; - UIWidgetPtr m_focusedChild; - OTMLNodePtr m_style; - Timer m_clickTimer; - Fw::FocusReason m_lastFocusReason; - Fw::AutoFocusPolicy m_autoFocusPolicy; - -public: - void addChild(const UIWidgetPtr& child); - void onChildIdChange(const UIWidgetPtr& child); - void insertChild(int index, const UIWidgetPtr& child); - void removeChild(UIWidgetPtr child); - void focusChild(const UIWidgetPtr& child, Fw::FocusReason reason); - void focusNextChild(Fw::FocusReason reason, bool rotate = false); - void focusPreviousChild(Fw::FocusReason reason, bool rotate = false); - void lowerChild(UIWidgetPtr child); - void raiseChild(UIWidgetPtr child); - void moveChildToIndex(const UIWidgetPtr& child, int index); - void reorderChildren(const std::vector& childrens); - void lockChild(const UIWidgetPtr& child); - void unlockChild(const UIWidgetPtr& child); - void mergeStyle(const OTMLNodePtr& styleNode); - void applyStyle(const OTMLNodePtr& styleNode); - void addAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge); - void removeAnchor(Fw::AnchorEdge anchoredEdge); - void fill(const std::string& hookedWidgetId); - void centerIn(const std::string& hookedWidgetId); - void breakAnchors(); - void updateParentLayout(); - void updateLayout(); - void lock(); - void unlock(); - void focus(); - void recursiveFocus(Fw::FocusReason reason); - void lower(); - void raise(); - void grabMouse(); - void ungrabMouse(); - void grabKeyboard(); - void ungrabKeyboard(); - void bindRectToParent(); - void destroy(); - void destroyChildren(); - - void setId(const std::string& id); - void setParent(const UIWidgetPtr& parent); - void setLayout(const UILayoutPtr& layout); - bool setRect(const Rect& rect); - void setStyle(const std::string& styleName); - void setStyleFromNode(const OTMLNodePtr& styleNode); - void setEnabled(bool enabled); - void setVisible(bool visible); - void setOn(bool on); - void setChecked(bool checked); - void setFocusable(bool focusable); - void setPhantom(bool phantom); - void setDraggable(bool draggable); - void setFixedSize(bool fixed); - void setClipping(bool clipping) { m_clipping = clipping; } - void setLastFocusReason(Fw::FocusReason reason); - void setAutoFocusPolicy(Fw::AutoFocusPolicy policy); - void setAutoRepeatDelay(int delay) { m_autoRepeatDelay = delay; } - void setVirtualOffset(const Point& offset); - - bool isAnchored(); - bool isChildLocked(const UIWidgetPtr& child); - bool hasChild(const UIWidgetPtr& child); - int getChildIndex(const UIWidgetPtr& child); - Rect getPaddingRect(); - Rect getMarginRect(); - Rect getChildrenRect(); - UIAnchorLayoutPtr getAnchoredLayout(); - UIWidgetPtr getRootParent(); - UIWidgetPtr getChildAfter(const UIWidgetPtr& relativeChild); - UIWidgetPtr getChildBefore(const UIWidgetPtr& relativeChild); - UIWidgetPtr getChildById(const std::string& childId); - UIWidgetPtr getChildByPos(const Point& childPos); - UIWidgetPtr getChildByIndex(int index); - UIWidgetPtr recursiveGetChildById(const std::string& id); - UIWidgetPtr recursiveGetChildByPos(const Point& childPos, bool wantsPhantom); - UIWidgetList recursiveGetChildren(); - UIWidgetList recursiveGetChildrenByPos(const Point& childPos); - UIWidgetList recursiveGetChildrenByMarginPos(const Point& childPos); - UIWidgetPtr backwardsGetWidgetById(const std::string& id); - -private: - stdext::boolean m_updateEventScheduled; - stdext::boolean m_loadingStyle; - - -// state managment -protected: - bool setState(Fw::WidgetState state, bool on); - bool hasState(Fw::WidgetState state); - -private: - void internalDestroy(); - void updateState(Fw::WidgetState state); - void updateStates(); - void updateChildrenIndexStates(); - void updateStyle(); - - stdext::boolean m_updateStyleScheduled; - stdext::boolean m_firstOnStyle; - OTMLNodePtr m_stateStyle; - int m_states; - - -// event processing -protected: - virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode); - virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect); - virtual void onLayoutUpdate(); - virtual void onFocusChange(bool focused, Fw::FocusReason reason); - virtual void onChildFocusChange(const UIWidgetPtr& focusedChild, const UIWidgetPtr& unfocusedChild, Fw::FocusReason reason); - virtual void onHoverChange(bool hovered); - virtual void onVisibilityChange(bool visible); - virtual bool onDragEnter(const Point& mousePos); - virtual bool onDragLeave(UIWidgetPtr droppedWidget, const Point& mousePos); - virtual bool onDragMove(const Point& mousePos, const Point& mouseMoved); - virtual bool onDrop(UIWidgetPtr draggedWidget, const Point& mousePos); - virtual bool onKeyText(const std::string& keyText); - virtual bool onKeyDown(uchar keyCode, int keyboardModifiers); - virtual bool onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks); - virtual bool onKeyUp(uchar keyCode, int keyboardModifiers); - virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button); - virtual bool onMouseRelease(const Point& mousePos, Fw::MouseButton button); - virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved); - virtual bool onMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction); - virtual bool onClick(const Point& mousePos); - virtual bool onDoubleClick(const Point& mousePos); - - friend class UILayout; - - bool propagateOnKeyText(const std::string& keyText); - bool propagateOnKeyDown(uchar keyCode, int keyboardModifiers); - bool propagateOnKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks); - bool propagateOnKeyUp(uchar keyCode, int keyboardModifiers); - bool propagateOnMouseEvent(const Point& mousePos, UIWidgetList& widgetList); - bool propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved, UIWidgetList& widgetList); - - -// function shortcuts -public: - void resize(int width, int height) { setRect(Rect(getPosition(), Size(width, height))); } - void move(int x, int y) { setRect(Rect(x, y, getSize())); } - void rotate(float degrees) { setRotation(degrees); } - void hide() { setVisible(false); } - void show() { setVisible(true); } - void disable() { setEnabled(false); } - void enable() { setEnabled(true); } - - bool isActive() { return hasState(Fw::ActiveState); } - bool isEnabled() { return !hasState(Fw::DisabledState); } - bool isDisabled() { return hasState(Fw::DisabledState); } - bool isFocused() { return hasState(Fw::FocusState); } - bool isHovered() { return hasState(Fw::HoverState); } - bool isPressed() { return hasState(Fw::PressedState); } - bool isFirst() { return hasState(Fw::FirstState); } - bool isMiddle() { return hasState(Fw::MiddleState); } - bool isLast() { return hasState(Fw::LastState); } - bool isAlternate() { return hasState(Fw::AlternateState); } - bool isChecked() { return hasState(Fw::CheckedState); } - bool isOn() { return hasState(Fw::OnState); } - bool isDragging() { return hasState(Fw::DraggingState); } - bool isVisible() { return !hasState(Fw::HiddenState); } - bool isHidden() { return hasState(Fw::HiddenState); } - bool isExplicitlyEnabled() { return m_enabled; } - bool isExplicitlyVisible() { return m_visible; } - bool isFocusable() { return m_focusable; } - bool isPhantom() { return m_phantom; } - bool isDraggable() { return m_draggable; } - bool isFixedSize() { return m_fixedSize; } - bool isClipping() { return m_clipping; } - bool isDestroyed() { return m_destroyed; } - - bool hasChildren() { return m_children.size() > 0; } - bool containsMarginPoint(const Point& point) { return getMarginRect().contains(point); } - bool containsPaddingPoint(const Point& point) { return getPaddingRect().contains(point); } - bool containsPoint(const Point& point) { return m_rect.contains(point); } - - std::string getId() { return m_id; } - std::string getSource() { return m_source; } - UIWidgetPtr getParent() { return m_parent; } - std::string getParentId() { return m_parentId; } - UIWidgetPtr getFocusedChild() { return m_focusedChild; } - UIWidgetList getChildren() { return m_children; } - UIWidgetPtr getFirstChild() { return getChildByIndex(1); } - UIWidgetPtr getLastChild() { return getChildByIndex(-1); } - UILayoutPtr getLayout() { return m_layout; } - OTMLNodePtr getStyle() { return m_style; } - int getChildCount() { return m_children.size(); } - Fw::FocusReason getLastFocusReason() { return m_lastFocusReason; } - Fw::AutoFocusPolicy getAutoFocusPolicy() { return m_autoFocusPolicy; } - int getAutoRepeatDelay() { return m_autoRepeatDelay; } - Point getVirtualOffset() { return m_virtualOffset; } - std::string getStyleName() { return m_style->tag(); } - Point getLastClickPosition() { return m_lastClickPosition; } - - // for stats only - bool isRootChild() - { - return m_isRootChild; - } - - void setRootChild(bool v) - { - m_isRootChild = v; - } - - -// base style -private: - void initBaseStyle(); - void parseBaseStyle(const OTMLNodePtr& styleNode); - -protected: - void drawBackground(const Rect& screenCoords); - void drawBorder(const Rect& screenCoords); - void drawIcon(const Rect& screenCoords); - - Color m_color; - Color m_backgroundColor; - Rect m_backgroundRect; - TexturePtr m_icon; - Color m_iconColor; - Rect m_iconRect; - Rect m_iconClipRect; - Fw::AlignmentFlag m_iconAlign; - EdgeGroup m_borderColor; - EdgeGroup m_borderWidth; - EdgeGroup m_margin; - EdgeGroup m_padding; - float m_opacity; - float m_rotation; - int m_autoRepeatDelay; - Point m_lastClickPosition; - bool m_isRootChild = false; // for stats - -public: - void setX(int x) { move(x, getY()); } - void setY(int y) { move(getX(), y); } - void setWidth(int width) { resize(width, getHeight()); } - void setHeight(int height) { resize(getWidth(), height); } - void setSize(const Size& size) { resize(size.width(), size.height()); } - void setPosition(const Point& pos) { move(pos.x, pos.y); } - void setColor(const Color& color) { m_color = color; } - void setBackgroundColor(const Color& color) { m_backgroundColor = color; } - void setBackgroundOffsetX(int x) { m_backgroundRect.setX(x); } - void setBackgroundOffsetY(int y) { m_backgroundRect.setX(y); } - void setBackgroundOffset(const Point& pos) { m_backgroundRect.move(pos); } - void setBackgroundWidth(int width) { m_backgroundRect.setWidth(width); } - void setBackgroundHeight(int height) { m_backgroundRect.setHeight(height); } - void setBackgroundSize(const Size& size) { m_backgroundRect.resize(size); } - void setBackgroundRect(const Rect& rect) { m_backgroundRect = rect; } - void setIcon(const std::string& iconFile); - void setIconColor(const Color& color) { m_iconColor = color; } - void setIconOffsetX(int x) { m_iconOffset.x = x; } - void setIconOffsetY(int y) { m_iconOffset.y = y; } - void setIconOffset(const Point& pos) { m_iconOffset = pos; } - void setIconWidth(int width) { m_iconRect.setWidth(width); } - void setIconHeight(int height) { m_iconRect.setHeight(height); } - void setIconSize(const Size& size) { m_iconRect.resize(size); } - void setIconRect(const Rect& rect) { m_iconRect = rect; } - void setIconClip(const Rect& rect) { m_iconClipRect = rect; } - void setIconAlign(Fw::AlignmentFlag align) { m_iconAlign = align; } - void setBorderWidth(int width) { m_borderWidth.set(width); updateLayout(); } - void setBorderWidthTop(int width) { m_borderWidth.top = width; } - void setBorderWidthRight(int width) { m_borderWidth.right = width; } - void setBorderWidthBottom(int width) { m_borderWidth.bottom = width; } - void setBorderWidthLeft(int width) { m_borderWidth.left = width; } - void setBorderColor(const Color& color) { m_borderColor.set(color); updateLayout(); } - void setBorderColorTop(const Color& color) { m_borderColor.top = color; } - void setBorderColorRight(const Color& color) { m_borderColor.right = color; } - void setBorderColorBottom(const Color& color) { m_borderColor.bottom = color; } - void setBorderColorLeft(const Color& color) { m_borderColor.left = color; } - void setMargin(int margin) { m_margin.set(margin); updateParentLayout(); } - void setMarginHorizontal(int margin) { m_margin.right = m_margin.left = margin; updateParentLayout(); } - void setMarginVertical(int margin) { m_margin.bottom = m_margin.top = margin; updateParentLayout(); } - void setMarginTop(int margin) { m_margin.top = margin; updateParentLayout(); } - void setMarginRight(int margin) { m_margin.right = margin; updateParentLayout(); } - void setMarginBottom(int margin) { m_margin.bottom = margin; updateParentLayout(); } - void setMarginLeft(int margin) { m_margin.left = margin; updateParentLayout(); } - void setPadding(int padding) { m_padding.top = m_padding.right = m_padding.bottom = m_padding.left = padding; updateLayout(); } - void setPaddingHorizontal(int padding) { m_padding.right = m_padding.left = padding; updateLayout(); } - void setPaddingVertical(int padding) { m_padding.bottom = m_padding.top = padding; updateLayout(); } - void setPaddingTop(int padding) { m_padding.top = padding; updateLayout(); } - void setPaddingRight(int padding) { m_padding.right = padding; updateLayout(); } - void setPaddingBottom(int padding) { m_padding.bottom = padding; updateLayout(); } - void setPaddingLeft(int padding) { m_padding.left = padding; updateLayout(); } - void setOpacity(float opacity) { m_opacity = stdext::clamp(opacity, 0.0f, 1.0f); } - void setRotation(float degrees) { m_rotation = degrees; } - - int getX() { return m_rect.x(); } - int getY() { return m_rect.y(); } - Point getPosition() { return m_rect.topLeft(); } - int getWidth() { return m_rect.width(); } - int getHeight() { return m_rect.height(); } - Size getSize() { return m_rect.size(); } - Rect getRect() { return m_rect; } - Color getColor() { return m_color; } - Color getBackgroundColor() { return m_backgroundColor; } - int getBackgroundOffsetX() { return m_backgroundRect.x(); } - int getBackgroundOffsetY() { return m_backgroundRect.y(); } - Point getBackgroundOffset() { return m_backgroundRect.topLeft(); } - int getBackgroundWidth() { return m_backgroundRect.width(); } - int getBackgroundHeight() { return m_backgroundRect.height(); } - Size getBackgroundSize() { return m_backgroundRect.size(); } - Rect getBackgroundRect() { return m_backgroundRect; } - Color getIconColor() { return m_iconColor; } - int getIconOffsetX() { return m_iconRect.x(); } - int getIconOffsetY() { return m_iconRect.y(); } - Point getIconOffset() { return m_iconRect.topLeft(); } - int getIconWidth() { return m_iconRect.width(); } - int getIconHeight() { return m_iconRect.height(); } - Size getIconSize() { return m_iconRect.size(); } - Rect getIconRect() { return m_iconRect; } - Rect getIconClip() { return m_iconClipRect; } - Fw::AlignmentFlag getIconAlign() { return m_iconAlign; } - Color getBorderTopColor() { return m_borderColor.top; } - Color getBorderRightColor() { return m_borderColor.right; } - Color getBorderBottomColor() { return m_borderColor.bottom; } - Color getBorderLeftColor() { return m_borderColor.left; } - int getBorderTopWidth() { return m_borderWidth.top; } - int getBorderRightWidth() { return m_borderWidth.right; } - int getBorderBottomWidth() { return m_borderWidth.bottom; } - int getBorderLeftWidth() { return m_borderWidth.left; } - int getMarginTop() { return m_margin.top; } - int getMarginRight() { return m_margin.right; } - int getMarginBottom() { return m_margin.bottom; } - int getMarginLeft() { return m_margin.left; } - int getPaddingTop() { return m_padding.top; } - int getPaddingRight() { return m_padding.right; } - int getPaddingBottom() { return m_padding.bottom; } - int getPaddingLeft() { return m_padding.left; } - float getOpacity() { return m_opacity; } - float getRotation() { return m_rotation; } - -// image -private: - void initImage(); - void parseImageStyle(const OTMLNodePtr& styleNode); - - void updateImageCache() { m_imageMustRecache = true; } - void configureBorderImage() { m_imageBordered = true; updateImageCache(); } - - CoordsBuffer m_imageCoordsBuffer; - Rect m_imageCachedScreenCoords; - stdext::boolean m_imageMustRecache; - stdext::boolean m_imageBordered; - -protected: - void drawImage(const Rect& screenCoords); - - TexturePtr m_imageTexture; - Rect m_imageClipRect; - Rect m_imageRect; - Color m_imageColor; - Point m_iconOffset; - stdext::boolean m_imageFixedRatio; - stdext::boolean m_imageRepeated; - stdext::boolean m_imageSmooth; - stdext::boolean m_imageAutoResize; - EdgeGroup m_imageBorder; - -public: - void setQRCode(const std::string& code, int border); - void setImageSource(const std::string& source); - void setImageSourceBase64(const std::string & data); - void setImageClip(const Rect& clipRect) { m_imageClipRect = clipRect; updateImageCache(); } - void setImageOffsetX(int x) { m_imageRect.setX(x); updateImageCache(); } - void setImageOffsetY(int y) { m_imageRect.setY(y); updateImageCache(); } - void setImageOffset(const Point& pos) { m_imageRect.move(pos); updateImageCache(); } - void setImageWidth(int width) { m_imageRect.setWidth(width); updateImageCache(); } - void setImageHeight(int height) { m_imageRect.setHeight(height); updateImageCache(); } - void setImageSize(const Size& size) { m_imageRect.resize(size); updateImageCache(); } - void setImageRect(const Rect& rect) { m_imageRect = rect; updateImageCache(); } - void setImageColor(const Color& color) { m_imageColor = color; updateImageCache(); } - void setImageFixedRatio(bool fixedRatio) { m_imageFixedRatio = fixedRatio; updateImageCache(); } - void setImageRepeated(bool repeated) { m_imageRepeated = repeated; updateImageCache(); } - void setImageSmooth(bool smooth) { m_imageSmooth = smooth; } - void setImageAutoResize(bool autoResize) { m_imageAutoResize = autoResize; } - void setImageBorderTop(int border) { m_imageBorder.top = border; configureBorderImage(); } - void setImageBorderRight(int border) { m_imageBorder.right = border; configureBorderImage(); } - void setImageBorderBottom(int border) { m_imageBorder.bottom = border; configureBorderImage(); } - void setImageBorderLeft(int border) { m_imageBorder.left = border; configureBorderImage(); } - void setImageBorder(int border) { m_imageBorder.set(border); configureBorderImage(); } - - Rect getImageClip() { return m_imageClipRect; } - int getImageOffsetX() { return m_imageRect.x(); } - int getImageOffsetY() { return m_imageRect.y(); } - Point getImageOffset() { return m_imageRect.topLeft(); } - int getImageWidth() { return m_imageRect.width(); } - int getImageHeight() { return m_imageRect.height(); } - Size getImageSize() { return m_imageRect.size(); } - Rect getImageRect() { return m_imageRect; } - Color getImageColor() { return m_imageColor; } - bool isImageFixedRatio() { return m_imageFixedRatio; } - bool isImageSmooth() { return m_imageSmooth; } - bool isImageAutoResize() { return m_imageAutoResize; } - int getImageBorderTop() { return m_imageBorder.top; } - int getImageBorderRight() { return m_imageBorder.right; } - int getImageBorderBottom() { return m_imageBorder.bottom; } - int getImageBorderLeft() { return m_imageBorder.left; } - int getImageTextureWidth() { return m_imageTexture ? m_imageTexture->getWidth() : 0; } - int getImageTextureHeight() { return m_imageTexture ? m_imageTexture->getHeight() : 0; } - -// text related -private: - void initText(); - void parseTextStyle(const OTMLNodePtr& styleNode); - - stdext::boolean m_textMustRecache; - Rect m_textCachedScreenCoords; - -protected: - virtual void updateText(); - void drawText(const Rect& screenCoords); - - virtual void onTextChange(const std::string& text, const std::string& oldText); - virtual void onFontChange(const std::string& font); - - std::string m_text; - std::string m_drawText; - Fw::AlignmentFlag m_textAlign; - Point m_textOffset; - stdext::boolean m_textWrap; - stdext::boolean m_textVerticalAutoResize; - stdext::boolean m_textHorizontalAutoResize; - stdext::boolean m_textOnlyUpperCase; - BitmapFontPtr m_font; - std::vector> m_textColors; - std::vector> m_drawTextColors; - -public: - void resizeToText() { setSize(getTextSize()); } - void clearText() { setText(""); } - - void setText(std::string text, bool dontFireLuaCall = false); - void setColoredText(const std::vector& texts, bool dontFireLuaCall = false); - void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; updateText(); } - void setTextOffset(const Point& offset) { m_textOffset = offset; updateText(); } - void setTextWrap(bool textWrap) { m_textWrap = textWrap; updateText(); } - void setTextAutoResize(bool textAutoResize) { m_textHorizontalAutoResize = textAutoResize; m_textVerticalAutoResize = textAutoResize; updateText(); } - void setTextHorizontalAutoResize(bool textAutoResize) { m_textHorizontalAutoResize = textAutoResize; updateText(); } - void setTextVerticalAutoResize(bool textAutoResize) { m_textVerticalAutoResize = textAutoResize; updateText(); } - void setTextOnlyUpperCase(bool textOnlyUpperCase) { m_textOnlyUpperCase = textOnlyUpperCase; setText(m_text); } - void setFont(const std::string& fontName); - - std::string getText() { return m_text; } - std::string getDrawText() { return m_drawText; } - Fw::AlignmentFlag getTextAlign() { return m_textAlign; } - Point getTextOffset() { return m_textOffset; } - bool getTextWrap() { return m_textWrap; } - std::string getFont() { return m_font->getName(); } - Size getTextSize() { return m_font->calculateTextRectSize(m_drawText); } -}; - -#endif diff --git a/src/framework/ui/uiwidgetbasestyle.cpp b/src/framework/ui/uiwidgetbasestyle.cpp deleted file mode 100644 index 7c88beb..0000000 --- a/src/framework/ui/uiwidgetbasestyle.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiwidget.h" -#include "uihorizontallayout.h" -#include "uiverticallayout.h" -#include "uigridlayout.h" -#include "uianchorlayout.h" -#include "uitranslator.h" - -#include -#include -#include - -void UIWidget::initBaseStyle() -{ - m_backgroundColor = Color::alpha; - m_borderColor.set(Color::black); - m_iconColor = Color::white; - m_color = Color::white; - m_opacity = 1.0f; - m_rotation = 0.0f; - m_iconAlign = Fw::AlignNone; - - // generate an unique id, this is need because anchored layouts find widgets by id - static unsigned long id = 1; - m_id = std::string("widget") + std::to_string(id++); -} - -void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode) -{ - // parse lua variables and callbacks first - for(const OTMLNodePtr& node : styleNode->children()) { - // lua functions - if(stdext::starts_with(node->tag(), "@")) { - // load once - if(m_firstOnStyle) { - std::string funcName = node->tag().substr(1); - std::string funcOrigin = std::string("@") + node->source() + ": [" + node->tag() + "]"; - g_lua.loadFunction(node->value(), funcOrigin); - luaSetField(funcName); - } - // lua fields value - } else if(stdext::starts_with(node->tag(), "&")) { - std::string fieldName = node->tag().substr(1); - std::string fieldOrigin = std::string("@") + node->source() + ": [" + node->tag() + "]"; - - g_lua.evaluateExpression(node->value(), fieldOrigin); - luaSetField(fieldName); - } - } - // load styles used by all widgets - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "color") - setColor(node->value()); - else if(node->tag() == "x") - setX(node->value()); - else if(node->tag() == "y") - setY(node->value()); - else if(node->tag() == "pos") - setPosition(node->value()); - else if(node->tag() == "width") - setWidth(node->value()); - else if(node->tag() == "height") - setHeight(node->value()); - else if(node->tag() == "rect") - setRect(node->value()); - else if(node->tag() == "background") - setBackgroundColor(node->value()); - else if(node->tag() == "background-color") - setBackgroundColor(node->value()); - else if(node->tag() == "background-offset-x") - setBackgroundOffsetX(node->value()); - else if(node->tag() == "background-offset-y") - setBackgroundOffsetY(node->value()); - else if(node->tag() == "background-offset") - setBackgroundOffset(node->value()); - else if(node->tag() == "background-width") - setBackgroundWidth(node->value()); - else if(node->tag() == "background-height") - setBackgroundHeight(node->value()); - else if(node->tag() == "background-size") - setBackgroundSize(node->value()); - else if(node->tag() == "background-rect") - setBackgroundRect(node->value()); - else if(node->tag() == "icon") - setIcon(stdext::resolve_path(node->value(), node->source())); - else if(node->tag() == "icon-source") - setIcon(stdext::resolve_path(node->value(), node->source())); - else if(node->tag() == "icon-color") - setIconColor(node->value()); - else if(node->tag() == "icon-offset-x") - setIconOffsetX(node->value()); - else if(node->tag() == "icon-offset-y") - setIconOffsetY(node->value()); - else if(node->tag() == "icon-offset") - setIconOffset(node->value()); - else if(node->tag() == "icon-width") - setIconWidth(node->value()); - else if(node->tag() == "icon-height") - setIconHeight(node->value()); - else if(node->tag() == "icon-size") - setIconSize(node->value()); - else if(node->tag() == "icon-rect") - setIconRect(node->value()); - else if(node->tag() == "icon-clip") - setIconClip(node->value()); - else if(node->tag() == "icon-align") - setIconAlign(Fw::translateAlignment(node->value())); - else if(node->tag() == "opacity") - setOpacity(node->value()); - else if (node->tag() == "rotation") - setRotation(node->value()); - else if(node->tag() == "enabled") - setEnabled(node->value()); - else if(node->tag() == "visible") - setVisible(node->value()); - else if(node->tag() == "checked") - setChecked(node->value()); - else if(node->tag() == "draggable") - setDraggable(node->value()); - else if(node->tag() == "on") - setOn(node->value()); - else if(node->tag() == "focusable") - setFocusable(node->value()); - else if(node->tag() == "auto-focus") - setAutoFocusPolicy(Fw::translateAutoFocusPolicy(node->value())); - else if(node->tag() == "phantom") - setPhantom(node->value()); - else if(node->tag() == "size") - setSize(node->value()); - else if(node->tag() == "fixed-size") - setFixedSize(node->value()); - else if(node->tag() == "clipping") - setClipping(node->value()); - else if(node->tag() == "border") { - auto split = stdext::split(node->value(), " "); - if(split.size() == 2) { - setBorderWidth(stdext::safe_cast(split[0])); - setBorderColor(stdext::safe_cast(split[1])); - } else - throw OTMLException(node, "border param must have its width followed by its color"); - } - else if(node->tag() == "border-width") - setBorderWidth(node->value()); - else if(node->tag() == "border-width-top") - setBorderWidthTop(node->value()); - else if(node->tag() == "border-width-right") - setBorderWidthRight(node->value()); - else if(node->tag() == "border-width-bottom") - setBorderWidthBottom(node->value()); - else if(node->tag() == "border-width-left") - setBorderWidthLeft(node->value()); - else if(node->tag() == "border-color") - setBorderColor(node->value()); - else if(node->tag() == "border-color-top") - setBorderColorTop(node->value()); - else if(node->tag() == "border-color-right") - setBorderColorRight(node->value()); - else if(node->tag() == "border-color-bottom") - setBorderColorBottom(node->value()); - else if(node->tag() == "border-color-left") - setBorderColorLeft(node->value()); - else if(node->tag() == "margin-top") - setMarginTop(node->value()); - else if(node->tag() == "margin-right") - setMarginRight(node->value()); - else if(node->tag() == "margin-bottom") - setMarginBottom(node->value()); - else if(node->tag() == "margin-left") - setMarginLeft(node->value()); - else if(node->tag() == "margin") { - std::string marginDesc = node->value(); - std::vector split = stdext::split(marginDesc, " "); - if(split.size() == 4) { - setMarginTop(stdext::safe_cast(split[0])); - setMarginRight(stdext::safe_cast(split[1])); - setMarginBottom(stdext::safe_cast(split[2])); - setMarginLeft(stdext::safe_cast(split[3])); - } else if(split.size() == 3) { - int marginTop = stdext::safe_cast(split[0]); - int marginHorizontal = stdext::safe_cast(split[1]); - int marginBottom = stdext::safe_cast(split[2]); - setMarginTop(marginTop); - setMarginRight(marginHorizontal); - setMarginBottom(marginBottom); - setMarginLeft(marginHorizontal); - } else if(split.size() == 2) { - int marginVertical = stdext::safe_cast(split[0]); - int marginHorizontal = stdext::safe_cast(split[1]); - setMarginTop(marginVertical); - setMarginRight(marginHorizontal); - setMarginBottom(marginVertical); - setMarginLeft(marginHorizontal); - } else if(split.size() == 1) { - int margin = stdext::safe_cast(split[0]); - setMarginTop(margin); - setMarginRight(margin); - setMarginBottom(margin); - setMarginLeft(margin); - } - } - else if(node->tag() == "padding-top") - setPaddingTop(node->value()); - else if(node->tag() == "padding-right") - setPaddingRight(node->value()); - else if(node->tag() == "padding-bottom") - setPaddingBottom(node->value()); - else if(node->tag() == "padding-left") - setPaddingLeft(node->value()); - else if(node->tag() == "padding") { - std::string paddingDesc = node->value(); - std::vector split = stdext::split(paddingDesc, " "); - if(split.size() == 4) { - setPaddingTop(stdext::safe_cast(split[0])); - setPaddingRight(stdext::safe_cast(split[1])); - setPaddingBottom(stdext::safe_cast(split[2])); - setPaddingLeft(stdext::safe_cast(split[3])); - } else if(split.size() == 3) { - int paddingTop = stdext::safe_cast(split[0]); - int paddingHorizontal = stdext::safe_cast(split[1]); - int paddingBottom = stdext::safe_cast(split[2]); - setPaddingTop(paddingTop); - setPaddingRight(paddingHorizontal); - setPaddingBottom(paddingBottom); - setPaddingLeft(paddingHorizontal); - } else if(split.size() == 2) { - int paddingVertical = stdext::safe_cast(split[0]); - int paddingHorizontal = stdext::safe_cast(split[1]); - setPaddingTop(paddingVertical); - setPaddingRight(paddingHorizontal); - setPaddingBottom(paddingVertical); - setPaddingLeft(paddingHorizontal); - } else if(split.size() == 1) { - int padding = stdext::safe_cast(split[0]); - setPaddingTop(padding); - setPaddingRight(padding); - setPaddingBottom(padding); - setPaddingLeft(padding); - } - } - // layouts - else if(node->tag() == "layout") { - std::string layoutType; - if(node->hasValue()) - layoutType = node->value(); - else - layoutType = node->valueAt("type", ""); - - if(!layoutType.empty()) { - UILayoutPtr layout; - if(layoutType == "horizontalBox") - layout = UIHorizontalLayoutPtr(new UIHorizontalLayout(static_self_cast())); - else if(layoutType == "verticalBox") - layout = UIVerticalLayoutPtr(new UIVerticalLayout(static_self_cast())); - else if(layoutType == "grid") - layout = UIGridLayoutPtr(new UIGridLayout(static_self_cast())); - else if(layoutType == "anchor") - layout = UIAnchorLayoutPtr(new UIAnchorLayout(static_self_cast())); - else - throw OTMLException(node, "cannot determine layout type"); - setLayout(layout); - } - - if(node->hasChildren()) - m_layout->applyStyle(node); - } - // anchors - else if(stdext::starts_with(node->tag(), "anchors.")) { - UIWidgetPtr parent = getParent(); - if(!parent) { - if(m_firstOnStyle) - throw OTMLException(node, "cannot create anchor, there is no parent widget!"); - else - continue; - } - - UILayoutPtr layout = parent->getLayout(); - UIAnchorLayoutPtr anchorLayout; - if(layout->isUIAnchorLayout()) - anchorLayout = layout->static_self_cast(); - - if(!anchorLayout) - throw OTMLException(node, "cannot create anchor, the parent widget doesn't use anchor layout!"); - - std::string what = node->tag().substr(8); - if(what == "fill") { - fill(node->value()); - } else if(what == "centerIn") { - centerIn(node->value()); - } else { - Fw::AnchorEdge anchoredEdge = Fw::translateAnchorEdge(what); - - if(node->value() == "none") { - removeAnchor(anchoredEdge); - } else { - std::vector split = stdext::split(node->value(), "."); - if(split.size() != 2) - throw OTMLException(node, "invalid anchor description"); - - std::string hookedWidgetId = split[0]; - Fw::AnchorEdge hookedEdge = Fw::translateAnchorEdge(split[1]); - - if(anchoredEdge == Fw::AnchorNone) - throw OTMLException(node, "invalid anchor edge"); - - if(hookedEdge == Fw::AnchorNone) - throw OTMLException(node, "invalid anchor target edge"); - - addAnchor(anchoredEdge, hookedWidgetId, hookedEdge); - } - } - } - } -} - -void UIWidget::drawBackground(const Rect& screenCoords) -{ - if(m_backgroundColor.aF() > 0.0f) { - Rect drawRect = screenCoords; - drawRect.translate(m_backgroundRect.topLeft()); - if(m_backgroundRect.isValid()) - drawRect.resize(m_backgroundRect.size()); - g_drawQueue->addFilledRect(drawRect, m_backgroundColor); - } -} - -void UIWidget::drawBorder(const Rect& screenCoords) -{ - // top - if(m_borderWidth.top > 0) { - Rect borderRect(screenCoords.topLeft(), screenCoords.width(), m_borderWidth.top); - g_drawQueue->addFilledRect(borderRect, m_borderColor.top); - } - - // right - if(m_borderWidth.right > 0) { - Rect borderRect(screenCoords.topRight() - Point(m_borderWidth.right - 1, 0), m_borderWidth.right, screenCoords.height()); - g_drawQueue->addFilledRect(borderRect, m_borderColor.right); - } - - // bottom - if(m_borderWidth.bottom > 0) { - Rect borderRect(screenCoords.bottomLeft() - Point(0, m_borderWidth.bottom - 1), screenCoords.width(), m_borderWidth.bottom); - g_drawQueue->addFilledRect(borderRect, m_borderColor.bottom); - } - - // left - if(m_borderWidth.left > 0) { - Rect borderRect(screenCoords.topLeft(), m_borderWidth.left, screenCoords.height()); - g_drawQueue->addFilledRect(borderRect, m_borderColor.left); - } -} - -void UIWidget::drawIcon(const Rect& screenCoords) -{ - if(m_icon) { - Rect drawRect; - if(m_iconRect.isValid()) { - drawRect = screenCoords; - drawRect.translate(m_iconRect.topLeft()); - drawRect.resize(m_iconRect.size()); - } else { - drawRect.resize(m_iconClipRect.size()); - - if(m_iconAlign == Fw::AlignNone) - drawRect.moveCenter(screenCoords.center()); - else - drawRect.alignIn(screenCoords, m_iconAlign); - } - drawRect.translate(m_iconOffset); - g_drawQueue->addTexturedRect(drawRect, m_icon, m_iconClipRect, m_iconColor); - } -} - -void UIWidget::setIcon(const std::string& iconFile) -{ - if(iconFile.empty()) - m_icon = nullptr; - else - m_icon = g_textures.getTexture(iconFile); - if(m_icon && !m_iconClipRect.isValid()) - m_iconClipRect = Rect(0, 0, m_icon->getSize()); -} diff --git a/src/framework/ui/uiwidgetimage.cpp b/src/framework/ui/uiwidgetimage.cpp deleted file mode 100644 index 2ecfb1c..0000000 --- a/src/framework/ui/uiwidgetimage.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiwidget.h" -#include -#include -#include -#include -#include -#include - -void UIWidget::initImage() -{ -} - -void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode) -{ - for(const OTMLNodePtr& node : styleNode->children()) { - if (node->tag() == "qr" || node->tag() == "qr-code") - setQRCode(node->value(), 1); - else if(node->tag() == "image-source") - setImageSource(stdext::resolve_path(node->value(), node->source())); - else if(node->tag() == "image-source-base64") - setImageSourceBase64(node->value()); - else if(node->tag() == "image-offset-x") - setImageOffsetX(node->value()); - else if(node->tag() == "image-offset-y") - setImageOffsetY(node->value()); - else if(node->tag() == "image-offset") - setImageOffset(node->value()); - else if(node->tag() == "image-width") - setImageWidth(node->value()); - else if(node->tag() == "image-height") - setImageHeight(node->value()); - else if(node->tag() == "image-size") - setImageSize(node->value()); - else if(node->tag() == "image-rect") - setImageRect(node->value()); - else if(node->tag() == "image-clip") - setImageClip(node->value()); - else if(node->tag() == "image-fixed-ratio") - setImageFixedRatio(node->value()); - else if(node->tag() == "image-repeated") - setImageRepeated(node->value()); - else if(node->tag() == "image-smooth") - setImageSmooth(node->value()); - else if(node->tag() == "image-color") - setImageColor(node->value()); - else if(node->tag() == "image-border-top") - setImageBorderTop(node->value()); - else if(node->tag() == "image-border-right") - setImageBorderRight(node->value()); - else if(node->tag() == "image-border-bottom") - setImageBorderBottom(node->value()); - else if(node->tag() == "image-border-left") - setImageBorderLeft(node->value()); - else if(node->tag() == "image-border") - setImageBorder(node->value()); - else if(node->tag() == "image-auto-resize") - setImageAutoResize(node->value()); - } -} - -void UIWidget::drawImage(const Rect& screenCoords) -{ - if(!m_imageTexture || !screenCoords.isValid()) - return; - - // cache vertex buffers - if(m_imageCachedScreenCoords != screenCoords || m_imageMustRecache) { - m_imageCoordsBuffer.clear(); - m_imageCachedScreenCoords = screenCoords; - m_imageMustRecache = false; - - Rect drawRect = screenCoords; - drawRect.translate(m_imageRect.topLeft()); - if(m_imageRect.isValid()) - drawRect.resize(m_imageRect.size()); - - Rect clipRect = m_imageClipRect.isValid() ? m_imageClipRect : Rect(0, 0, m_imageTexture->getSize()); - - if(!m_imageBordered) { - if(m_imageFixedRatio) { - Size textureSize = m_imageTexture->getSize(); - - Size textureClipSize = drawRect.size(); - textureClipSize.scale(textureSize, Fw::KeepAspectRatio); - - Point texCoordsOffset; - if(textureSize.height() > textureClipSize.height()) - texCoordsOffset.y = (textureSize.height() - textureClipSize.height())/2; - else if(textureSize.width() > textureClipSize.width()) - texCoordsOffset.x = (textureSize.width() - textureClipSize.width())/2; - - Rect textureClipRect(texCoordsOffset, textureClipSize); - - m_imageCoordsBuffer.addRect(drawRect, textureClipRect); - } else { - if(m_imageRepeated) - m_imageCoordsBuffer.addRepeatedRects(drawRect, clipRect); - else - m_imageCoordsBuffer.addRect(drawRect, clipRect); - } - } else { - int top = m_imageBorder.top; - int bottom = m_imageBorder.bottom; - int left = m_imageBorder.left; - int right = m_imageBorder.right; - - // calculates border coords - const Rect clip = clipRect; - Rect leftBorder(clip.left(), clip.top() + top, left, clip.height() - top - bottom); - Rect rightBorder(clip.right() - right + 1, clip.top() + top, right, clip.height() - top - bottom); - Rect topBorder(clip.left() + left, clip.top(), clip.width() - right - left, top); - Rect bottomBorder(clip.left() + left, clip.bottom() - bottom + 1, clip.width() - right - left, bottom); - Rect topLeftCorner(clip.left(), clip.top(), left, top); - Rect topRightCorner(clip.right() - right + 1, clip.top(), right, top); - Rect bottomLeftCorner(clip.left(), clip.bottom() - bottom + 1, left, bottom); - Rect bottomRightCorner(clip.right() - right + 1, clip.bottom() - bottom + 1, right, bottom); - Rect center(clip.left() + left, clip.top() + top, clip.width() - right - left, clip.height() - top - bottom); - Size bordersSize(leftBorder.width() + rightBorder.width(), topBorder.height() + bottomBorder.height()); - Size centerSize = drawRect.size() - bordersSize; - Rect rectCoords; - - // first the center - if(centerSize.area() > 0) { - rectCoords = Rect(drawRect.left() + leftBorder.width(), drawRect.top() + topBorder.height(), centerSize); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, center); - } - // top left corner - rectCoords = Rect(drawRect.topLeft(), topLeftCorner.size()); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, topLeftCorner); - // top - rectCoords = Rect(drawRect.left() + topLeftCorner.width(), drawRect.topLeft().y, centerSize.width(), topBorder.height()); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, topBorder); - // top right corner - rectCoords = Rect(drawRect.left() + topLeftCorner.width() + centerSize.width(), drawRect.top(), topRightCorner.size()); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, topRightCorner); - // left - rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height(), leftBorder.width(), centerSize.height()); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, leftBorder); - // right - rectCoords = Rect(drawRect.left() + leftBorder.width() + centerSize.width(), drawRect.top() + topRightCorner.height(), rightBorder.width(), centerSize.height()); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, rightBorder); - // bottom left corner - rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height() + centerSize.height(), bottomLeftCorner.size()); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomLeftCorner); - // bottom - rectCoords = Rect(drawRect.left() + bottomLeftCorner.width(), drawRect.top() + topBorder.height() + centerSize.height(), centerSize.width(), bottomBorder.height()); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomBorder); - // bottom right corner - rectCoords = Rect(drawRect.left() + bottomLeftCorner.width() + centerSize.width(), drawRect.top() + topRightCorner.height() + centerSize.height(), bottomRightCorner.size()); - m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomRightCorner); - } - } - - g_drawQueue->addTextureCoords(m_imageCoordsBuffer, m_imageTexture, m_imageColor); -} - -void UIWidget::setQRCode(const std::string& code, int border) -{ - m_imageTexture = TexturePtr(new Texture(Image::fromQRCode(code, border))); - - if (m_imageTexture && (!m_rect.isValid() || m_imageAutoResize)) { - Size size = getSize(); - Size imageSize = m_imageTexture->getSize(); - if (size.width() <= 0 || m_imageAutoResize) - size.setWidth(imageSize.width()); - if (size.height() <= 0 || m_imageAutoResize) - size.setHeight(imageSize.height()); - setSize(size); - } - - m_imageMustRecache = true; -} - -void UIWidget::setImageSource(const std::string& source) -{ - if(source.empty()) - m_imageTexture = nullptr; - else - m_imageTexture = g_textures.getTexture(source); - - if(m_imageTexture && (!m_rect.isValid() || m_imageAutoResize)) { - Size size = getSize(); - Size imageSize = m_imageTexture->getSize(); - if(size.width() <= 0 || m_imageAutoResize) - size.setWidth(imageSize.width()); - if(size.height() <= 0 || m_imageAutoResize) - size.setHeight(imageSize.height()); - setSize(size); - } - - m_imageMustRecache = true; -} - -void UIWidget::setImageSourceBase64(const std::string& data) { - if (data.size() % 4 != 0 || data.empty()) { - m_imageTexture = nullptr; - m_imageMustRecache = true; - return; - } - - std::stringstream stream; - std::string decoded = g_crypt.base64Decode(data); - stream.write(decoded.c_str(), decoded.size()); - m_imageTexture = g_textures.loadTexture(stream, "base64"); - if(m_imageTexture && (!m_rect.isValid() || m_imageAutoResize)) { - Size size = getSize(); - Size imageSize = m_imageTexture->getSize(); - if(size.width() <= 0 || m_imageAutoResize) - size.setWidth(imageSize.width()); - if(size.height() <= 0 || m_imageAutoResize) - size.setHeight(imageSize.height()); - setSize(size); - } - - m_imageMustRecache = true; -} diff --git a/src/framework/ui/uiwidgettext.cpp b/src/framework/ui/uiwidgettext.cpp deleted file mode 100644 index d3b1e8c..0000000 --- a/src/framework/ui/uiwidgettext.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "uiwidget.h" -#include "uitranslator.h" -#include -#include -#include - -void UIWidget::initText() -{ - m_font = g_fonts.getDefaultFont(); - m_textAlign = Fw::AlignCenter; -} - -void UIWidget::updateText() -{ - if (m_textWrap && m_rect.isValid()) { - m_drawTextColors = m_textColors; - m_drawText = m_font->wrapText(m_text, getWidth() - m_textOffset.x, &m_drawTextColors); - } else { - m_drawText = m_text; - m_drawTextColors = m_textColors; - } - - // update rect size - if(!m_rect.isValid() || m_textHorizontalAutoResize || m_textVerticalAutoResize) { - Size textBoxSize = getTextSize(); - textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom) + m_textOffset.toSize(); - Size size = getSize(); - if(size.width() <= 0 || (m_textHorizontalAutoResize && !m_textWrap)) - size.setWidth(textBoxSize.width()); - if(size.height() <= 0 || m_textVerticalAutoResize) - size.setHeight(textBoxSize.height()); - setSize(size); - } - - m_textMustRecache = true; -} - -void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode) -{ - for(const OTMLNodePtr& node : styleNode->children()) { - if(node->tag() == "text") - setText(node->value()); - else if(node->tag() == "text-align") - setTextAlign(Fw::translateAlignment(node->value())); - else if(node->tag() == "text-offset") - setTextOffset(node->value()); - else if(node->tag() == "text-wrap") - setTextWrap(node->value()); - else if(node->tag() == "text-auto-resize") - setTextAutoResize(node->value()); - else if(node->tag() == "text-horizontal-auto-resize") - setTextHorizontalAutoResize(node->value()); - else if(node->tag() == "text-vertical-auto-resize") - setTextVerticalAutoResize(node->value()); - else if(node->tag() == "text-only-upper-case") - setTextOnlyUpperCase(node->value()); - else if(node->tag() == "font") - setFont(node->value()); - } -} - -void UIWidget::drawText(const Rect& screenCoords) -{ - if(m_drawText.length() == 0 || m_color.aF() == 0.0f) - return; - - if(screenCoords != m_textCachedScreenCoords || m_textMustRecache) { - Rect coords = Rect(screenCoords.topLeft() + m_textOffset, screenCoords.bottomRight()); - m_textMustRecache = false; - m_textCachedScreenCoords = coords; - } - - if (!m_drawTextColors.empty()) { - m_font->drawColoredText(m_drawText, m_textCachedScreenCoords, m_textAlign, m_drawTextColors); - } else { - m_font->drawText(m_drawText, m_textCachedScreenCoords, m_textAlign, m_color); - } -} - -void UIWidget::onTextChange(const std::string& text, const std::string& oldText) -{ - callLuaField("onTextChange", text, oldText); -} - -void UIWidget::onFontChange(const std::string& font) -{ - callLuaField("onFontChange", font); -} - -void UIWidget::setText(std::string text, bool dontFireLuaCall) -{ - if(m_textOnlyUpperCase) - stdext::toupper(text); - - m_textColors.clear(); - m_drawTextColors.clear(); - - if(m_text == text) - return; - - std::string oldText = m_text; - m_text = text; - updateText(); - - if(!dontFireLuaCall) { - onTextChange(text, oldText); - } -} - -void UIWidget::setColoredText(const std::vector& texts, bool dontFireLuaCall) -{ - m_textColors.clear(); - m_drawTextColors.clear(); - - std::string text = ""; - for(size_t i = 0, p = 0; i < texts.size() - 1; i += 2) { - Color c(Color::white); - stdext::cast(texts[i + 1], c); - text += texts[i]; - for (auto& c : texts[i]) { - if ((uint8)c >= 32) - p += 1; - } - m_textColors.push_back(std::make_pair(p, c)); - } - - if (m_textOnlyUpperCase) - stdext::toupper(text); - - std::string oldText = m_text; - m_text = text; - updateText(); - - if (!dontFireLuaCall) { - onTextChange(text, oldText); - } -} - -void UIWidget::setFont(const std::string& fontName) -{ - m_font = g_fonts.getFont(fontName); - updateText(); - onFontChange(fontName); -} diff --git a/src/framework/util/color.cpp b/src/framework/util/color.cpp deleted file mode 100644 index 96515ff..0000000 --- a/src/framework/util/color.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "color.h" - -// NOTE: AABBGGRR order -const Color Color::alpha = 0x00000000U; -const Color Color::white = 0xffffffff; -const Color Color::black = 0xff000000; -const Color Color::red = 0xff0000ff; -const Color Color::darkRed = 0xff000080; -const Color Color::green = 0xff00ff00; -const Color Color::darkGreen = 0xff008000; -const Color Color::blue = 0xffff0000; -const Color Color::darkBlue = 0xff800000; -const Color Color::pink = 0xffff00ff; -const Color Color::darkPink = 0xff800080; -const Color Color::yellow = 0xff00ffff; -const Color Color::darkYellow = 0xff008080; -const Color Color::teal = 0xffffff00; -const Color Color::darkTeal = 0xff808000; -const Color Color::gray = 0xffa0a0a0; -const Color Color::darkGray = 0xff808080; -const Color Color::lightGray = 0xffc0c0c0; -const Color Color::orange = 0xff008cff; - -Color::Color(const std::string& coltext) -{ - std::stringstream ss(coltext); - ss >> *this; -} - -Color Color::getOutfitColor(int color) -{ - static const int HSI_SI_VALUES = 7; - static const int HSI_H_STEPS = 19; - - if (color >= HSI_H_STEPS * HSI_SI_VALUES) - color = 0; - - float loc1 = 0, loc2 = 0, loc3 = 0; - if (color % HSI_H_STEPS != 0) { - loc1 = color % HSI_H_STEPS * 1.0 / 18.0; - loc2 = 1; - loc3 = 1; - - switch (int(color / HSI_H_STEPS)) { - case 0: - loc2 = 0.25; - loc3 = 1.00; - break; - case 1: - loc2 = 0.25; - loc3 = 0.75; - break; - case 2: - loc2 = 0.50; - loc3 = 0.75; - break; - case 3: - loc2 = 0.667; - loc3 = 0.75; - break; - case 4: - loc2 = 1.00; - loc3 = 1.00; - break; - case 5: - loc2 = 1.00; - loc3 = 0.75; - break; - case 6: - loc2 = 1.00; - loc3 = 0.50; - break; - } - } else { - loc1 = 0; - loc2 = 0; - loc3 = 1 - (float)color / HSI_H_STEPS / (float)HSI_SI_VALUES; - } - - if (loc3 == 0) - return Color(0, 0, 0); - - if (loc2 == 0) { - int loc7 = int(loc3 * 255); - return Color(loc7, loc7, loc7); - } - - float red = 0, green = 0, blue = 0; - - if (loc1 < 1.0 / 6.0) { - red = loc3; - blue = loc3 * (1 - loc2); - green = blue + (loc3 - blue) * 6 * loc1; - } else if (loc1 < 2.0 / 6.0) { - green = loc3; - blue = loc3 * (1 - loc2); - red = green - (loc3 - blue) * (6 * loc1 - 1); - } else if (loc1 < 3.0 / 6.0) { - green = loc3; - red = loc3 * (1 - loc2); - blue = red + (loc3 - red) * (6 * loc1 - 2); - } else if (loc1 < 4.0 / 6.0) { - blue = loc3; - red = loc3 * (1 - loc2); - green = blue - (loc3 - red) * (6 * loc1 - 3); - } else if (loc1 < 5.0 / 6.0) { - blue = loc3; - green = loc3 * (1 - loc2); - red = green + (loc3 - green) * (6 * loc1 - 4); - } else { - red = loc3; - green = loc3 * (1 - loc2); - blue = red - (loc3 - green) * (6 * loc1 - 5); - } - return Color(int(red * 255), int(green * 255), int(blue * 255)); -} - -std::string Color::toHex() -{ - std::stringstream ss; - ss << *this; - return ss.str(); -} \ No newline at end of file diff --git a/src/framework/util/color.h b/src/framework/util/color.h deleted file mode 100644 index 964b5b5..0000000 --- a/src/framework/util/color.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef COLOR_H -#define COLOR_H - -#include "../stdext/types.h" -#include "../stdext/cast.h" -#include "../stdext/string.h" -#include "../const.h" -#include -#include -#include - -class Color -{ -public: - Color() : m_r(1.0f), m_g(1.0f), m_b(1.0f), m_a(1.0f) { } - Color(uint32 rgba) { setRGBA(rgba); } - Color(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) : m_r(r/255.0f), m_g(g/255.0f), m_b(b/255.0f), m_a(a/255.0f) { } - Color(int r, int g, int b, int a = 0xFF) : m_r(r/255.0f), m_g(g/255.0f), m_b(b/255.0f), m_a(a/255.0f) { } - Color(float r, float g, float b, float a = 1.0f) : m_r(r), m_g(g), m_b(b), m_a(a) { } - Color(const std::string& coltext); - - uint8 a() const { return 255.0f * m_a; } - uint8 b() const { return 255.0f * m_b; } - uint8 g() const { return 255.0f * m_g; } - uint8 r() const { return 255.0f * m_r; } - - float aF() const { return m_a; } - float bF() const { return m_b; } - float gF() const { return m_g; } - float rF() const { return m_r; } - - void setRed(int r) { m_r = 0.003921f * r; } - void setGreen(int g) { m_g = 0.003921f * g; } - void setBlue(int b) { m_b = 0.003921f * b; } - void setAlpha(int a) { m_a = 0.003921f * a; } - - void setRed(float r) { m_r = r; } - void setGreen(float g) { m_g = g; } - void setBlue(float b) { m_b = b; } - void setAlpha(float a) { m_a = a; } - - void setRGBA(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) { m_r = r/255.0f; m_g = g/255.0f; m_b = b/255.0f; m_a = a/255.0f; } - void setRGBA(uint32 rgba) { setRGBA((rgba >> 0) & 0xff, (rgba >> 8) & 0xff, (rgba >> 16) & 0xff, (rgba >> 24) & 0xff); } - - Color opacity(float opacity) const { - return Color(m_r, m_g, m_b, m_a * opacity); - } - - Color operator+(const Color& other) const { return Color(m_r + other.m_r, m_g + other.m_g, m_b + other.m_b, m_a + other.m_a); } - Color operator-(const Color& other) const { return Color(m_r - other.m_r, m_g - other.m_g, m_b - other.m_b, m_a - other.m_a); } - - Color operator*(float v) const { return Color(m_r*v, m_g*v, m_b*v, m_a*v); } - Color operator/(float v) const { return Color(m_r/v, m_g/v, m_b/v, m_a/v); } - - Color& operator=(uint32_t rgba) { setRGBA(rgba); return *this; } - - Color operator+=(const Color& other) const { - return Color(std::min(1.0f, m_r + other.m_r), std::min(1.0f, m_g + other.m_g), - std::min(1.0f, m_b + other.m_b), std::min(1.0f, m_a + other.m_a)); - } - - Color& operator=(const Color& other) { m_r = other.m_r; m_g = other.m_g; m_b = other.m_b; m_a = other.m_a; return *this; } - bool operator==(const Color& other) const { - if (std::abs(other.m_r - m_r) > 0.001) return false; - if (std::abs(other.m_g - m_g) > 0.001) return false; - if (std::abs(other.m_b - m_b) > 0.001) return false; - if (std::abs(other.m_a - m_a) > 0.001) return false; - return true; - } - bool operator!=(const Color& other) const { return !(other == *this); } - - std::string toHex(); - - static uint8 to8bit(const Color& color) { - uint8 c = 0; - c += (color.r() / 51) * 36; - c += (color.g() / 51) * 6; - c += (color.b() / 51); - return c; - } - - static Color from8bit(int color) { - if(color >= 216 || color <= 0) - return Color(0, 0, 0); - - int r = int(color / 36) % 6 * 51; - int g = int(color / 6) % 6 * 51; - int b = color % 6 * 51; - return Color(r, g, b); - } - - static Color getOutfitColor(int color); - - static const Color alpha; - static const Color white; - static const Color black; - static const Color red; - static const Color darkRed; - static const Color green; - static const Color darkGreen; - static const Color blue; - static const Color darkBlue; - static const Color pink; - static const Color darkPink; - static const Color yellow; - static const Color darkYellow; - static const Color teal; - static const Color darkTeal; - static const Color gray; - static const Color darkGray; - static const Color lightGray; - static const Color orange; - -private: - float m_r; - float m_g; - float m_b; - float m_a; -}; - -inline std::ostream& operator<<(std::ostream& out, const Color& color) -{ - using namespace std; - out << "#" << hex << setfill('0') - << setw(2) << (int)color.r() - << setw(2) << (int)color.g() - << setw(2) << (int)color.b() - << setw(2) << (int)color.a(); - out << dec << setfill(' '); - return out; -} - -inline std::istream& operator>>(std::istream& in, Color& color) -{ - using namespace std; - std::string tmp; - - if(in.get() == '#') { - in >> tmp; - - if(tmp.length() == 6 || tmp.length() == 8) { - color.setRed((uint8)stdext::hex_to_dec(tmp.substr(0, 2))); - color.setGreen((uint8)stdext::hex_to_dec(tmp.substr(2, 2))); - color.setBlue((uint8)stdext::hex_to_dec(tmp.substr(4, 2))); - if(tmp.length() == 8) - color.setAlpha((uint8)stdext::hex_to_dec(tmp.substr(6, 2))); - else - color.setAlpha(255); - } else - in.seekg(-(std::streampos)tmp.length()-1, ios_base::cur); - } else { - in.unget(); - in >> tmp; - - if(tmp == "alpha") { - color = Color::alpha; - } else if(tmp == "black") { - color = Color::black; - } else if(tmp == "white") { - color = Color::white; - } else if(tmp == "red") { - color = Color::red; - } else if(tmp == "darkRed") { - color = Color::darkRed; - } else if(tmp == "green") { - color = Color::green; - } else if(tmp == "darkGreen") { - color = Color::darkGreen; - } else if(tmp == "blue") { - color = Color::blue; - } else if(tmp == "darkBlue") { - color = Color::darkBlue; - } else if(tmp == "pink") { - color = Color::pink; - } else if(tmp == "darkPink") { - color = Color::darkPink; - } else if(tmp == "yellow") { - color = Color::yellow; - } else if(tmp == "darkYellow") { - color = Color::darkYellow; - } else if(tmp == "teal") { - color = Color::teal; - } else if(tmp == "darkTeal") { - color = Color::darkTeal; - } else if(tmp == "gray") { - color = Color::gray; - } else if(tmp == "darkGray") { - color = Color::darkGray; - } else if(tmp == "lightGray") { - color = Color::lightGray; - } else if(tmp == "orange") { - color = Color::orange; - } else { - in.seekg(-tmp.length(), ios_base::cur); - } - } - return in; -} - -#endif diff --git a/src/framework/util/extras.cpp b/src/framework/util/extras.cpp deleted file mode 100644 index 52f9d71..0000000 --- a/src/framework/util/extras.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "extras.h" -#include -#include -#include - -Extras g_extras; diff --git a/src/framework/util/extras.h b/src/framework/util/extras.h deleted file mode 100644 index 46c7fe5..0000000 --- a/src/framework/util/extras.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef EXTRAS_H -#define EXTRAS_H - -#include -#include -#include -#include - -constexpr bool default_value = true; - -#define DEFINE_OPTION(option, description) { m_options[ #option ] = std::make_pair(description, &(this -> option )); } - -class Extras { -public: - Extras() { - DEFINE_OPTION(limitedPolling, "Limited polling"); - - DEFINE_OPTION(debugWalking, "Debug walking"); - DEFINE_OPTION(debugPredictiveWalking, "Debug predictive walking"); - DEFINE_OPTION(debugPathfinding, "Debug path finding"); - DEFINE_OPTION(debugRender, "Debug render"); - DEFINE_OPTION(debugProxy, "Debug proxy"); - DEFINE_OPTION(showPredictions, "Show predictions"); - DEFINE_OPTION(debugWidgets, "Debug widgets"); - - DEFINE_OPTION(disablePredictiveWalking, "Disable predictive walking"); - } - - bool botDetection = default_value; - - bool newMapViewRendering = default_value; - bool limitedPolling = default_value; - - bool debugWalking = false; - bool debugPredictiveWalking = false; - bool debugPathfinding = false; - bool debugRender = false; - bool debugProxy = false; - bool disablePredictiveWalking = false; - bool showPredictions = false; - bool debugWidgets = false; - - int testMode = 0; - - void set(const std::string& key, bool value) { - auto it = m_options.find(key); - if (it == m_options.end()) { - g_logger.fatal(std::string("Invalid extraOptions key:") + key); - return; - } - *(it->second.second) = value; - } - - bool get(const std::string& key) { - auto it = m_options.find(key); - if (it == m_options.end()) { - g_logger.fatal(std::string("Invalid extraOptions key:") + key); - return false; - } - return *(it->second.second); - } - - std::string getDescription(const std::string& key) { - auto it = m_options.find(key); - if (it == m_options.end()) { - g_logger.fatal(std::string("Invalid extraOptions key:") + key); - return ""; - } - return it->second.first; - } - - std::vector getAll() { - std::vector ret; - for (auto& it : m_options) - ret.push_back(it.first); - return ret; - } - -private: - std::map> m_options; - std::deque framerRenderTimes; -}; - -extern Extras g_extras; - -#endif \ No newline at end of file diff --git a/src/framework/util/framecounter.h b/src/framework/util/framecounter.h deleted file mode 100644 index 0607434..0000000 --- a/src/framework/util/framecounter.h +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include "../stdext/time.h" - -class FrameCounter { -public: - void addFrame() // not thread-safe - { - ticks_t now = stdext::millis(); - m_framesList.push_back(now); - m_frames += 1; - while (m_framesList.front() + 1000 < now) { - m_framesList.pop_front(); - m_frames -= 1; - } - } - - int getFps() // thread safe - { - return m_frames.load(); - } - -private: - std::list m_framesList; - std::atomic_int m_frames; -}; diff --git a/src/framework/util/matrix.h b/src/framework/util/matrix.h deleted file mode 100644 index d9aaf76..0000000 --- a/src/framework/util/matrix.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MATRIX_H -#define MATRIX_H - -#include -#include -#include -#include - -template -class Matrix -{ -public: - Matrix() { setIdentity(); } - Matrix(int) {} // construct without initializing identity matrix - Matrix(const Matrix& other) = default; - template - Matrix(const std::initializer_list& values) { *this = values; } - template - Matrix(const U *values) { *this = values; } - - void setIdentity(); - bool isIdentity() const; - void fill(T value); - - Matrix transposed() const; - typename std::enable_if::type transpose() { *this = transposed(); } - - T *data() { return m[0]; } - const T *data() const { return m[0]; } - - T& operator()(int row, int column) { return m[row-1][column-1]; } - T operator()(int row, int column) const { return m[row-1][column-1]; } - - Matrix& operator=(const Matrix& other) = default; - template - Matrix& operator=(const std::initializer_list& values); - template - Matrix& operator=(const U *values); - Matrix& operator+=(const Matrix& other); - Matrix& operator-=(const Matrix& other); - Matrix& operator*=(T factor); - Matrix& operator/=(T divisor); - bool operator==(const Matrix& other) const; - bool operator!=(const Matrix& other) const; - -private: - T m[N][M]; -}; - -template -void Matrix::setIdentity() { - for(int i=0;i -bool Matrix::isIdentity() const { - for(int i=0;i -void Matrix::fill(T value) { - for(int i=0;i -Matrix Matrix::transposed() const { - Matrix result(1); - for(int i=0;i -template -Matrix& Matrix::operator=(const std::initializer_list& values) { - auto it = values.begin(); - for(int i=0;i -template -Matrix& Matrix::operator=(const U *values) { - for(int i=0;i -Matrix& Matrix::operator+=(const Matrix& other) { - for(int i=0;i -Matrix& Matrix::operator-=(const Matrix& other) { - for(int i=0;i -Matrix& Matrix::operator*=(T factor) { - for(int i=0;i -Matrix& Matrix::operator/=(T divisor) { - for(int i=0;i -bool Matrix::operator==(const Matrix& other) const -{ - for(int i=0;i -bool Matrix::operator!=(const Matrix& other) const -{ - return !(*this == other); -} - -template -std::ostream& operator<<(std::ostream& out, const Matrix& mat) -{ - for(int i=1;i<=N;++i) { - for(int j=1;j<=M;++j) { - out << mat(i,j); - if(j != M) - out << " "; - } - out << "\n"; - } - return out; -} - -template -std::istream& operator>>(std::istream& in, Matrix& mat) -{ - for(int i=0;i> mat(i,j); - return in; -} - -// faster comparing for 3x3 matrixes -template<> -inline bool Matrix<3,3,float>::operator==(const Matrix<3,3,float>& other) const -{ - return m[0][0] == other.m[0][0] && m[1][1] == other.m[1][1] && - m[2][1] == other.m[2][1] && m[2][0] == other.m[2][0] && - m[1][2] == other.m[1][2] && m[0][2] == other.m[0][2] && - m[1][0] == other.m[1][0] && m[0][1] == other.m[0][1] && - m[2][2] == other.m[2][2]; -} - -template -Matrix operator*(const Matrix& a, const Matrix& b) -{ - static_assert(N==P, "N==P"); - Matrix c(1); - for(int i=1;i<=M;++i) { - for(int j=1;j<=Q;++j) { - T sum = 0; - for(int k=1;k<=N;++k) - sum += a(i,k) * b(k,j); - c(i,j) = sum; - } - } - return c; -} - -template -Matrix operator+(const Matrix& a, const Matrix& b) { Matrix c(a); c += b; return c; } - -template -Matrix operator-(const Matrix& a, const Matrix& b) { Matrix c(a); c -= b; return c; } - -template -Matrix operator*(const Matrix& a, float b) { Matrix c(a); c *= b; return c; } - -template -Matrix operator/(const Matrix& a, float b) { Matrix c = a; c /= b; return c; } - -typedef Matrix<4,4> Matrix4x4; -typedef Matrix<3,3> Matrix3x3; -typedef Matrix<2,2> Matrix2x2; - -typedef Matrix4x4 Matrix4; -typedef Matrix3x3 Matrix3; -typedef Matrix2x2 Matrix2; - -#endif diff --git a/src/framework/util/point.h b/src/framework/util/point.h deleted file mode 100644 index 1bb4cd0..0000000 --- a/src/framework/util/point.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef POINT_H -#define POINT_H - -#include "../stdext/types.h" -#include -#include - -template -class TSize; - -template -class TPoint -{ -public: - TPoint() : x(0), y(0) {} - TPoint(T x, T y) : x(x), y(y) { } - TPoint(const TPoint& other) : x(other.x), y(other.y) { } - - bool isNull() const { return x==0 && y==0; } - TSize toSize() const { return TSize(x, y); } - - TPoint operator-() const { return TPoint(-x, -y); } - - TPoint operator+(const TPoint& other) const { return TPoint(x + other.x, y + other.y); } - TPoint& operator+=(const TPoint& other) { x+=other.x; y+=other.y; return *this; } - TPoint operator-(const TPoint& other) const { return TPoint(x - other.x, y - other.y); } - TPoint& operator-=(const TPoint& other) { x-=other.x; y-=other.y; return *this; } - TPoint operator*(const TPoint& other) const { return TPoint(x * other.x, y * other.y); } - TPoint& operator*=(const TPoint& other) { x*=other.x; y*=other.y; return *this; } - TPoint operator/(const TPoint& other) const { return TPoint(x/other.x, y/other.y); } - TPoint& operator/=(const TPoint& other) { x/=other.x; y/=other.y; return *this; } - - TPoint operator+(T other) const { return TPoint(x + other, y + other); } - TPoint& operator+=(T other) { x+=other; y+=other; return *this; } - TPoint operator-(T other) const { return TPoint(x - other, y - other); } - TPoint& operator-=(T other) { x-=other; y-=other; return *this; } - TPoint operator*(float v) const { return TPoint(x*v, y*v); } - TPoint& operator*=(float v) { x*=v; y*=v; return *this; } - TPoint operator/(float v) const { return TPoint(x/v, y/v); } - TPoint& operator/=(float v) { x/=v; y/=v; return *this; } - - TPoint operator&(int a) { return TPoint(x & a, y & a); } - TPoint& operator&=(int a) { x &= a; y &= a; return *this; } - - bool operator<=(const TPoint&other) const { return x<=other.x || (x==other.x && y<=other.y); } - bool operator>=(const TPoint&other) const { return x>=other.x || (x==other.x && y>=other.y); } - bool operator<(const TPoint&other) const { return x(const TPoint&other) const { return x>other.x || (x==other.x && y>other.y); } - - TPoint& operator=(const TPoint& other) { x = other.x; y = other.y; return *this; } - bool operator==(const TPoint& other) const { return other.x==x && other.y==y; } - bool operator!=(const TPoint& other) const { return other.x!=x || other.y!=y; } - - float length() const { return sqrt((float)(x*x + y*y)); } - T manhattanLength() const { return std::abs(x) + std::abs(y); } - - float distanceFrom(const TPoint& other) const { - return TPoint(x - other.x, y - other.y).getLength(); - } - - T x, y; -}; - -typedef TPoint Point; -typedef TPoint PointF; - -template -std::ostream& operator<<(std::ostream& out, const TPoint& point) -{ - out << point.x << " " << point.y; - return out; -} - -template -std::istream& operator>>(std::istream& in, TPoint& point) -{ - in >> point.x; - in >> point.y; - return in; -} - -#endif diff --git a/src/framework/util/qrcodegen.c b/src/framework/util/qrcodegen.c deleted file mode 100644 index 9da795e..0000000 --- a/src/framework/util/qrcodegen.c +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * QR Code generator library (C) - * - * Copyright (c) Project Nayuki. (MIT License) - * https://www.nayuki.io/page/qr-code-generator-library - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#include -#include -#include -#include -#include "qrcodegen.h" - -#ifndef QRCODEGEN_TEST - #define testable static // Keep functions private -#else - #define testable // Expose private functions -#endif - - -/*---- Forward declarations for private functions ----*/ - -// Regarding all public and private functions defined in this source file: -// - They require all pointer/array arguments to be not null unless the array length is zero. -// - They only read input scalar/array arguments, write to output pointer/array -// arguments, and return scalar values; they are "pure" functions. -// - They don't read mutable global variables or write to any global variables. -// - They don't perform I/O, read the clock, print to console, etc. -// - They allocate a small and constant amount of stack memory. -// - They don't allocate or free any memory on the heap. -// - They don't recurse or mutually recurse. All the code -// could be inlined into the top-level public functions. -// - They run in at most quadratic time with respect to input arguments. -// Most functions run in linear time, and some in constant time. -// There are no unbounded loops or non-obvious termination conditions. -// - They are completely thread-safe if the caller does not give the -// same writable buffer to concurrent calls to these functions. - -testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen); - -testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]); -testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl); -testable int getNumRawDataModules(int ver); - -testable void reedSolomonComputeDivisor(int degree, uint8_t result[]); -testable void reedSolomonComputeRemainder(const uint8_t data[], int dataLen, - const uint8_t generator[], int degree, uint8_t result[]); -testable uint8_t reedSolomonMultiply(uint8_t x, uint8_t y); - -testable void initializeFunctionModules(int version, uint8_t qrcode[]); -static void drawWhiteFunctionModules(uint8_t qrcode[], int version); -static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[]); -testable int getAlignmentPatternPositions(int version, uint8_t result[7]); -static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[]); - -static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[]); -static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], enum qrcodegen_Mask mask); -static long getPenaltyScore(const uint8_t qrcode[]); -static int finderPenaltyCountPatterns(const int runHistory[7], int qrsize); -static int finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, int runHistory[7], int qrsize); -static void finderPenaltyAddHistory(int currentRunLength, int runHistory[7]); - -testable bool getModule(const uint8_t qrcode[], int x, int y); -testable void setModule(uint8_t qrcode[], int x, int y, bool isBlack); -testable void setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack); -static bool getBit(int x, int i); - -testable int calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars); -testable int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int version); -static int numCharCountBits(enum qrcodegen_Mode mode, int version); - - - -/*---- Private tables of constants ----*/ - -// The set of all legal characters in alphanumeric mode, where each character -// value maps to the index in the string. For checking text and encoding segments. -static const char *ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; - -// For generating error correction codes. -testable const int8_t ECC_CODEWORDS_PER_BLOCK[4][41] = { - // Version: (note that index 0 is for padding, and is set to an illegal value) - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level - {-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Low - {-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, // Medium - {-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Quartile - {-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // High -}; - -#define qrcodegen_REED_SOLOMON_DEGREE_MAX 30 // Based on the table above - -// For generating error correction codes. -testable const int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41] = { - // Version: (note that index 0 is for padding, and is set to an illegal value) - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level - {-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low - {-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium - {-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile - {-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High -}; - -// For automatic mask pattern selection. -static const int PENALTY_N1 = 3; -static const int PENALTY_N2 = 3; -static const int PENALTY_N3 = 40; -static const int PENALTY_N4 = 10; - - - -/*---- High-level QR Code encoding functions ----*/ - -// Public function - see documentation comment in header file. -bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[], - enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) { - - size_t textLen = strlen(text); - if (textLen == 0) - return qrcodegen_encodeSegmentsAdvanced(NULL, 0, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode); - size_t bufLen = (size_t)qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion); - - struct qrcodegen_Segment seg; - if (qrcodegen_isNumeric(text)) { - if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_NUMERIC, textLen) > bufLen) - goto fail; - seg = qrcodegen_makeNumeric(text, tempBuffer); - } else if (qrcodegen_isAlphanumeric(text)) { - if (qrcodegen_calcSegmentBufferSize(qrcodegen_Mode_ALPHANUMERIC, textLen) > bufLen) - goto fail; - seg = qrcodegen_makeAlphanumeric(text, tempBuffer); - } else { - if (textLen > bufLen) - goto fail; - for (size_t i = 0; i < textLen; i++) - tempBuffer[i] = (uint8_t)text[i]; - seg.mode = qrcodegen_Mode_BYTE; - seg.bitLength = calcSegmentBitLength(seg.mode, textLen); - if (seg.bitLength == -1) - goto fail; - seg.numChars = (int)textLen; - seg.data = tempBuffer; - } - return qrcodegen_encodeSegmentsAdvanced(&seg, 1, ecl, minVersion, maxVersion, mask, boostEcl, tempBuffer, qrcode); - -fail: - qrcode[0] = 0; // Set size to invalid value for safety - return false; -} - - -// Public function - see documentation comment in header file. -bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[], - enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) { - - struct qrcodegen_Segment seg; - seg.mode = qrcodegen_Mode_BYTE; - seg.bitLength = calcSegmentBitLength(seg.mode, dataLen); - if (seg.bitLength == -1) { - qrcode[0] = 0; // Set size to invalid value for safety - return false; - } - seg.numChars = (int)dataLen; - seg.data = dataAndTemp; - return qrcodegen_encodeSegmentsAdvanced(&seg, 1, ecl, minVersion, maxVersion, mask, boostEcl, dataAndTemp, qrcode); -} - - -// Appends the given number of low-order bits of the given value to the given byte-based -// bit buffer, increasing the bit length. Requires 0 <= numBits <= 16 and val < 2^numBits. -testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen) { - assert(0 <= numBits && numBits <= 16 && (unsigned long)val >> numBits == 0); - for (int i = numBits - 1; i >= 0; i--, (*bitLen)++) - buffer[*bitLen >> 3] |= ((val >> i) & 1) << (7 - (*bitLen & 7)); -} - - - -/*---- Low-level QR Code encoding functions ----*/ - -// Public function - see documentation comment in header file. -bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], size_t len, - enum qrcodegen_Ecc ecl, uint8_t tempBuffer[], uint8_t qrcode[]) { - return qrcodegen_encodeSegmentsAdvanced(segs, len, ecl, - qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true, tempBuffer, qrcode); -} - - -// Public function - see documentation comment in header file. -bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], size_t len, enum qrcodegen_Ecc ecl, - int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl, uint8_t tempBuffer[], uint8_t qrcode[]) { - assert(segs != NULL || len == 0); - assert(qrcodegen_VERSION_MIN <= minVersion && minVersion <= maxVersion && maxVersion <= qrcodegen_VERSION_MAX); - assert(0 <= (int)ecl && (int)ecl <= 3 && -1 <= (int)mask && (int)mask <= 7); - - // Find the minimal version number to use - int version, dataUsedBits; - for (version = minVersion; ; version++) { - int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available - dataUsedBits = getTotalBits(segs, len, version); - if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) - break; // This version number is found to be suitable - if (version >= maxVersion) { // All versions in the range could not fit the given data - qrcode[0] = 0; // Set size to invalid value for safety - return false; - } - } - assert(dataUsedBits != -1); - - // Increase the error correction level while the data still fits in the current version number - for (int i = (int)qrcodegen_Ecc_MEDIUM; i <= (int)qrcodegen_Ecc_HIGH; i++) { // From low to high - if (boostEcl && dataUsedBits <= getNumDataCodewords(version, (enum qrcodegen_Ecc)i) * 8) - ecl = (enum qrcodegen_Ecc)i; - } - - // Concatenate all segments to create the data bit string - memset(qrcode, 0, (size_t)qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0])); - int bitLen = 0; - for (size_t i = 0; i < len; i++) { - const struct qrcodegen_Segment *seg = &segs[i]; - appendBitsToBuffer((unsigned int)seg->mode, 4, qrcode, &bitLen); - appendBitsToBuffer((unsigned int)seg->numChars, numCharCountBits(seg->mode, version), qrcode, &bitLen); - for (int j = 0; j < seg->bitLength; j++) { - int bit = (seg->data[j >> 3] >> (7 - (j & 7))) & 1; - appendBitsToBuffer((unsigned int)bit, 1, qrcode, &bitLen); - } - } - assert(bitLen == dataUsedBits); - - // Add terminator and pad up to a byte if applicable - int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; - assert(bitLen <= dataCapacityBits); - int terminatorBits = dataCapacityBits - bitLen; - if (terminatorBits > 4) - terminatorBits = 4; - appendBitsToBuffer(0, terminatorBits, qrcode, &bitLen); - appendBitsToBuffer(0, (8 - bitLen % 8) % 8, qrcode, &bitLen); - assert(bitLen % 8 == 0); - - // Pad with alternating bytes until data capacity is reached - for (uint8_t padByte = 0xEC; bitLen < dataCapacityBits; padByte ^= 0xEC ^ 0x11) - appendBitsToBuffer(padByte, 8, qrcode, &bitLen); - - // Draw function and data codeword modules - addEccAndInterleave(qrcode, version, ecl, tempBuffer); - initializeFunctionModules(version, qrcode); - drawCodewords(tempBuffer, getNumRawDataModules(version) / 8, qrcode); - drawWhiteFunctionModules(qrcode, version); - initializeFunctionModules(version, tempBuffer); - - // Handle masking - if (mask == qrcodegen_Mask_AUTO) { // Automatically choose best mask - long minPenalty = LONG_MAX; - for (int i = 0; i < 8; i++) { - enum qrcodegen_Mask msk = (enum qrcodegen_Mask)i; - applyMask(tempBuffer, qrcode, msk); - drawFormatBits(ecl, msk, qrcode); - long penalty = getPenaltyScore(qrcode); - if (penalty < minPenalty) { - mask = msk; - minPenalty = penalty; - } - applyMask(tempBuffer, qrcode, msk); // Undoes the mask due to XOR - } - } - assert(0 <= (int)mask && (int)mask <= 7); - applyMask(tempBuffer, qrcode, mask); - drawFormatBits(ecl, mask, qrcode); - return true; -} - - - -/*---- Error correction code generation functions ----*/ - -// Appends error correction bytes to each block of the given data array, then interleaves -// bytes from the blocks and stores them in the result array. data[0 : dataLen] contains -// the input data. data[dataLen : rawCodewords] is used as a temporary work area and will -// be clobbered by this function. The final answer is stored in result[0 : rawCodewords]. -testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]) { - // Calculate parameter numbers - assert(0 <= (int)ecl && (int)ecl < 4 && qrcodegen_VERSION_MIN <= version && version <= qrcodegen_VERSION_MAX); - int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[(int)ecl][version]; - int blockEccLen = ECC_CODEWORDS_PER_BLOCK [(int)ecl][version]; - int rawCodewords = getNumRawDataModules(version) / 8; - int dataLen = getNumDataCodewords(version, ecl); - int numShortBlocks = numBlocks - rawCodewords % numBlocks; - int shortBlockDataLen = rawCodewords / numBlocks - blockEccLen; - - // Split data into blocks, calculate ECC, and interleave - // (not concatenate) the bytes into a single sequence - uint8_t rsdiv[qrcodegen_REED_SOLOMON_DEGREE_MAX]; - reedSolomonComputeDivisor(blockEccLen, rsdiv); - const uint8_t *dat = data; - for (int i = 0; i < numBlocks; i++) { - int datLen = shortBlockDataLen + (i < numShortBlocks ? 0 : 1); - uint8_t *ecc = &data[dataLen]; // Temporary storage - reedSolomonComputeRemainder(dat, datLen, rsdiv, blockEccLen, ecc); - for (int j = 0, k = i; j < datLen; j++, k += numBlocks) { // Copy data - if (j == shortBlockDataLen) - k -= numShortBlocks; - result[k] = dat[j]; - } - for (int j = 0, k = dataLen + i; j < blockEccLen; j++, k += numBlocks) // Copy ECC - result[k] = ecc[j]; - dat += datLen; - } -} - - -// Returns the number of 8-bit codewords that can be used for storing data (not ECC), -// for the given version number and error correction level. The result is in the range [9, 2956]. -testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl) { - int v = version, e = (int)ecl; - assert(0 <= e && e < 4); - return getNumRawDataModules(v) / 8 - - ECC_CODEWORDS_PER_BLOCK [e][v] - * NUM_ERROR_CORRECTION_BLOCKS[e][v]; -} - - -// Returns the number of data bits that can be stored in a QR Code of the given version number, after -// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8. -// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table. -testable int getNumRawDataModules(int ver) { - assert(qrcodegen_VERSION_MIN <= ver && ver <= qrcodegen_VERSION_MAX); - int result = (16 * ver + 128) * ver + 64; - if (ver >= 2) { - int numAlign = ver / 7 + 2; - result -= (25 * numAlign - 10) * numAlign - 55; - if (ver >= 7) - result -= 36; - } - assert(208 <= result && result <= 29648); - return result; -} - - - -/*---- Reed-Solomon ECC generator functions ----*/ - -// Computes a Reed-Solomon ECC generator polynomial for the given degree, storing in result[0 : degree]. -// This could be implemented as a lookup table over all possible parameter values, instead of as an algorithm. -testable void reedSolomonComputeDivisor(int degree, uint8_t result[]) { - assert(1 <= degree && degree <= qrcodegen_REED_SOLOMON_DEGREE_MAX); - // Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1. - // For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}. - memset(result, 0, (size_t)degree * sizeof(result[0])); - result[degree - 1] = 1; // Start off with the monomial x^0 - - // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), - // drop the highest monomial term which is always 1x^degree. - // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). - uint8_t root = 1; - for (int i = 0; i < degree; i++) { - // Multiply the current product by (x - r^i) - for (int j = 0; j < degree; j++) { - result[j] = reedSolomonMultiply(result[j], root); - if (j + 1 < degree) - result[j] ^= result[j + 1]; - } - root = reedSolomonMultiply(root, 0x02); - } -} - - -// Computes the Reed-Solomon error correction codeword for the given data and divisor polynomials. -// The remainder when data[0 : dataLen] is divided by divisor[0 : degree] is stored in result[0 : degree]. -// All polynomials are in big endian, and the generator has an implicit leading 1 term. -testable void reedSolomonComputeRemainder(const uint8_t data[], int dataLen, - const uint8_t generator[], int degree, uint8_t result[]) { - assert(1 <= degree && degree <= qrcodegen_REED_SOLOMON_DEGREE_MAX); - memset(result, 0, (size_t)degree * sizeof(result[0])); - for (int i = 0; i < dataLen; i++) { // Polynomial division - uint8_t factor = data[i] ^ result[0]; - memmove(&result[0], &result[1], (size_t)(degree - 1) * sizeof(result[0])); - result[degree - 1] = 0; - for (int j = 0; j < degree; j++) - result[j] ^= reedSolomonMultiply(generator[j], factor); - } -} - -#undef qrcodegen_REED_SOLOMON_DEGREE_MAX - - -// Returns the product of the two given field elements modulo GF(2^8/0x11D). -// All inputs are valid. This could be implemented as a 256*256 lookup table. -testable uint8_t reedSolomonMultiply(uint8_t x, uint8_t y) { - // Russian peasant multiplication - uint8_t z = 0; - for (int i = 7; i >= 0; i--) { - z = (uint8_t)((z << 1) ^ ((z >> 7) * 0x11D)); - z ^= ((y >> i) & 1) * x; - } - return z; -} - - - -/*---- Drawing function modules ----*/ - -// Clears the given QR Code grid with white modules for the given -// version's size, then marks every function module as black. -testable void initializeFunctionModules(int version, uint8_t qrcode[]) { - // Initialize QR Code - int qrsize = version * 4 + 17; - memset(qrcode, 0, (size_t)((qrsize * qrsize + 7) / 8 + 1) * sizeof(qrcode[0])); - qrcode[0] = (uint8_t)qrsize; - - // Fill horizontal and vertical timing patterns - fillRectangle(6, 0, 1, qrsize, qrcode); - fillRectangle(0, 6, qrsize, 1, qrcode); - - // Fill 3 finder patterns (all corners except bottom right) and format bits - fillRectangle(0, 0, 9, 9, qrcode); - fillRectangle(qrsize - 8, 0, 8, 9, qrcode); - fillRectangle(0, qrsize - 8, 9, 8, qrcode); - - // Fill numerous alignment patterns - uint8_t alignPatPos[7]; - int numAlign = getAlignmentPatternPositions(version, alignPatPos); - for (int i = 0; i < numAlign; i++) { - for (int j = 0; j < numAlign; j++) { - // Don't draw on the three finder corners - if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0))) - fillRectangle(alignPatPos[i] - 2, alignPatPos[j] - 2, 5, 5, qrcode); - } - } - - // Fill version blocks - if (version >= 7) { - fillRectangle(qrsize - 11, 0, 3, 6, qrcode); - fillRectangle(0, qrsize - 11, 6, 3, qrcode); - } -} - - -// Draws white function modules and possibly some black modules onto the given QR Code, without changing -// non-function modules. This does not draw the format bits. This requires all function modules to be previously -// marked black (namely by initializeFunctionModules()), because this may skip redrawing black function modules. -static void drawWhiteFunctionModules(uint8_t qrcode[], int version) { - // Draw horizontal and vertical timing patterns - int qrsize = qrcodegen_getSize(qrcode); - for (int i = 7; i < qrsize - 7; i += 2) { - setModule(qrcode, 6, i, false); - setModule(qrcode, i, 6, false); - } - - // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) - for (int dy = -4; dy <= 4; dy++) { - for (int dx = -4; dx <= 4; dx++) { - int dist = abs(dx); - if (abs(dy) > dist) - dist = abs(dy); - if (dist == 2 || dist == 4) { - setModuleBounded(qrcode, 3 + dx, 3 + dy, false); - setModuleBounded(qrcode, qrsize - 4 + dx, 3 + dy, false); - setModuleBounded(qrcode, 3 + dx, qrsize - 4 + dy, false); - } - } - } - - // Draw numerous alignment patterns - uint8_t alignPatPos[7]; - int numAlign = getAlignmentPatternPositions(version, alignPatPos); - for (int i = 0; i < numAlign; i++) { - for (int j = 0; j < numAlign; j++) { - if ((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0)) - continue; // Don't draw on the three finder corners - for (int dy = -1; dy <= 1; dy++) { - for (int dx = -1; dx <= 1; dx++) - setModule(qrcode, alignPatPos[i] + dx, alignPatPos[j] + dy, dx == 0 && dy == 0); - } - } - } - - // Draw version blocks - if (version >= 7) { - // Calculate error correction code and pack bits - int rem = version; // version is uint6, in the range [7, 40] - for (int i = 0; i < 12; i++) - rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); - long bits = (long)version << 12 | rem; // uint18 - assert(bits >> 18 == 0); - - // Draw two copies - for (int i = 0; i < 6; i++) { - for (int j = 0; j < 3; j++) { - int k = qrsize - 11 + j; - setModule(qrcode, k, i, (bits & 1) != 0); - setModule(qrcode, i, k, (bits & 1) != 0); - bits >>= 1; - } - } - } -} - - -// Draws two copies of the format bits (with its own error correction code) based -// on the given mask and error correction level. This always draws all modules of -// the format bits, unlike drawWhiteFunctionModules() which might skip black modules. -static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[]) { - // Calculate error correction code and pack bits - assert(0 <= (int)mask && (int)mask <= 7); - static const int table[] = {1, 0, 3, 2}; - int data = table[(int)ecl] << 3 | (int)mask; // errCorrLvl is uint2, mask is uint3 - int rem = data; - for (int i = 0; i < 10; i++) - rem = (rem << 1) ^ ((rem >> 9) * 0x537); - int bits = (data << 10 | rem) ^ 0x5412; // uint15 - assert(bits >> 15 == 0); - - // Draw first copy - for (int i = 0; i <= 5; i++) - setModule(qrcode, 8, i, getBit(bits, i)); - setModule(qrcode, 8, 7, getBit(bits, 6)); - setModule(qrcode, 8, 8, getBit(bits, 7)); - setModule(qrcode, 7, 8, getBit(bits, 8)); - for (int i = 9; i < 15; i++) - setModule(qrcode, 14 - i, 8, getBit(bits, i)); - - // Draw second copy - int qrsize = qrcodegen_getSize(qrcode); - for (int i = 0; i < 8; i++) - setModule(qrcode, qrsize - 1 - i, 8, getBit(bits, i)); - for (int i = 8; i < 15; i++) - setModule(qrcode, 8, qrsize - 15 + i, getBit(bits, i)); - setModule(qrcode, 8, qrsize - 8, true); // Always black -} - - -// Calculates and stores an ascending list of positions of alignment patterns -// for this version number, returning the length of the list (in the range [0,7]). -// Each position is in the range [0,177), and are used on both the x and y axes. -// This could be implemented as lookup table of 40 variable-length lists of unsigned bytes. -testable int getAlignmentPatternPositions(int version, uint8_t result[7]) { - if (version == 1) - return 0; - int numAlign = version / 7 + 2; - int step = (version == 32) ? 26 : - (version*4 + numAlign*2 + 1) / (numAlign*2 - 2) * 2; - for (int i = numAlign - 1, pos = version * 4 + 10; i >= 1; i--, pos -= step) - result[i] = (uint8_t)pos; - result[0] = 6; - return numAlign; -} - - -// Sets every pixel in the range [left : left + width] * [top : top + height] to black. -static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[]) { - for (int dy = 0; dy < height; dy++) { - for (int dx = 0; dx < width; dx++) - setModule(qrcode, left + dx, top + dy, true); - } -} - - - -/*---- Drawing data modules and masking ----*/ - -// Draws the raw codewords (including data and ECC) onto the given QR Code. This requires the initial state of -// the QR Code to be black at function modules and white at codeword modules (including unused remainder bits). -static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[]) { - int qrsize = qrcodegen_getSize(qrcode); - int i = 0; // Bit index into the data - // Do the funny zigzag scan - for (int right = qrsize - 1; right >= 1; right -= 2) { // Index of right column in each column pair - if (right == 6) - right = 5; - for (int vert = 0; vert < qrsize; vert++) { // Vertical counter - for (int j = 0; j < 2; j++) { - int x = right - j; // Actual x coordinate - bool upward = ((right + 1) & 2) == 0; - int y = upward ? qrsize - 1 - vert : vert; // Actual y coordinate - if (!getModule(qrcode, x, y) && i < dataLen * 8) { - bool black = getBit(data[i >> 3], 7 - (i & 7)); - setModule(qrcode, x, y, black); - i++; - } - // If this QR Code has any remainder bits (0 to 7), they were assigned as - // 0/false/white by the constructor and are left unchanged by this method - } - } - } - assert(i == dataLen * 8); -} - - -// XORs the codeword modules in this QR Code with the given mask pattern. -// The function modules must be marked and the codeword bits must be drawn -// before masking. Due to the arithmetic of XOR, calling applyMask() with -// the same mask value a second time will undo the mask. A final well-formed -// QR Code needs exactly one (not zero, two, etc.) mask applied. -static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], enum qrcodegen_Mask mask) { - assert(0 <= (int)mask && (int)mask <= 7); // Disallows qrcodegen_Mask_AUTO - int qrsize = qrcodegen_getSize(qrcode); - for (int y = 0; y < qrsize; y++) { - for (int x = 0; x < qrsize; x++) { - if (getModule(functionModules, x, y)) - continue; - bool invert; - switch ((int)mask) { - case 0: invert = (x + y) % 2 == 0; break; - case 1: invert = y % 2 == 0; break; - case 2: invert = x % 3 == 0; break; - case 3: invert = (x + y) % 3 == 0; break; - case 4: invert = (x / 3 + y / 2) % 2 == 0; break; - case 5: invert = x * y % 2 + x * y % 3 == 0; break; - case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; - case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; - default: assert(false); return; - } - bool val = getModule(qrcode, x, y); - setModule(qrcode, x, y, val ^ invert); - } - } -} - - -// Calculates and returns the penalty score based on state of the given QR Code's current modules. -// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. -static long getPenaltyScore(const uint8_t qrcode[]) { - int qrsize = qrcodegen_getSize(qrcode); - long result = 0; - - // Adjacent modules in row having same color, and finder-like patterns - for (int y = 0; y < qrsize; y++) { - bool runColor = false; - int runX = 0; - int runHistory[7] = {0}; - int padRun = qrsize; // Add white border to initial run - for (int x = 0; x < qrsize; x++) { - if (getModule(qrcode, x, y) == runColor) { - runX++; - if (runX == 5) - result += PENALTY_N1; - else if (runX > 5) - result++; - } else { - finderPenaltyAddHistory(runX + padRun, runHistory); - padRun = 0; - if (!runColor) - result += finderPenaltyCountPatterns(runHistory, qrsize) * PENALTY_N3; - runColor = getModule(qrcode, x, y); - runX = 1; - } - } - result += finderPenaltyTerminateAndCount(runColor, runX + padRun, runHistory, qrsize) * PENALTY_N3; - } - // Adjacent modules in column having same color, and finder-like patterns - for (int x = 0; x < qrsize; x++) { - bool runColor = false; - int runY = 0; - int runHistory[7] = {0}; - int padRun = qrsize; // Add white border to initial run - for (int y = 0; y < qrsize; y++) { - if (getModule(qrcode, x, y) == runColor) { - runY++; - if (runY == 5) - result += PENALTY_N1; - else if (runY > 5) - result++; - } else { - finderPenaltyAddHistory(runY + padRun, runHistory); - padRun = 0; - if (!runColor) - result += finderPenaltyCountPatterns(runHistory, qrsize) * PENALTY_N3; - runColor = getModule(qrcode, x, y); - runY = 1; - } - } - result += finderPenaltyTerminateAndCount(runColor, runY + padRun, runHistory, qrsize) * PENALTY_N3; - } - - // 2*2 blocks of modules having same color - for (int y = 0; y < qrsize - 1; y++) { - for (int x = 0; x < qrsize - 1; x++) { - bool color = getModule(qrcode, x, y); - if ( color == getModule(qrcode, x + 1, y) && - color == getModule(qrcode, x, y + 1) && - color == getModule(qrcode, x + 1, y + 1)) - result += PENALTY_N2; - } - } - - // Balance of black and white modules - int black = 0; - for (int y = 0; y < qrsize; y++) { - for (int x = 0; x < qrsize; x++) { - if (getModule(qrcode, x, y)) - black++; - } - } - int total = qrsize * qrsize; // Note that size is odd, so black/total != 1/2 - // Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)% - int k = (int)((labs(black * 20L - total * 10L) + total - 1) / total) - 1; - result += k * PENALTY_N4; - return result; -} - - -// Can only be called immediately after a white run is added, and -// returns either 0, 1, or 2. A helper function for getPenaltyScore(). -static int finderPenaltyCountPatterns(const int runHistory[7], int qrsize) { - int n = runHistory[1]; - assert(n <= qrsize * 3); - bool core = n > 0 && runHistory[2] == n && runHistory[3] == n * 3 && runHistory[4] == n && runHistory[5] == n; - // The maximum QR Code size is 177, hence the black run length n <= 177. - // Arithmetic is promoted to int, so n*4 will not overflow. - return (core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) - + (core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0); -} - - -// Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore(). -static int finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, int runHistory[7], int qrsize) { - if (currentRunColor) { // Terminate black run - finderPenaltyAddHistory(currentRunLength, runHistory); - currentRunLength = 0; - } - currentRunLength += qrsize; // Add white border to final run - finderPenaltyAddHistory(currentRunLength, runHistory); - return finderPenaltyCountPatterns(runHistory, qrsize); -} - - -// Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore(). -static void finderPenaltyAddHistory(int currentRunLength, int runHistory[7]) { - memmove(&runHistory[1], &runHistory[0], 6 * sizeof(runHistory[0])); - runHistory[0] = currentRunLength; -} - - - -/*---- Basic QR Code information ----*/ - -// Public function - see documentation comment in header file. -int qrcodegen_getSize(const uint8_t qrcode[]) { - assert(qrcode != NULL); - int result = qrcode[0]; - assert((qrcodegen_VERSION_MIN * 4 + 17) <= result - && result <= (qrcodegen_VERSION_MAX * 4 + 17)); - return result; -} - - -// Public function - see documentation comment in header file. -bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y) { - assert(qrcode != NULL); - int qrsize = qrcode[0]; - return (0 <= x && x < qrsize && 0 <= y && y < qrsize) && getModule(qrcode, x, y); -} - - -// Gets the module at the given coordinates, which must be in bounds. -testable bool getModule(const uint8_t qrcode[], int x, int y) { - int qrsize = qrcode[0]; - assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize); - int index = y * qrsize + x; - return getBit(qrcode[(index >> 3) + 1], index & 7); -} - - -// Sets the module at the given coordinates, which must be in bounds. -testable void setModule(uint8_t qrcode[], int x, int y, bool isBlack) { - int qrsize = qrcode[0]; - assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize); - int index = y * qrsize + x; - int bitIndex = index & 7; - int byteIndex = (index >> 3) + 1; - if (isBlack) - qrcode[byteIndex] |= 1 << bitIndex; - else - qrcode[byteIndex] &= (1 << bitIndex) ^ 0xFF; -} - - -// Sets the module at the given coordinates, doing nothing if out of bounds. -testable void setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack) { - int qrsize = qrcode[0]; - if (0 <= x && x < qrsize && 0 <= y && y < qrsize) - setModule(qrcode, x, y, isBlack); -} - - -// Returns true iff the i'th bit of x is set to 1. Requires x >= 0 and 0 <= i <= 14. -static bool getBit(int x, int i) { - return ((x >> i) & 1) != 0; -} - - - -/*---- Segment handling ----*/ - -// Public function - see documentation comment in header file. -bool qrcodegen_isAlphanumeric(const char *text) { - assert(text != NULL); - for (; *text != '\0'; text++) { - if (strchr(ALPHANUMERIC_CHARSET, *text) == NULL) - return false; - } - return true; -} - - -// Public function - see documentation comment in header file. -bool qrcodegen_isNumeric(const char *text) { - assert(text != NULL); - for (; *text != '\0'; text++) { - if (*text < '0' || *text > '9') - return false; - } - return true; -} - - -// Public function - see documentation comment in header file. -size_t qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars) { - int temp = calcSegmentBitLength(mode, numChars); - if (temp == -1) - return SIZE_MAX; - assert(0 <= temp && temp <= INT16_MAX); - return ((size_t)temp + 7) / 8; -} - - -// Returns the number of data bits needed to represent a segment -// containing the given number of characters using the given mode. Notes: -// - Returns -1 on failure, i.e. numChars > INT16_MAX or -// the number of needed bits exceeds INT16_MAX (i.e. 32767). -// - Otherwise, all valid results are in the range [0, INT16_MAX]. -// - For byte mode, numChars measures the number of bytes, not Unicode code points. -// - For ECI mode, numChars must be 0, and the worst-case number of bits is returned. -// An actual ECI segment can have shorter data. For non-ECI modes, the result is exact. -testable int calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars) { - // All calculations are designed to avoid overflow on all platforms - if (numChars > (unsigned int)INT16_MAX) - return -1; - long result = (long)numChars; - if (mode == qrcodegen_Mode_NUMERIC) - result = (result * 10 + 2) / 3; // ceil(10/3 * n) - else if (mode == qrcodegen_Mode_ALPHANUMERIC) - result = (result * 11 + 1) / 2; // ceil(11/2 * n) - else if (mode == qrcodegen_Mode_BYTE) - result *= 8; - else if (mode == qrcodegen_Mode_KANJI) - result *= 13; - else if (mode == qrcodegen_Mode_ECI && numChars == 0) - result = 3 * 8; - else { // Invalid argument - assert(false); - return -1; - } - assert(result >= 0); - if (result > INT16_MAX) - return -1; - return (int)result; -} - - -// Public function - see documentation comment in header file. -struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]) { - assert(data != NULL || len == 0); - struct qrcodegen_Segment result; - result.mode = qrcodegen_Mode_BYTE; - result.bitLength = calcSegmentBitLength(result.mode, len); - assert(result.bitLength != -1); - result.numChars = (int)len; - if (len > 0) - memcpy(buf, data, len * sizeof(buf[0])); - result.data = buf; - return result; -} - - -// Public function - see documentation comment in header file. -struct qrcodegen_Segment qrcodegen_makeNumeric(const char *digits, uint8_t buf[]) { - assert(digits != NULL); - struct qrcodegen_Segment result; - size_t len = strlen(digits); - result.mode = qrcodegen_Mode_NUMERIC; - int bitLen = calcSegmentBitLength(result.mode, len); - assert(bitLen != -1); - result.numChars = (int)len; - if (bitLen > 0) - memset(buf, 0, ((size_t)bitLen + 7) / 8 * sizeof(buf[0])); - result.bitLength = 0; - - unsigned int accumData = 0; - int accumCount = 0; - for (; *digits != '\0'; digits++) { - char c = *digits; - assert('0' <= c && c <= '9'); - accumData = accumData * 10 + (unsigned int)(c - '0'); - accumCount++; - if (accumCount == 3) { - appendBitsToBuffer(accumData, 10, buf, &result.bitLength); - accumData = 0; - accumCount = 0; - } - } - if (accumCount > 0) // 1 or 2 digits remaining - appendBitsToBuffer(accumData, accumCount * 3 + 1, buf, &result.bitLength); - assert(result.bitLength == bitLen); - result.data = buf; - return result; -} - - -// Public function - see documentation comment in header file. -struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char *text, uint8_t buf[]) { - assert(text != NULL); - struct qrcodegen_Segment result; - size_t len = strlen(text); - result.mode = qrcodegen_Mode_ALPHANUMERIC; - int bitLen = calcSegmentBitLength(result.mode, len); - assert(bitLen != -1); - result.numChars = (int)len; - if (bitLen > 0) - memset(buf, 0, ((size_t)bitLen + 7) / 8 * sizeof(buf[0])); - result.bitLength = 0; - - unsigned int accumData = 0; - int accumCount = 0; - for (; *text != '\0'; text++) { - const char *temp = strchr(ALPHANUMERIC_CHARSET, *text); - assert(temp != NULL); - accumData = accumData * 45 + (unsigned int)(temp - ALPHANUMERIC_CHARSET); - accumCount++; - if (accumCount == 2) { - appendBitsToBuffer(accumData, 11, buf, &result.bitLength); - accumData = 0; - accumCount = 0; - } - } - if (accumCount > 0) // 1 character remaining - appendBitsToBuffer(accumData, 6, buf, &result.bitLength); - assert(result.bitLength == bitLen); - result.data = buf; - return result; -} - - -// Public function - see documentation comment in header file. -struct qrcodegen_Segment qrcodegen_makeEci(long assignVal, uint8_t buf[]) { - struct qrcodegen_Segment result; - result.mode = qrcodegen_Mode_ECI; - result.numChars = 0; - result.bitLength = 0; - if (assignVal < 0) - assert(false); - else if (assignVal < (1 << 7)) { - memset(buf, 0, 1 * sizeof(buf[0])); - appendBitsToBuffer((unsigned int)assignVal, 8, buf, &result.bitLength); - } else if (assignVal < (1 << 14)) { - memset(buf, 0, 2 * sizeof(buf[0])); - appendBitsToBuffer(2, 2, buf, &result.bitLength); - appendBitsToBuffer((unsigned int)assignVal, 14, buf, &result.bitLength); - } else if (assignVal < 1000000L) { - memset(buf, 0, 3 * sizeof(buf[0])); - appendBitsToBuffer(6, 3, buf, &result.bitLength); - appendBitsToBuffer((unsigned int)(assignVal >> 10), 11, buf, &result.bitLength); - appendBitsToBuffer((unsigned int)(assignVal & 0x3FF), 10, buf, &result.bitLength); - } else - assert(false); - result.data = buf; - return result; -} - - -// Calculates the number of bits needed to encode the given segments at the given version. -// Returns a non-negative number if successful. Otherwise returns -1 if a segment has too -// many characters to fit its length field, or the total bits exceeds INT16_MAX. -testable int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int version) { - assert(segs != NULL || len == 0); - long result = 0; - for (size_t i = 0; i < len; i++) { - int numChars = segs[i].numChars; - int bitLength = segs[i].bitLength; - assert(0 <= numChars && numChars <= INT16_MAX); - assert(0 <= bitLength && bitLength <= INT16_MAX); - int ccbits = numCharCountBits(segs[i].mode, version); - assert(0 <= ccbits && ccbits <= 16); - if (numChars >= (1L << ccbits)) - return -1; // The segment's length doesn't fit the field's bit width - result += 4L + ccbits + bitLength; - if (result > INT16_MAX) - return -1; // The sum might overflow an int type - } - assert(0 <= result && result <= INT16_MAX); - return (int)result; -} - - -// Returns the bit width of the character count field for a segment in the given mode -// in a QR Code at the given version number. The result is in the range [0, 16]. -static int numCharCountBits(enum qrcodegen_Mode mode, int version) { - assert(qrcodegen_VERSION_MIN <= version && version <= qrcodegen_VERSION_MAX); - int i = (version + 7) / 17; - switch (mode) { - case qrcodegen_Mode_NUMERIC : { static const int temp[] = {10, 12, 14}; return temp[i]; } - case qrcodegen_Mode_ALPHANUMERIC: { static const int temp[] = { 9, 11, 13}; return temp[i]; } - case qrcodegen_Mode_BYTE : { static const int temp[] = { 8, 16, 16}; return temp[i]; } - case qrcodegen_Mode_KANJI : { static const int temp[] = { 8, 10, 12}; return temp[i]; } - case qrcodegen_Mode_ECI : return 0; - default: assert(false); return -1; // Dummy value - } -} \ No newline at end of file diff --git a/src/framework/util/qrcodegen.h b/src/framework/util/qrcodegen.h deleted file mode 100644 index c9353f2..0000000 --- a/src/framework/util/qrcodegen.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * QR Code generator library (C) - * - * Copyright (c) Project Nayuki. (MIT License) - * https://www.nayuki.io/page/qr-code-generator-library - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#pragma once - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * This library creates QR Code symbols, which is a type of two-dimension barcode. - * Invented by Denso Wave and described in the ISO/IEC 18004 standard. - * A QR Code structure is an immutable square grid of black and white cells. - * The library provides functions to create a QR Code from text or binary data. - * The library covers the QR Code Model 2 specification, supporting all versions (sizes) - * from 1 to 40, all 4 error correction levels, and 4 character encoding modes. - * - * Ways to create a QR Code object: - * - High level: Take the payload data and call qrcodegen_encodeText() or qrcodegen_encodeBinary(). - * - Low level: Custom-make the list of segments and call - * qrcodegen_encodeSegments() or qrcodegen_encodeSegmentsAdvanced(). - * (Note that all ways require supplying the desired error correction level and various byte buffers.) - */ - - -/*---- Enum and struct types----*/ - -/* - * The error correction level in a QR Code symbol. - */ -enum qrcodegen_Ecc { - // Must be declared in ascending order of error protection - // so that an internal qrcodegen function works properly - qrcodegen_Ecc_LOW = 0 , // The QR Code can tolerate about 7% erroneous codewords - qrcodegen_Ecc_MEDIUM , // The QR Code can tolerate about 15% erroneous codewords - qrcodegen_Ecc_QUARTILE, // The QR Code can tolerate about 25% erroneous codewords - qrcodegen_Ecc_HIGH , // The QR Code can tolerate about 30% erroneous codewords -}; - - -/* - * The mask pattern used in a QR Code symbol. - */ -enum qrcodegen_Mask { - // A special value to tell the QR Code encoder to - // automatically select an appropriate mask pattern - qrcodegen_Mask_AUTO = -1, - // The eight actual mask patterns - qrcodegen_Mask_0 = 0, - qrcodegen_Mask_1, - qrcodegen_Mask_2, - qrcodegen_Mask_3, - qrcodegen_Mask_4, - qrcodegen_Mask_5, - qrcodegen_Mask_6, - qrcodegen_Mask_7, -}; - - -/* - * Describes how a segment's data bits are interpreted. - */ -enum qrcodegen_Mode { - qrcodegen_Mode_NUMERIC = 0x1, - qrcodegen_Mode_ALPHANUMERIC = 0x2, - qrcodegen_Mode_BYTE = 0x4, - qrcodegen_Mode_KANJI = 0x8, - qrcodegen_Mode_ECI = 0x7, -}; - - -/* - * A segment of character/binary/control data in a QR Code symbol. - * The mid-level way to create a segment is to take the payload data - * and call a factory function such as qrcodegen_makeNumeric(). - * The low-level way to create a segment is to custom-make the bit buffer - * and initialize a qrcodegen_Segment struct with appropriate values. - * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. - * Any segment longer than this is meaningless for the purpose of generating QR Codes. - * Moreover, the maximum allowed bit length is 32767 because - * the largest QR Code (version 40) has 31329 modules. - */ -struct qrcodegen_Segment { - // The mode indicator of this segment. - enum qrcodegen_Mode mode; - - // The length of this segment's unencoded data. Measured in characters for - // numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode. - // Always zero or positive. Not the same as the data's bit length. - int numChars; - - // The data bits of this segment, packed in bitwise big endian. - // Can be null if the bit length is zero. - uint8_t *data; - - // The number of valid data bits used in the buffer. Requires - // 0 <= bitLength <= 32767, and bitLength <= (capacity of data array) * 8. - // The character count (numChars) must agree with the mode and the bit buffer length. - int bitLength; -}; - - - -/*---- Macro constants and functions ----*/ - -#define qrcodegen_VERSION_MIN 1 // The minimum version number supported in the QR Code Model 2 standard -#define qrcodegen_VERSION_MAX 40 // The maximum version number supported in the QR Code Model 2 standard - -// Calculates the number of bytes needed to store any QR Code up to and including the given version number, -// as a compile-time constant. For example, 'uint8_t buffer[qrcodegen_BUFFER_LEN_FOR_VERSION(25)];' -// can store any single QR Code from version 1 to 25 (inclusive). The result fits in an int (or int16). -// Requires qrcodegen_VERSION_MIN <= n <= qrcodegen_VERSION_MAX. -#define qrcodegen_BUFFER_LEN_FOR_VERSION(n) ((((n) * 4 + 17) * ((n) * 4 + 17) + 7) / 8 + 1) - -// The worst-case number of bytes needed to store one QR Code, up to and including -// version 40. This value equals 3918, which is just under 4 kilobytes. -// Use this more convenient value to avoid calculating tighter memory bounds for buffers. -#define qrcodegen_BUFFER_LEN_MAX qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX) - - - -/*---- Functions (high level) to generate QR Codes ----*/ - -/* - * Encodes the given text string to a QR Code, returning true if encoding succeeded. - * If the data is too long to fit in any version in the given range - * at the given ECC level, then false is returned. - * - The input text must be encoded in UTF-8 and contain no NULs. - * - The variables ecl and mask must correspond to enum constant values. - * - Requires 1 <= minVersion <= maxVersion <= 40. - * - The arrays tempBuffer and qrcode must each have a length - * of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). - * - After the function returns, tempBuffer contains no useful data. - * - If successful, the resulting QR Code may use numeric, - * alphanumeric, or byte mode to encode the text. - * - In the most optimistic case, a QR Code at version 40 with low ECC - * can hold any UTF-8 string up to 2953 bytes, or any alphanumeric string - * up to 4296 characters, or any digit string up to 7089 characters. - * These numbers represent the hard upper limit of the QR Code standard. - * - Please consult the QR Code specification for information on - * data capacities per version, ECC level, and text encoding mode. - */ -bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[], - enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl); - - -/* - * Encodes the given binary data to a QR Code, returning true if encoding succeeded. - * If the data is too long to fit in any version in the given range - * at the given ECC level, then false is returned. - * - The input array range dataAndTemp[0 : dataLen] should normally be - * valid UTF-8 text, but is not required by the QR Code standard. - * - The variables ecl and mask must correspond to enum constant values. - * - Requires 1 <= minVersion <= maxVersion <= 40. - * - The arrays dataAndTemp and qrcode must each have a length - * of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). - * - After the function returns, the contents of dataAndTemp may have changed, - * and does not represent useful data anymore. - * - If successful, the resulting QR Code will use byte mode to encode the data. - * - In the most optimistic case, a QR Code at version 40 with low ECC can hold any byte - * sequence up to length 2953. This is the hard upper limit of the QR Code standard. - * - Please consult the QR Code specification for information on - * data capacities per version, ECC level, and text encoding mode. - */ -bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[], - enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl); - - -/*---- Functions (low level) to generate QR Codes ----*/ - -/* - * Renders a QR Code representing the given segments at the given error correction level. - * The smallest possible QR Code version is automatically chosen for the output. Returns true if - * QR Code creation succeeded, or false if the data is too long to fit in any version. The ECC level - * of the result may be higher than the ecl argument if it can be done without increasing the version. - * This function allows the user to create a custom sequence of segments that switches - * between modes (such as alphanumeric and byte) to encode text in less space. - * This is a low-level API; the high-level API is qrcodegen_encodeText() and qrcodegen_encodeBinary(). - * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will - * result in them being clobbered, but the QR Code output will still be correct. - * But the qrcode array must not overlap tempBuffer or any segment's data buffer. - */ -bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], size_t len, - enum qrcodegen_Ecc ecl, uint8_t tempBuffer[], uint8_t qrcode[]); - - -/* - * Renders a QR Code representing the given segments with the given encoding parameters. - * Returns true if QR Code creation succeeded, or false if the data is too long to fit in the range of versions. - * The smallest possible QR Code version within the given range is automatically - * chosen for the output. Iff boostEcl is true, then the ECC level of the result - * may be higher than the ecl argument if it can be done without increasing the - * version. The mask is either between qrcodegen_Mask_0 to 7 to force that mask, or - * qrcodegen_Mask_AUTO to automatically choose an appropriate mask (which may be slow). - * This function allows the user to create a custom sequence of segments that switches - * between modes (such as alphanumeric and byte) to encode text in less space. - * This is a low-level API; the high-level API is qrcodegen_encodeText() and qrcodegen_encodeBinary(). - * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will - * result in them being clobbered, but the QR Code output will still be correct. - * But the qrcode array must not overlap tempBuffer or any segment's data buffer. - */ -bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], size_t len, enum qrcodegen_Ecc ecl, - int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl, uint8_t tempBuffer[], uint8_t qrcode[]); - - -/* - * Tests whether the given string can be encoded as a segment in alphanumeric mode. - * A string is encodable iff each character is in the following set: 0 to 9, A to Z - * (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon. - */ -bool qrcodegen_isAlphanumeric(const char *text); - - -/* - * Tests whether the given string can be encoded as a segment in numeric mode. - * A string is encodable iff each character is in the range 0 to 9. - */ -bool qrcodegen_isNumeric(const char *text); - - -/* - * Returns the number of bytes (uint8_t) needed for the data buffer of a segment - * containing the given number of characters using the given mode. Notes: - * - Returns SIZE_MAX on failure, i.e. numChars > INT16_MAX or - * the number of needed bits exceeds INT16_MAX (i.e. 32767). - * - Otherwise, all valid results are in the range [0, ceil(INT16_MAX / 8)], i.e. at most 4096. - * - It is okay for the user to allocate more bytes for the buffer than needed. - * - For byte mode, numChars measures the number of bytes, not Unicode code points. - * - For ECI mode, numChars must be 0, and the worst-case number of bytes is returned. - * An actual ECI segment can have shorter data. For non-ECI modes, the result is exact. - */ -size_t qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars); - - -/* - * Returns a segment representing the given binary data encoded in - * byte mode. All input byte arrays are acceptable. Any text string - * can be converted to UTF-8 bytes and encoded as a byte mode segment. - */ -struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]); - - -/* - * Returns a segment representing the given string of decimal digits encoded in numeric mode. - */ -struct qrcodegen_Segment qrcodegen_makeNumeric(const char *digits, uint8_t buf[]); - - -/* - * Returns a segment representing the given text string encoded in alphanumeric mode. - * The characters allowed are: 0 to 9, A to Z (uppercase only), space, - * dollar, percent, asterisk, plus, hyphen, period, slash, colon. - */ -struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char *text, uint8_t buf[]); - - -/* - * Returns a segment representing an Extended Channel Interpretation - * (ECI) designator with the given assignment value. - */ -struct qrcodegen_Segment qrcodegen_makeEci(long assignVal, uint8_t buf[]); - - -/*---- Functions to extract raw data from QR Codes ----*/ - -/* - * Returns the side length of the given QR Code, assuming that encoding succeeded. - * The result is in the range [21, 177]. Note that the length of the array buffer - * is related to the side length - every 'uint8_t qrcode[]' must have length at least - * qrcodegen_BUFFER_LEN_FOR_VERSION(version), which equals ceil(size^2 / 8 + 1). - */ -int qrcodegen_getSize(const uint8_t qrcode[]); - - -/* - * Returns the color of the module (pixel) at the given coordinates, which is false - * for white or true for black. The top left corner has the coordinates (x=0, y=0). - * If the given coordinates are out of bounds, then false (white) is returned. - */ -bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y); - - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/framework/util/rect.h b/src/framework/util/rect.h deleted file mode 100644 index 5548363..0000000 --- a/src/framework/util/rect.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef RECT_H -#define RECT_H - -#include "../stdext/types.h" -#include "../const.h" -#include - -template -class TPoint; - -template -class TSize; - -template -class TRect -{ -public: - TRect() : x1(0), y1(0), x2(-1), y2(-1) { } - TRect(T x, T y, T width, T height) : x1(x), y1(y), x2(x+width-1), y2(y+height-1) { } - TRect(const TPoint& topLeft, const TPoint& bottomRight) : x1(topLeft.x), y1(topLeft.y), x2(bottomRight.x), y2(bottomRight.y) { } - TRect(const TRect& other) : x1(other.x1), y1(other.y1), x2(other.x2), y2(other.y2) { } - TRect(T x, T y, const TSize& size) : x1(x), y1(y), x2(x+size.width()-1), y2(y+size.height()-1) { } - TRect(const TPoint& topLeft, const TSize& size) : x1(topLeft.x), y1(topLeft.y), x2(x1+size.width()-1), y2(y1+size.height()-1) { } - TRect(const TPoint& topLeft, int width, int height) : x1(topLeft.x), y1(topLeft.y), x2(x1+width-1), y2(y1+height-1) { } - - bool isNull() const { return x2 == x1 - 1 && y2 == y1 - 1; } - bool isEmpty() const { return x1 > x2 || y1 > y2; } - bool isValid() const { return x1 <= x2 && y1 <= y2; } - - inline T left() const { return x1; } - inline T top() const { return y1; } - inline T right() const { return x2; } - inline T bottom() const { return y2; } - inline T horizontalCenter() const { return x1 + (x2 - x1)/2; } - inline T verticalCenter() const { return y1 + (y2 - y1)/2; } - inline T x() const { return x1; } - inline T y() const { return y1; } - TPoint topLeft() const { return TPoint(x1, y1); } - TPoint bottomRight() const { return TPoint(x2, y2); } - TPoint topRight() const { return TPoint(x2, y1); } - TPoint bottomLeft() const { return TPoint(x1, y2); } - TPoint topCenter() const { return TPoint((x1+x2)/2, y1); } - TPoint bottomCenter() const { return TPoint((x1+x2)/2, y2); } - TPoint centerLeft() const { return TPoint(x1, (y1+y2)/2); } - TPoint centerRight() const { return TPoint(x2, (y1+y2)/2); } - TPoint center() const { return TPoint((x1+x2)/2, (y1+y2)/2); } - T width() const { return x2 - x1 + 1; } - T height() const { return y2 - y1 + 1; } - TSize size() const { return TSize(width(), height()); } - void reset() { x1 = y1 = 0; x2 = y2 = -1; } - void clear() { x2 = x1 - 1; y2 = y1 - 1; } - - void setLeft(T pos) { x1 = pos; } - void setTop(T pos) { y1 = pos; } - void setRight(T pos) { x2 = pos; } - void setBottom(T pos) { y2 = pos; } - void setX(T x) { x1 = x; } - void setY(T y) { y1 = y; } - void setTopLeft(const TPoint &p) { x1 = p.x; y1 = p.y; } - void setBottomRight(const TPoint &p) { x2 = p.x; y2 = p.y; } - void setTopRight(const TPoint &p) { x2 = p.x; y1 = p.y; } - void setBottomLeft(const TPoint &p) { x1 = p.x; y2 = p.y; } - void setWidth(T width) { x2 = x1 + width - 1; } - void setHeight(T height) { y2 = y1 + height- 1; } - void setSize(const TSize& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; } - void setRect(T x, T y, T width, T height) { x1 = x; y1 = y; x2 = (x + width - 1); y2 = (y + height - 1); } - void setCoords(int left, int top, int right, int bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; } - - void expandLeft(T add) { x1 -= add; } - void expandTop(T add) { y1 -= add; } - void expandRight(T add) { x2 += add; } - void expandBottom(T add) { y2 += add; } - void expand(T top, T right, T bottom, T left) { x1 -= left; y1 -= top; x2 += right; y2 += bottom; } - void expand(T add) { x1 -= add; y1 -= add; x2 += add; y2 += add; } - - void translate(T x, T y) { x1 += x; y1 += y; x2 += x; y2 += y; } - void translate(const TPoint &p) { x1 += p.x; y1 += p.y; x2 += p.x; y2 += p.y; } - void resize(const TSize& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; } - void resize(T width, T height) { x2 = x1 + width - 1; y2 = y1 + height - 1; } - void move(T x, T y) { x2 += x - x1; y2 += y - y1; x1 = x; y1 = y; } - void move(const TPoint &p) { x2 += p.x - x1; y2 += p.y - y1; x1 = p.x; y1 = p.y; } - void moveLeft(T pos) { x2 += (pos - x1); x1 = pos; } - void moveTop(T pos) { y2 += (pos - y1); y1 = pos; } - void moveRight(T pos) { x1 += (pos - x2); x2 = pos; } - void moveBottom(T pos) { y1 += (pos - y2); y2 = pos; } - void moveTopLeft(const TPoint &p) { moveLeft(p.x); moveTop(p.y); } - void moveBottomRight(const TPoint &p) { moveRight(p.x); moveBottom(p.y); } - void moveTopRight(const TPoint &p) { moveRight(p.x); moveTop(p.y); } - void moveBottomLeft(const TPoint &p) { moveLeft(p.x); moveBottom(p.y); } - void moveTopCenter(const TPoint &p) { moveHorizontalCenter(p.x); moveTop(p.y); } - void moveBottomCenter(const TPoint &p) { moveHorizontalCenter(p.x); moveBottom(p.y); } - void moveCenterLeft(const TPoint &p) { moveLeft(p.x); moveVerticalCenter(p.y); } - void moveCenterRight(const TPoint &p) { moveRight(p.x); moveVerticalCenter(p.y); } - - TRect translated(int x, int y) const { return TRect(TPoint(x1 + x, y1 + y), TPoint(x2 + x, y2 + y)); } - TRect translated(const TPoint &p) const { return TRect(TPoint(x1 + p.x, y1 + p.y), TPoint(x2 + p.x, y2 + p.y)); } - - TRect expanded(T add) const { return TRect(TPoint(x1 - add, y1 - add), TPoint(x2 + add, y2 + add)); } - - void moveCenter(const TPoint &p) { - T w = x2 - x1; - T h = y2 - y1; - x1 = p.x - w/2; - y1 = p.y - h/2; - x2 = x1 + w; - y2 = y1 + h; - } - void moveHorizontalCenter(T x) { - T w = x2 - x1; - x1 = x - w/2; - x2 = x1 + w; - } - void moveVerticalCenter(T y) { - T h = y2 - y1; - y1 = y - h/2; - y2 = y1 + h; - } - - bool contains(const TPoint &p, bool insideOnly = false) const { - T l, r; - if(x2 < x1 - 1) { - l = x2; - r = x1; - } else { - l = x1; - r = x2; - } - if(insideOnly) { - if(p.x <= l || p.x >= r) - return false; - } else { - if(p.x < l || p.x > r) - return false; - } - T t, b; - if(y2 < y1 - 1) { - t = y2; - b = y1; - } else { - t = y1; - b = y2; - } - if(insideOnly) { - if(p.y <= t || p.y >= b) - return false; - } else { - if(p.y < t || p.y > b) - return false; - } - return true; - } - - bool contains(const TRect &r, bool insideOnly = false) const { - if(contains(r.topLeft(), insideOnly) && contains(r.bottomRight(), insideOnly)) - return true; - return false; - } - - bool intersects(const TRect &r) const { - if(isNull() || r.isNull()) - return false; - - int l1 = x1; - int r1 = x1; - if(x2 - x1 + 1 < 0) - l1 = x2; - else - r1 = x2; - - int l2 = r.x1; - int r2 = r.x1; - if(r.x2 - r.x1 + 1 < 0) - l2 = r.x2; - else - r2 = r.x2; - - if(l1 > r2 || l2 > r1) - return false; - - int t1 = y1; - int b1 = y1; - if(y2 - y1 + 1 < 0) - t1 = y2; - else - b1 = y2; - - int t2 = r.y1; - int b2 = r.y1; - if(r.y2 - r.y1 + 1 < 0) - t2 = r.y2; - else - b2 = r.y2; - - if(t1 > b2 || t2 > b1) - return false; - - return true; - } - - TRect united(const TRect &r) const { - TRect tmp; - tmp.x1 = std::min(x1, r.x1); - tmp.x2 = std::max(x2, r.x2); - tmp.y1 = std::min(y1, r.y1); - tmp.y2 = std::max(y2, r.y2); - return tmp; - } - - TRect intersection(const TRect &r) const { - if(isNull()) - return r; - if(r.isNull()) - return *this; - - int l1 = x1; - int r1 = x1; - if(x2 - x1 + 1 < 0) - l1 = x2; - else - r1 = x2; - - int l2 = r.x1; - int r2 = r.x1; - if(r.x2 - r.x1 + 1 < 0) - l2 = r.x2; - else - r2 = r.x2; - - int t1 = y1; - int b1 = y1; - if(y2 - y1 + 1 < 0) - t1 = y2; - else - b1 = y2; - - int t2 = r.y1; - int b2 = r.y1; - if(r.y2 - r.y1 + 1 < 0) - t2 = r.y2; - else - b2 = r.y2; - - TRect tmp; - tmp.x1 = std::max(l1, l2); - tmp.x2 = std::min(r1, r2); - tmp.y1 = std::max(t1, t2); - tmp.y2 = std::min(b1, b2); - return tmp; - } - - void bind(const TRect &r) { - if(isNull() || r.isNull()) - return; - - if(right() > r.right()) - moveRight(r.right()); - if(bottom() > r.bottom()) - moveBottom(r.bottom()); - if(left() < r.left()) - moveLeft(r.left()); - if(top() < r.top()) - moveTop(r.top()); - } - - void alignIn(const TRect &r, Fw::AlignmentFlag align) { - if(align == Fw::AlignTopLeft) - moveTopLeft(r.topLeft()); - else if(align == Fw::AlignTopRight) - moveTopRight(r.topRight()); - else if(align == Fw::AlignTopCenter) - moveTopCenter(r.topCenter()); - else if(align == Fw::AlignBottomLeft) - moveBottomLeft(r.bottomLeft()); - else if(align == Fw::AlignBottomRight) - moveBottomRight(r.bottomRight()); - else if(align == Fw::AlignBottomCenter) - moveBottomCenter(r.bottomCenter()); - else if(align == Fw::AlignLeftCenter) - moveCenterLeft(r.centerLeft()); - else if(align == Fw::AlignCenter) - moveCenter(r.center()); - else if(align == Fw::AlignRightCenter) - moveCenterRight(r.centerRight()); - } - - TRect& operator=(const TRect& other) { x1 = other.x1; y1 = other.y1; x2 = other.x2; y2 = other.y2; return *this; } - bool operator==(const TRect& other) const { return (x1 == other.x1 && y1 == other.y1 && x2 == other.x2 && y2 == other.y2); } - bool operator!=(const TRect& other) const { return (x1 != other.x1 || y1 != other.y1 || x2 != other.x2 || y2 != other.y2); } - - TRect& operator|=(const TRect& other) { *this = united(other); return *this; } - TRect& operator&=(const TRect& other) { *this = intersection(other); return *this; } - - TRect operator+(TPoint other) const { return translated(other); } - TRect& operator+=(TPoint other) { x1 += other.x; x2 += other.x; y1 += other.y; y2 += other.y; return *this; } - - TRect operator*(float num) const { return TRect(x1 * num, y1 * num, (x2 - x1) * num, (y2 - y1) * num); } - -private: - T x1, y1, x2, y2; -}; - -typedef TRect Rect; -typedef TRect RectF; - -template -std::ostream& operator<<(std::ostream& out, const TRect& rect) -{ - out << rect.left() << " " << rect.top() << " " << rect.width() << " " << rect.height(); - return out; -} - -template -std::istream& operator>>(std::istream& in, TRect& rect) -{ - T x, y , w, h; - in >> x >> y >> w >> h; - rect.setRect(x,y,w,h); - return in; -} - -#endif diff --git a/src/framework/util/size.h b/src/framework/util/size.h deleted file mode 100644 index 40f15ba..0000000 --- a/src/framework/util/size.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2010-2017 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef SIZE_H -#define SIZE_H - -#include "point.h" -#include "../const.h" - -template -class TSize -{ -public: - TSize() : wd(-1), ht(-1) {}; - TSize(T width, T height) : wd(width), ht(height) { }; - TSize(const TSize& other) : wd(other.wd), ht(other.ht) { }; - - TPoint toPoint() const { return TPoint(wd, ht); } - - bool isNull() const { return wd==0 && ht==0; } - bool isEmpty() const { return wd<1 || ht<1; } - bool isValid() const { return wd>=0 && ht>=0; } - - T width() const { return wd; } - T height() const { return ht; } - - void resize(T w, T h) { wd = w; ht = h; } - void setWidth(T w) { wd = w; } - void setHeight(T h) { ht = h; } - - TSize operator-() const { return TSize(-wd, -ht); } - TSize operator+(const TSize& other) const { return TSize(wd + other.wd, ht + other.ht); } - TSize& operator+=(const TSize& other) { wd+=other.wd; ht+=other.ht; return *this; } - TSize operator-(const TSize& other) const { return TSize(wd - other.wd, ht - other.ht); } - TSize& operator-=(const TSize& other) { wd-=other.wd; ht-=other.ht; return *this; } - TSize operator*(const TSize& other) const { return TSize((T)other.wd*wd, (T)ht*other.ht); } - TSize& operator*=(const TSize& other) { wd=(T)other.wd*wd; ht=(T)ht*other.ht; return *this; } - TSize operator/(const TSize& other) const { return TSize((T)wd/other.wd, (T)ht/other.ht); } - TSize& operator/=(const TSize& other) { (T)wd/=other.wd; (T)ht/=other.ht; return *this; } - TSize operator*(const float v) const { return TSize((T)wd*v, (T)ht*v); } - TSize& operator*=(const float v) { wd=(T)wd*v; ht=(T)ht*v; return *this; } - TSize operator/(const float v) const { return TSize((T)wd/v, (T)ht/v); } - TSize& operator/=(const float v) { wd/=v; ht/=v; return *this; } - - bool operator<=(const TSize&other) const { return wd<=other.wd || ht<=other.ht; } - bool operator>=(const TSize&other) const { return wd>=other.wd || ht>=other.ht; } - bool operator<(const TSize&other) const { return wd(const TSize&other) const { return wd>other.wd || ht>other.ht; } - - TSize& operator=(const TSize& other) { wd = other.wd; ht = other.ht; return *this; } - bool operator==(const TSize& other) const { return other.wd==wd && other.ht==ht; } - bool operator!=(const TSize& other) const { return other.wd!=wd || other.ht!=ht; } - - TSize expandedTo(const TSize& other) const { return TSize(std::max(wd, other.wd), std::max(ht, other.ht)); } - TSize boundedTo(const TSize& other) const { return TSize(std::min(wd, other.wd), std::min(ht, other.ht)); } - - void scale(const TSize& s, Fw::AspectRatioMode mode) { - if(mode == Fw::IgnoreAspectRatio || wd == 0 || ht == 0) { - wd = s.wd; - ht = s.ht; - } else { - bool useHeight; - T rw = (s.ht * wd) / ht; - - if(mode == Fw::KeepAspectRatio) - useHeight = (rw <= s.wd); - else // mode == Fw::KeepAspectRatioByExpanding - useHeight = (rw >= s.wd); - - if(useHeight) { - wd = rw; - ht = s.ht; - } else { - ht = (s.wd * ht)/wd; - wd = s.wd; - } - } - } - void scale(int w, int h, Fw::AspectRatioMode mode) { scale(TSize(w, h), mode); } - - float ratio() const { return (float)wd/ht; } - T area() const { return wd*ht; } - -private: - T wd, ht; -}; - -typedef TSize Size; -typedef TSize SizeF; - -template -std::ostream& operator<<(std::ostream& out, const TSize& size) -{ - out << size.width() << " " << size.height(); - return out; -} - -template -std::istream& operator>>(std::istream& in, TSize& size) -{ - T w, h; - in >> w >> h; - size.resize(w, h); - return in; -} - -#endif diff --git a/src/framework/xml/tinystr.cpp b/src/framework/xml/tinystr.cpp deleted file mode 100644 index 84dd8bd..0000000 --- a/src/framework/xml/tinystr.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include - -#ifndef TIXML_USE_STL - -#include "tinystr.h" - -// Error value for find primitive -const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); - - -// Null rep. -TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; - - -void TiXmlString::reserve (size_type cap) -{ - if (cap > capacity()) - { - TiXmlString tmp; - tmp.init(length(), cap); - memcpy(tmp.start(), data(), length()); - swap(tmp); - } -} - - -TiXmlString& TiXmlString::assign(const char* str, size_type len) -{ - size_type cap = capacity(); - if (len > cap || cap > 3*(len + 8)) - { - TiXmlString tmp; - tmp.init(len); - memcpy(tmp.start(), str, len); - swap(tmp); - } - else - { - memmove(start(), str, len); - set_size(len); - } - return *this; -} - - -TiXmlString& TiXmlString::append(const char* str, size_type len) -{ - size_type newsize = length() + len; - if (newsize > capacity()) - { - reserve (newsize + capacity()); - } - memmove(finish(), str, len); - set_size(newsize); - return *this; -} - - -TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) -{ - TiXmlString tmp; - tmp.reserve(a.length() + b.length()); - tmp += a; - tmp += b; - return tmp; -} - -TiXmlString operator + (const TiXmlString & a, const char* b) -{ - TiXmlString tmp; - TiXmlString::size_type b_len = static_cast( strlen(b) ); - tmp.reserve(a.length() + b_len); - tmp += a; - tmp.append(b, b_len); - return tmp; -} - -TiXmlString operator + (const char* a, const TiXmlString & b) -{ - TiXmlString tmp; - TiXmlString::size_type a_len = static_cast( strlen(a) ); - tmp.reserve(a_len + b.length()); - tmp.append(a, a_len); - tmp += b; - return tmp; -} - - -#endif // TIXML_USE_STL diff --git a/src/framework/xml/tinystr.h b/src/framework/xml/tinystr.h deleted file mode 100644 index ac0c2ab..0000000 --- a/src/framework/xml/tinystr.h +++ /dev/null @@ -1,304 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - - -#ifndef TIXML_USE_STL - -#ifndef TIXML_STRING_INCLUDED -#define TIXML_STRING_INCLUDED - -#include - -/* The support for explicit isn't that universal, and it isn't really - required - it is used to check that the TiXmlString class isn't incorrectly - used. Be nice to old compilers and macro it here: -*/ -#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - #define TIXML_EXPLICIT explicit -#elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - #define TIXML_EXPLICIT explicit -#else - #define TIXML_EXPLICIT -#endif - - -/* - TiXmlString is an emulation of a subset of the std::string template. - Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. - Only the member functions relevant to the TinyXML project have been implemented. - The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase - a string and there's no more room, we allocate a buffer twice as big as we need. -*/ -class TiXmlString -{ - public : - // The size type used - typedef size_t size_type; - - // Error value for find primitive - static const size_type npos; // = -1; - - - // TiXmlString empty constructor - TiXmlString () : rep_(&nullrep_) - { - } - - // TiXmlString copy constructor - TiXmlString ( const TiXmlString & copy) : rep_(0) - { - init(copy.length()); - memcpy(start(), copy.data(), length()); - } - - // TiXmlString constructor, based on a string - TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) - { - init( static_cast( strlen(copy) )); - memcpy(start(), copy, length()); - } - - // TiXmlString constructor, based on a string - TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) - { - init(len); - memcpy(start(), str, len); - } - - // TiXmlString destructor - ~TiXmlString () - { - quit(); - } - - TiXmlString& operator = (const char * copy) - { - return assign( copy, (size_type)strlen(copy)); - } - - TiXmlString& operator = (const TiXmlString & copy) - { - return assign(copy.start(), copy.length()); - } - - - // += operator. Maps to append - TiXmlString& operator += (const char * suffix) - { - return append(suffix, static_cast( strlen(suffix) )); - } - - // += operator. Maps to append - TiXmlString& operator += (char single) - { - return append(&single, 1); - } - - // += operator. Maps to append - TiXmlString& operator += (const TiXmlString & suffix) - { - return append(suffix.data(), suffix.length()); - } - - - // Convert a TiXmlString into a null-terminated char * - const char * c_str () const { return rep_->str; } - - // Convert a TiXmlString into a char * (need not be null terminated). - const char * data () const { return rep_->str; } - - // Return the length of a TiXmlString - size_type length () const { return rep_->size; } - - // Alias for length() - size_type size () const { return rep_->size; } - - // Checks if a TiXmlString is empty - bool empty () const { return rep_->size == 0; } - - // Return capacity of string - size_type capacity () const { return rep_->capacity; } - - - // single char extraction - const char& at (size_type index) const - { - VALIDATE( index < length() ); - return rep_->str[ index ]; - } - - // [] operator - char& operator [] (size_type index) const - { - VALIDATE( index < length() ); - return rep_->str[ index ]; - } - - // find a char in a string. Return TiXmlString::npos if not found - size_type find (char lookup) const - { - return find(lookup, 0); - } - - // find a char in a string from an offset. Return TiXmlString::npos if not found - size_type find (char tofind, size_type offset) const - { - if (offset >= length()) return npos; - - for (const char* p = c_str() + offset; *p != '\0'; ++p) - { - if (*p == tofind) return static_cast< size_type >( p - c_str() ); - } - return npos; - } - - void clear () - { - //Lee: - //The original was just too strange, though correct: - // TiXmlString().swap(*this); - //Instead use the quit & re-init: - quit(); - init(0,0); - } - - /* Function to reserve a big amount of data when we know we'll need it. Be aware that this - function DOES NOT clear the content of the TiXmlString if any exists. - */ - void reserve (size_type cap); - - TiXmlString& assign (const char* str, size_type len); - - TiXmlString& append (const char* str, size_type len); - - void swap (TiXmlString& other) - { - Rep* r = rep_; - rep_ = other.rep_; - other.rep_ = r; - } - - private: - - void init(size_type sz) { init(sz, sz); } - void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } - char* start() const { return rep_->str; } - char* finish() const { return rep_->str + rep_->size; } - - struct Rep - { - size_type size, capacity; - char str[1]; - }; - - void init(size_type sz, size_type cap) - { - if (cap) - { - // Lee: the original form: - // rep_ = static_cast(operator new(sizeof(Rep) + cap)); - // doesn't work in some cases of new being overloaded. Switching - // to the normal allocation, although use an 'int' for systems - // that are overly picky about structure alignment. - const size_type bytesNeeded = sizeof(Rep) + cap; - const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); - rep_ = reinterpret_cast( new int[ intsNeeded ] ); - - rep_->str[ rep_->size = sz ] = '\0'; - rep_->capacity = cap; - } - else - { - rep_ = &nullrep_; - } - } - - void quit() - { - if (rep_ != &nullrep_) - { - // The rep_ is really an array of ints. (see the allocator, above). - // Cast it back before delete, so the compiler won't incorrectly call destructors. - delete [] ( reinterpret_cast( rep_ ) ); - } - } - - Rep * rep_; - static Rep nullrep_; - -} ; - - -inline bool operator == (const TiXmlString & a, const TiXmlString & b) -{ - return ( a.length() == b.length() ) // optimization on some platforms - && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare -} -inline bool operator < (const TiXmlString & a, const TiXmlString & b) -{ - return strcmp(a.c_str(), b.c_str()) < 0; -} - -inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } -inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } -inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } -inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } - -inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } -inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } -inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } -inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } - -TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); -TiXmlString operator + (const TiXmlString & a, const char* b); -TiXmlString operator + (const char* a, const TiXmlString & b); - - -/* - TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. - Only the operators that we need for TinyXML have been developped. -*/ -class TiXmlOutStream : public TiXmlString -{ -public : - - // TiXmlOutStream << operator. - TiXmlOutStream & operator << (const TiXmlString & in) - { - *this += in; - return *this; - } - - // TiXmlOutStream << operator. - TiXmlOutStream & operator << (const char * in) - { - *this += in; - return *this; - } - -} ; - -#endif // TIXML_STRING_INCLUDED -#endif // TIXML_USE_STL diff --git a/src/framework/xml/tinyxml.cpp b/src/framework/xml/tinyxml.cpp deleted file mode 100644 index 8d52ed3..0000000 --- a/src/framework/xml/tinyxml.cpp +++ /dev/null @@ -1,1690 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ -#include - -#include - -#ifdef TIXML_USE_STL -#include -#include -#endif - -#include "tinyxml.h" - -FILE* TiXmlFOpen( const char* filename, const char* mode ); - -bool TiXmlBase::condenseWhiteSpace = true; - -// Microsoft compiler security -FILE* TiXmlFOpen( const char* filename, const char* mode ) -{ - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - FILE* fp = 0; - errno_t err = fopen_s( &fp, filename, mode ); - if ( !err && fp ) - return fp; - return 0; - #else - return fopen( filename, mode ); - #endif -} - -void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) -{ - int i=0; - - while( i<(int)str.length() ) - { - unsigned char c = (unsigned char) str[i]; - - if ( c == '&' - && i < ( (int)str.length() - 2 ) - && str[i+1] == '#' - && str[i+2] == 'x' ) - { - // Hexadecimal character reference. - // Pass through unchanged. - // © -- copyright symbol, for example. - // - // The -1 is a bug fix from Rob Laveaux. It keeps - // an overflow from happening if there is no ';'. - // There are actually 2 ways to exit this loop - - // while fails (error case) and break (semicolon found). - // However, there is no mechanism (currently) for - // this function to return an error. - while ( i<(int)str.length()-1 ) - { - outString->append( str.c_str() + i, 1 ); - ++i; - if ( str[i] == ';' ) - break; - } - } - else if ( c == '&' ) - { - outString->append( entity[0].str, entity[0].strLength ); - ++i; - } - else if ( c == '<' ) - { - outString->append( entity[1].str, entity[1].strLength ); - ++i; - } - else if ( c == '>' ) - { - outString->append( entity[2].str, entity[2].strLength ); - ++i; - } - else if ( c == '\"' ) - { - outString->append( entity[3].str, entity[3].strLength ); - ++i; - } - else if ( c == '\'' ) - { - outString->append( entity[4].str, entity[4].strLength ); - ++i; - } - else if ( c < 32 ) - { - // Easy pass at non-alpha/numeric/symbol - // Below 32 is symbolic. - char buf[ 32 ]; - - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); - #else - sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); - #endif - - //*ME: warning C4267: convert 'size_t' to 'int' - //*ME: Int-Cast to make compiler happy ... - outString->append( buf, (int)strlen( buf ) ); - ++i; - } - else - { - //char realc = (char) c; - //outString->append( &realc, 1 ); - *outString += (char) c; // somewhat more efficient function call. - ++i; - } - } -} - - -TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() -{ - parent = 0; - type = _type; - firstChild = 0; - lastChild = 0; - prev = 0; - next = 0; -} - - -TiXmlNode::~TiXmlNode() -{ - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; - - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } -} - - -void TiXmlNode::CopyTo( TiXmlNode* target ) const -{ - target->SetValue (value.c_str() ); - target->userData = userData; - target->location = location; -} - - -void TiXmlNode::Clear() -{ - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; - - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } - - firstChild = 0; - lastChild = 0; -} - - -TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) -{ - VALIDATE( node->parent == 0 || node->parent == this ); - VALIDATE( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); - - if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT ) - { - delete node; - if ( GetDocument() ) - GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - node->parent = this; - - node->prev = lastChild; - node->next = 0; - - if ( lastChild ) - lastChild->next = node; - else - firstChild = node; // it was an empty list. - - lastChild = node; - return node; -} - - -TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) -{ - if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) - { - if ( GetDocument() ) - GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - - return LinkEndChild( node ); -} - - -TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) -{ - if ( !beforeThis || beforeThis->parent != this ) { - return 0; - } - if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) - { - if ( GetDocument() ) - GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->next = beforeThis; - node->prev = beforeThis->prev; - if ( beforeThis->prev ) - { - beforeThis->prev->next = node; - } - else - { - VALIDATE( firstChild == beforeThis ); - firstChild = node; - } - beforeThis->prev = node; - return node; -} - - -TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) -{ - if ( !afterThis || afterThis->parent != this ) { - return 0; - } - if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) - { - if ( GetDocument() ) - GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->prev = afterThis; - node->next = afterThis->next; - if ( afterThis->next ) - { - afterThis->next->prev = node; - } - else - { - VALIDATE( lastChild == afterThis ); - lastChild = node; - } - afterThis->next = node; - return node; -} - - -TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) -{ - if ( !replaceThis ) - return 0; - - if ( replaceThis->parent != this ) - return 0; - - if ( withThis.ToDocument() ) { - // A document can never be a child. Thanks to Noam. - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = withThis.Clone(); - if ( !node ) - return 0; - - node->next = replaceThis->next; - node->prev = replaceThis->prev; - - if ( replaceThis->next ) - replaceThis->next->prev = node; - else - lastChild = node; - - if ( replaceThis->prev ) - replaceThis->prev->next = node; - else - firstChild = node; - - delete replaceThis; - node->parent = this; - return node; -} - - -bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) -{ - if ( !removeThis ) { - return false; - } - - if ( removeThis->parent != this ) - { - VALIDATE( 0 ); - return false; - } - - if ( removeThis->next ) - removeThis->next->prev = removeThis->prev; - else - lastChild = removeThis->prev; - - if ( removeThis->prev ) - removeThis->prev->next = removeThis->next; - else - firstChild = removeThis->next; - - delete removeThis; - return true; -} - -const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = firstChild; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = lastChild; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const -{ - if ( !previous ) - { - return FirstChild(); - } - else - { - VALIDATE( previous->parent == this ); - return previous->NextSibling(); - } -} - - -const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const -{ - if ( !previous ) - { - return FirstChild( val ); - } - else - { - VALIDATE( previous->parent == this ); - return previous->NextSibling( val ); - } -} - - -const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = next; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = prev; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - -void TiXmlElement::RemoveAttribute(const std::string &name) -{ - TiXmlAttribute* node = attributeSet.Find(name); - if ( node ) - { - attributeSet.Remove( node ); - delete node; - } -} - -const TiXmlElement* TiXmlNode::FirstChildElement() const -{ - const TiXmlNode* node; - - for ( node = FirstChild(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const -{ - const TiXmlNode* node; - - for ( node = FirstChild( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::NextSiblingElement() const -{ - const TiXmlNode* node; - - for ( node = NextSibling(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const -{ - const TiXmlNode* node; - - for ( node = NextSibling( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlDocument* TiXmlNode::GetDocument() const -{ - const TiXmlNode* node; - - for( node = this; node; node = node->parent ) - { - if ( node->ToDocument() ) - return node->ToDocument(); - } - return 0; -} - -TiXmlElement::TiXmlElement( const std::string& _value ) - : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) -{ - firstChild = lastChild = 0; - value = _value; -} - -TiXmlElement::TiXmlElement( const TiXmlElement& copy) - : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) -{ - firstChild = lastChild = 0; - copy.CopyTo( this ); -} - - -TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base ) -{ - ClearThis(); - base.CopyTo( this ); - return *this; -} - - -TiXmlElement::~TiXmlElement() -{ - ClearThis(); -} - - -void TiXmlElement::ClearThis() -{ - Clear(); - while( attributeSet.First() ) - { - TiXmlAttribute* node = attributeSet.First(); - attributeSet.Remove( node ); - delete node; - } -} - -std::string TiXmlElement::Attribute( const std::string& name ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - if ( attrib ) - return attrib->ValueStr(); - return std::string(); -} - -std::string TiXmlElement::Attribute( const std::string& name, int* i ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - std::string result; - - if ( attrib ) { - result = attrib->ValueStr(); - if ( i ) { - attrib->QueryIntValue( i ); - } - } - return result; -} - -std::string TiXmlElement::Attribute( const std::string& name, double* d ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - std::string result = 0; - - if ( attrib ) { - result = attrib->ValueStr(); - if ( d ) { - attrib->QueryDoubleValue( d ); - } - } - return result; -} - -void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value ) -{ - TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name ); - if ( attrib ) { - attrib->SetValue( _value ); - } -} - - -void TiXmlElement::Print( FILE* cfile, int depth ) const -{ - int i; - VALIDATE( cfile ); - for ( i=0; iNext() ) - { - fprintf( cfile, " " ); - attrib->Print( cfile, depth ); - } - - // There are 3 different formatting approaches: - // 1) An element without children is printed as a node - // 2) An element with only a text child is printed as text - // 3) An element with children is printed on multiple lines. - TiXmlNode* node; - if ( !firstChild ) - { - fprintf( cfile, " />" ); - } - else if ( firstChild == lastChild && firstChild->ToText() ) - { - fprintf( cfile, ">" ); - firstChild->Print( cfile, depth + 1 ); - fprintf( cfile, "", value.c_str() ); - } - else - { - fprintf( cfile, ">" ); - - for ( node = firstChild; node; node=node->NextSibling() ) - { - if ( !node->ToText() ) - { - fprintf( cfile, "\n" ); - } - node->Print( cfile, depth+1 ); - } - fprintf( cfile, "\n" ); - for( i=0; i", value.c_str() ); - } -} - - -void TiXmlElement::CopyTo( TiXmlElement* target ) const -{ - // superclass: - TiXmlNode::CopyTo( target ); - - // Element class: - // Clone the attributes, then clone the children. - const TiXmlAttribute* attribute = 0; - for( attribute = attributeSet.First(); - attribute; - attribute = attribute->Next() ) - { - target->SetAttribute( attribute->Name(), attribute->Value() ); - } - - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } -} - -bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this, attributeSet.First() ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); -} - - -TiXmlNode* TiXmlElement::Clone() const -{ - TiXmlElement* clone = new TiXmlElement( Value() ); - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -const char* TiXmlElement::GetText() const -{ - const TiXmlNode* child = this->FirstChild(); - if ( child ) { - const TiXmlText* childText = child->ToText(); - if ( childText ) { - return childText->Value(); - } - } - return 0; -} - - -TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - ClearError(); -} - -TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); -} - - -#ifdef TIXML_USE_STL -TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); -} -#endif - - -TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) -{ - copy.CopyTo( this ); -} - - -TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy ) -{ - Clear(); - copy.CopyTo( this ); - return *this; -} - - -bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) -{ - return LoadFile( Value(), encoding ); -} - - -bool TiXmlDocument::SaveFile() const -{ - return SaveFile( Value() ); -} - -bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) -{ - TIXML_STRING filename( _filename ); - value = filename; - - // reading in binary mode so that tinyxml can normalize the EOL - FILE* file = TiXmlFOpen( value.c_str (), "rb" ); - - if ( file ) - { - bool result = LoadFile( file, encoding ); - fclose( file ); - return result; - } - else - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } -} - -bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) -{ - if ( !file ) - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Delete the existing data: - Clear(); - location.Clear(); - - // Get the file size, so we can pre-allocate the string. HUGE speed impact. - long length = 0; - fseek( file, 0, SEEK_END ); - length = ftell( file ); - fseek( file, 0, SEEK_SET ); - - // Strange case, but good to handle up front. - if ( length <= 0 ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Subtle bug here. TinyXml did use fgets. But from the XML spec: - // 2.11 End-of-Line Handling - // - // - // ...the XML processor MUST behave as if it normalized all line breaks in external - // parsed entities (including the document entity) on input, before parsing, by translating - // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to - // a single #xA character. - // - // - // It is not clear fgets does that, and certainly isn't clear it works cross platform. - // Generally, you expect fgets to translate from the convention of the OS to the c/unix - // convention, and not work generally. - - /* - while( fgets( buf, sizeof(buf), file ) ) - { - data += buf; - } - */ - - char* buf = new char[ length+1 ]; - buf[0] = 0; - - if ( fread( buf, length, 1, file ) != 1 ) { - delete [] buf; - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Process the buffer in place to normalize new lines. (See comment above.) - // Copies from the 'p' to 'q' pointer, where p can advance faster if - // a newline-carriage return is hit. - // - // Wikipedia: - // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or - // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)... - // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others - // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS - // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9 - - const char* p = buf; // the read head - char* q = buf; // the write head - const char CR = 0x0d; - const char LF = 0x0a; - - buf[length] = 0; - while( *p ) { - VALIDATE( p < (buf+length) ); - VALIDATE( q <= (buf+length) ); - VALIDATE( q <= p ); - - if ( *p == CR ) { - *q++ = LF; - p++; - if ( *p == LF ) { // check for CR+LF (and skip LF) - p++; - } - } - else { - *q++ = *p++; - } - } - VALIDATE( q <= (buf+length) ); - *q = 0; - - Parse( buf, 0, encoding ); - - delete [] buf; - return !Error(); -} - - -bool TiXmlDocument::SaveFile( const char * filename ) const -{ - // The old c stuff lives on... - FILE* fp = TiXmlFOpen( filename, "w" ); - if ( fp ) - { - bool result = SaveFile( fp ); - fclose( fp ); - return result; - } - return false; -} - - -bool TiXmlDocument::SaveFile( FILE* fp ) const -{ - if ( useMicrosoftBOM ) - { - const unsigned char TIXML_UTF_LEAD_0 = 0xefU; - const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; - const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - - fputc( TIXML_UTF_LEAD_0, fp ); - fputc( TIXML_UTF_LEAD_1, fp ); - fputc( TIXML_UTF_LEAD_2, fp ); - } - Print( fp, 0 ); - return (ferror(fp) == 0); -} - - -void TiXmlDocument::CopyTo( TiXmlDocument* target ) const -{ - TiXmlNode::CopyTo( target ); - - target->error = error; - target->errorId = errorId; - target->errorDesc = errorDesc; - target->tabsize = tabsize; - target->errorLocation = errorLocation; - target->useMicrosoftBOM = useMicrosoftBOM; - - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } -} - - -TiXmlNode* TiXmlDocument::Clone() const -{ - TiXmlDocument* clone = new TiXmlDocument(); - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlDocument::Print( FILE* cfile, int depth ) const -{ - VALIDATE( cfile ); - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - node->Print( cfile, depth ); - fprintf( cfile, "\n" ); - } -} - - -bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); -} - - -const TiXmlAttribute* TiXmlAttribute::Next() const -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; -} - -/* -TiXmlAttribute* TiXmlAttribute::Next() -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; -} -*/ - -const TiXmlAttribute* TiXmlAttribute::Previous() const -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; -} - -/* -TiXmlAttribute* TiXmlAttribute::Previous() -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; -} -*/ - -void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const -{ - TIXML_STRING n, v; - - EncodeString( name, &n ); - EncodeString( value, &v ); - - if (value.find ('\"') == TIXML_STRING::npos) { - if ( cfile ) { - fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); - } - if ( str ) { - (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; - } - } - else { - if ( cfile ) { - fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); - } - if ( str ) { - (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; - } - } -} - - -int TiXmlAttribute::QueryIntValue( int* ival ) const -{ - if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; -} - -int TiXmlAttribute::QueryDoubleValue( double* dval ) const -{ - if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; -} - -void TiXmlAttribute::SetIntValue( int _value ) -{ - char buf [64]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); - #else - sprintf (buf, "%d", _value); - #endif - SetValue (buf); -} - -void TiXmlAttribute::SetDoubleValue( double _value ) -{ - char buf [256]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value); - #else - sprintf (buf, "%g", _value); - #endif - SetValue (buf); -} - -int TiXmlAttribute::IntValue() const -{ - return atoi (value.c_str ()); -} - -double TiXmlAttribute::DoubleValue() const -{ - return atof (value.c_str ()); -} - - -TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) -{ - copy.CopyTo( this ); -} - - -TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base ) -{ - Clear(); - base.CopyTo( this ); - return *this; -} - - -void TiXmlComment::Print( FILE* cfile, int depth ) const -{ - VALIDATE( cfile ); - for ( int i=0; i", value.c_str() ); -} - - -void TiXmlComment::CopyTo( TiXmlComment* target ) const -{ - TiXmlNode::CopyTo( target ); -} - - -bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlComment::Clone() const -{ - TiXmlComment* clone = new TiXmlComment(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlText::Print( FILE* cfile, int depth ) const -{ - VALIDATE( cfile ); - if ( cdata ) - { - int i; - fprintf( cfile, "\n" ); - for ( i=0; i\n", value.c_str() ); // unformatted output - } - else - { - TIXML_STRING buffer; - EncodeString( value, &buffer ); - fprintf( cfile, "%s", buffer.c_str() ); - } -} - - -void TiXmlText::CopyTo( TiXmlText* target ) const -{ - TiXmlNode::CopyTo( target ); - target->cdata = cdata; -} - - -bool TiXmlText::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlText::Clone() const -{ - TiXmlText* clone = 0; - clone = new TiXmlText( "" ); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -TiXmlDeclaration::TiXmlDeclaration( const char * _version, - const char * _encoding, - const char * _standalone ) - : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) -{ - version = _version; - encoding = _encoding; - standalone = _standalone; -} - - -#ifdef TIXML_USE_STL -TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, - const std::string& _encoding, - const std::string& _standalone ) - : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) -{ - version = _version; - encoding = _encoding; - standalone = _standalone; -} -#endif - - -TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) - : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) -{ - copy.CopyTo( this ); -} - - -TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) -{ - Clear(); - copy.CopyTo( this ); - return *this; -} - - -void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const -{ - if ( cfile ) fprintf( cfile, "" ); - if ( str ) (*str) += "?>"; -} - - -void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const -{ - TiXmlNode::CopyTo( target ); - - target->version = version; - target->encoding = encoding; - target->standalone = standalone; -} - - -bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlDeclaration::Clone() const -{ - TiXmlDeclaration* clone = new TiXmlDeclaration(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlUnknown::Print( FILE* cfile, int depth ) const -{ - for ( int i=0; i", value.c_str() ); -} - - -void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const -{ - TiXmlNode::CopyTo( target ); -} - - -bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlUnknown::Clone() const -{ - TiXmlUnknown* clone = new TiXmlUnknown(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -TiXmlAttributeSet::TiXmlAttributeSet() -{ - sentinel.next = &sentinel; - sentinel.prev = &sentinel; -} - - -TiXmlAttributeSet::~TiXmlAttributeSet() -{ - VALIDATE( sentinel.next == &sentinel ); - VALIDATE( sentinel.prev == &sentinel ); -} - - -void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) -{ - #ifdef TIXML_USE_STL - VALIDATE( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. - #else - VALIDATE( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. - #endif - - addMe->next = &sentinel; - addMe->prev = sentinel.prev; - - sentinel.prev->next = addMe; - sentinel.prev = addMe; -} - -void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) -{ - TiXmlAttribute* node; - - for( node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node == removeMe ) - { - node->prev->next = node->next; - node->next->prev = node->prev; - node->next = 0; - node->prev = 0; - return; - } - } - VALIDATE( 0 ); // we tried to remove a non-linked attribute. -} - - -#ifdef TIXML_USE_STL -TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const -{ - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node->name == name ) - return node; - } - return 0; -} - -TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name ) -{ - TiXmlAttribute* attrib = Find( _name ); - if ( !attrib ) { - attrib = new TiXmlAttribute(); - Add( attrib ); - attrib->SetName( _name ); - } - return attrib; -} -#endif - - -TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const -{ - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( strcmp( node->name.c_str(), name ) == 0 ) - return node; - } - return 0; -} - - -TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name ) -{ - TiXmlAttribute* attrib = Find( _name ); - if ( !attrib ) { - attrib = new TiXmlAttribute(); - Add( attrib ); - attrib->SetName( _name ); - } - return attrib; -} - - -#ifdef TIXML_USE_STL -std::istream& operator>> (std::istream & in, TiXmlNode & base) -{ - TIXML_STRING tag; - tag.reserve( 8 * 1000 ); - base.StreamIn( &in, &tag ); - - base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); - return in; -} -#endif - - -#ifdef TIXML_USE_STL -std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) -{ - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out << printer.Str(); - - return out; -} - - -std::string& operator<< (std::string& out, const TiXmlNode& base ) -{ - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out.append( printer.Str() ); - - return out; -} -#endif - - -TiXmlHandle TiXmlHandle::FirstChild() const -{ - if ( node ) - { - TiXmlNode* child = node->FirstChild(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const -{ - if ( node ) - { - TiXmlNode* child = node->FirstChild( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChildElement() const -{ - if ( node ) - { - TiXmlElement* child = node->FirstChildElement(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const -{ - if ( node ) - { - TiXmlElement* child = node->FirstChildElement( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::Child( int count ) const -{ - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild(); - for ( i=0; - child && iNextSibling(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const -{ - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild( value ); - for ( i=0; - child && iNextSibling( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::ChildElement( int count ) const -{ - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement(); - for ( i=0; - child && iNextSiblingElement(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const -{ - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement( value ); - for ( i=0; - child && iNextSiblingElement( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) -{ - return true; -} - -bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) -{ - return true; -} - -bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) -{ - DoIndent(); - buffer += "<"; - buffer += element.Value(); - - for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) - { - buffer += " "; - attrib->Print( 0, 0, &buffer ); - } - - if ( !element.FirstChild() ) - { - buffer += " />"; - DoLineBreak(); - } - else - { - buffer += ">"; - if ( element.FirstChild()->ToText() - && element.LastChild() == element.FirstChild() - && element.FirstChild()->ToText()->CDATA() == false ) - { - simpleTextPrint = true; - // no DoLineBreak()! - } - else - { - DoLineBreak(); - } - } - ++depth; - return true; -} - - -bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) -{ - --depth; - if ( !element.FirstChild() ) - { - // nothing. - } - else - { - if ( simpleTextPrint ) - { - simpleTextPrint = false; - } - else - { - DoIndent(); - } - buffer += ""; - DoLineBreak(); - } - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlText& text ) -{ - if ( text.CDATA() ) - { - DoIndent(); - buffer += ""; - DoLineBreak(); - } - else if ( simpleTextPrint ) - { - TIXML_STRING str; - TiXmlBase::EncodeString( text.ValueTStr(), &str ); - buffer += str; - } - else - { - DoIndent(); - TIXML_STRING str; - TiXmlBase::EncodeString( text.ValueTStr(), &str ); - buffer += str; - DoLineBreak(); - } - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) -{ - DoIndent(); - declaration.Print( 0, 0, &buffer ); - DoLineBreak(); - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlComment& comment ) -{ - DoIndent(); - buffer += ""; - DoLineBreak(); - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) -{ - DoIndent(); - buffer += "<"; - buffer += unknown.Value(); - buffer += ">"; - DoLineBreak(); - return true; -} - diff --git a/src/framework/xml/tinyxml.h b/src/framework/xml/tinyxml.h deleted file mode 100644 index 421ee3b..0000000 --- a/src/framework/xml/tinyxml.h +++ /dev/null @@ -1,1721 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - - -#ifndef TINYXML_INCLUDED -#define TINYXML_INCLUDED - -#define TIXML_USE_STL // use STL strings instead - -#ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4530 ) -#pragma warning( disable : 4786 ) -#endif - -#include -#include -#include -#include - -#include -#include -#include - -// Help out windows: -#if defined( _DEBUG ) && !defined( DEBUG ) -#define DEBUG -#endif - -#ifdef TIXML_USE_STL - #include - #include - #include - #define TIXML_STRING std::string -#else - #include "tinystr.h" - #define TIXML_STRING TiXmlString -#endif - -// Deprecated library function hell. Compilers want to use the -// new safe versions. This probably doesn't fully address the problem, -// but it gets closer. There are too many compilers for me to fully -// test. If you get compilation troubles, undefine TIXML_SAFE -#define TIXML_SAFE - -#ifdef TIXML_SAFE - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - // Microsoft visual studio, version 2005 and higher. - #define TIXML_SNPRINTF _snprintf_s - #define TIXML_SSCANF sscanf_s - #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - //#pragma message( "Using _sn* functions." ) - #define TIXML_SNPRINTF _snprintf - #define TIXML_SSCANF sscanf - #elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - //#warning( "Using sn* functions." ) - #define TIXML_SNPRINTF snprintf - #define TIXML_SSCANF sscanf - #else - #define TIXML_SNPRINTF snprintf - #define TIXML_SSCANF sscanf - #endif -#endif - -class TiXmlDocument; -class TiXmlElement; -class TiXmlComment; -class TiXmlUnknown; -class TiXmlAttribute; -class TiXmlText; -class TiXmlDeclaration; -class TiXmlParsingData; - -const int TIXML_MAJOR_VERSION = 2; -const int TIXML_MINOR_VERSION = 6; -const int TIXML_PATCH_VERSION = 2; - -/* Internal structure for tracking location of items - in the XML file. -*/ -struct TiXmlCursor -{ - TiXmlCursor() { Clear(); } - void Clear() { row = col = -1; } - - int row; // 0 based. - int col; // 0 based. -}; - - -/** - Implements the interface to the "Visitor pattern" (see the Accept() method.) - If you call the Accept() method, it requires being passed a TiXmlVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves - are simply called with Visit(). - - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, no children of this node or its sibilings will be Visited. - - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. - - Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. - - You should never change the document from a callback. - - @sa TiXmlNode::Accept() -*/ -class TiXmlVisitor -{ -public: - virtual ~TiXmlVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } - /// Visit a document. - virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } - - /// Visit an element. - virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } - /// Visit an element. - virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } - - /// Visit a declaration - virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } - /// Visit a text node - virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } - /// Visit a comment node - virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } - /// Visit an unknown node - virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } -}; - -// Only used by Attribute::Query functions -enum -{ - TIXML_SUCCESS, - TIXML_NO_ATTRIBUTE, - TIXML_WRONG_TYPE -}; - - -// Used by the parsing routines. -enum TiXmlEncoding -{ - TIXML_ENCODING_UNKNOWN, - TIXML_ENCODING_UTF8, - TIXML_ENCODING_LEGACY -}; -static const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; -/** TiXmlBase is a base class for every class in TinyXml. - It does little except to establish that TinyXml classes - can be printed and provide some utility functions. - - In XML, the document and elements can contain - other elements and other types of nodes. - - @verbatim - A Document can contain: Element (container or leaf) - Comment (leaf) - Unknown (leaf) - Declaration( leaf ) - - An Element can contain: Element (container or leaf) - Text (leaf) - Attributes (not on tree) - Comment (leaf) - Unknown (leaf) - - A Decleration contains: Attributes (not on tree) - @endverbatim -*/ -class TiXmlBase -{ - friend class TiXmlNode; - friend class TiXmlElement; - friend class TiXmlDocument; - -public: - TiXmlBase( const TiXmlBase& ) = delete; - void operator=( const TiXmlBase& base ) = delete; - - TiXmlBase() : userData(0) {} - virtual ~TiXmlBase() {} - - /** All TinyXml classes can print themselves to a filestream - or the string class (TiXmlString in non-STL mode, std::string - in STL mode.) Either or both cfile and str can be null. - - This is a formatted print, and will insert - tabs and newlines. - - (For an unformatted stream, use the << operator.) - */ - virtual void Print( FILE* cfile, int depth ) const = 0; - - /** The world does not agree on whether white space should be kept or - not. In order to make everyone happy, these global, static functions - are provided to set whether or not TinyXml will condense all white space - into a single space or not. The default is to condense. Note changing this - value is not thread safe. - */ - static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } - - /// Return the current white space setting. - static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } - - /** Return the position, in the original source file, of this node or attribute. - The row and column are 1-based. (That is the first row and first column is - 1,1). If the returns values are 0 or less, then the parser does not have - a row and column value. - - Generally, the row and column value will be set when the TiXmlDocument::Load(), - TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set - when the DOM was created from operator>>. - - The values reflect the initial load. Once the DOM is modified programmatically - (by adding or changing nodes and attributes) the new values will NOT update to - reflect changes in the document. - - There is a minor performance cost to computing the row and column. Computation - can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. - - @sa TiXmlDocument::SetTabSize() - */ - int Row() const { return location.row + 1; } - int Column() const { return location.col + 1; } ///< See Row() - - void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. - void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. - const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. - - // Table that returs, for a given lead byte, the total number of bytes - // in the UTF-8 sequence. - static const int utf8ByteTable[256]; - - virtual const char* Parse( const char* p, - TiXmlParsingData* data, - TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; - - /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, - or they will be transformed into entities! - */ - static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); - - enum - { - TIXML_NO_ERROR = 0, - TIXML_ERROR, - TIXML_ERROR_OPENING_FILE, - TIXML_ERROR_PARSING_ELEMENT, - TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, - TIXML_ERROR_READING_ELEMENT_VALUE, - TIXML_ERROR_READING_ATTRIBUTES, - TIXML_ERROR_PARSING_EMPTY, - TIXML_ERROR_READING_END_TAG, - TIXML_ERROR_PARSING_UNKNOWN, - TIXML_ERROR_PARSING_COMMENT, - TIXML_ERROR_PARSING_DECLARATION, - TIXML_ERROR_DOCUMENT_EMPTY, - TIXML_ERROR_EMBEDDED_NULL, - TIXML_ERROR_PARSING_CDATA, - TIXML_ERROR_DOCUMENT_TOP_ONLY, - - TIXML_ERROR_STRING_COUNT - }; - -protected: - - static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); - - inline static bool IsWhiteSpace( char c ) - { - return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); - } - inline static bool IsWhiteSpace( int c ) - { - if ( c < 256 ) - return IsWhiteSpace( (char) c ); - return false; // Again, only truly correct for English/Latin...but usually works. - } - - #ifdef TIXML_USE_STL - static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); - static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); - #endif - - /* Reads an XML name into the string provided. Returns - a pointer just past the last character of the name, - or 0 if the function has an error. - */ - static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); - - /* Reads text. Returns a pointer past the given end tag. - Wickedly complex options, but it keeps the (sensitive) code in one place. - */ - static const char* ReadText( const char* in, // where to start - TIXML_STRING* text, // the string read - bool ignoreWhiteSpace, // whether to keep the white space - const char* endTag, // what ends this text - bool ignoreCase, // whether to ignore case in the end tag - TiXmlEncoding encoding ); // the current encoding - - // If an entity has been found, transform it into a character. - static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); - - // Get a character, while interpreting entities. - // The length can be from 0 to 4 bytes. - inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) - { - VALIDATE( p ); - if ( encoding == TIXML_ENCODING_UTF8 ) - { - *length = utf8ByteTable[ *((const unsigned char*)p) ]; - VALIDATE( *length >= 0 && *length < 5 ); - } - else - { - *length = 1; - } - - if ( *length == 1 ) - { - if ( *p == '&' ) - return GetEntity( p, _value, length, encoding ); - *_value = *p; - return p+1; - } - else if ( *length ) - { - //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), - // and the null terminator isn't needed - for( int i=0; p[i] && i<*length; ++i ) { - _value[i] = p[i]; - } - return p + (*length); - } - else - { - // Not valid text. - return 0; - } - } - - // Return true if the next characters in the stream are any of the endTag sequences. - // Ignore case only works for english, and should only be relied on when comparing - // to English words: StringEqual( p, "version", true ) is fine. - static bool StringEqual( const char* p, - const char* endTag, - bool ignoreCase, - TiXmlEncoding encoding ); - - static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; - - TiXmlCursor location; - - /// Field containing a generic user pointer - void* userData; - - // None of these methods are reliable for any language except English. - // Good for approximation, not great for accuracy. - static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); - static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); - inline static int ToLower( int v, TiXmlEncoding encoding ) - { - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( v < 128 ) return tolower( v ); - return v; - } - else - { - return tolower( v ); - } - } - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); - -private: - struct Entity - { - const char* str; - unsigned int strLength; - char chr; - }; - enum - { - NUM_ENTITY = 5, - MAX_ENTITY_LENGTH = 6 - - }; - static Entity entity[ NUM_ENTITY ]; - static bool condenseWhiteSpace; -}; - - -/** The parent class for everything in the Document Object Model. - (Except for attributes). - Nodes have siblings, a parent, and children. A node can be - in a document, or stand on its own. The type of a TiXmlNode - can be queried, and it can be cast to its more defined type. -*/ -class TiXmlNode : public TiXmlBase -{ - friend class TiXmlDocument; - friend class TiXmlElement; - -public: - TiXmlNode( const TiXmlNode& ) = delete; - void operator=( const TiXmlNode& base ) = delete; - - #ifdef TIXML_USE_STL - - /** An input stream operator, for every class. Tolerant of newlines and - formatting, but doesn't expect them. - */ - friend std::istream& operator >> (std::istream& in, TiXmlNode& base); - - /** An output stream operator, for every class. Note that this outputs - without any newlines or formatting, as opposed to Print(), which - includes tabs and new lines. - - The operator<< and operator>> are not completely symmetric. Writing - a node to a stream is very well defined. You'll get a nice stream - of output, without any extra whitespace or newlines. - - But reading is not as well defined. (As it always is.) If you create - a TiXmlElement (for example) and read that from an input stream, - the text needs to define an element or junk will result. This is - true of all input streams, but it's worth keeping in mind. - - A TiXmlDocument will read nodes until it reads a root element, and - all the children of that root element. - */ - friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); - - /// Appends the XML node or attribute to a std::string. - friend std::string& operator<< (std::string& out, const TiXmlNode& base ); - - #endif - - /** The types of XML nodes supported by TinyXml. (All the - unsupported types are picked up by UNKNOWN.) - */ - enum NodeType - { - TINYXML_DOCUMENT, - TINYXML_ELEMENT, - TINYXML_COMMENT, - TINYXML_UNKNOWN, - TINYXML_TEXT, - TINYXML_DECLARATION, - TINYXML_TYPECOUNT - }; - - virtual ~TiXmlNode(); - - /** The meaning of 'value' changes for the specific type of - TiXmlNode. - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - - The subclasses will wrap this function. - */ - const char *Value() const { return value.c_str (); } - - #ifdef TIXML_USE_STL - /** Return Value() as a std::string. If you only use STL, - this is more efficient than calling Value(). - Only available in STL mode. - */ - const std::string& ValueStr() const { return value; } - #endif - - const TIXML_STRING& ValueTStr() const { return value; } - - /** Changes the value of the node. Defined as: - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - */ - void SetValue(const char * _value) { value = _value;} - - #ifdef TIXML_USE_STL - /// STL std::string form. - void SetValue( const std::string& _value ) { value = _value; } - #endif - - /// Delete all the children of this node. Does not affect 'this'. - void Clear(); - - /// One step up the DOM. - TiXmlNode* Parent() { return parent; } - const TiXmlNode* Parent() const { return parent; } - - const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. - TiXmlNode* FirstChild() { return firstChild; } - const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. - /// The first child of this node with the matching 'value'. Will be null if none found. - TiXmlNode* FirstChild( const char * _value ) { - // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) - // call the method, cast the return back to non-const. - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); - } - const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. - TiXmlNode* LastChild() { return lastChild; } - - const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. - TiXmlNode* LastChild( const char * _value ) { - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. - const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. - #endif - - /** An alternate way to walk the children of a node. - One way to iterate over nodes is: - @verbatim - for( child = parent->FirstChild(); child; child = child->NextSibling() ) - @endverbatim - - IterateChildren does the same thing with the syntax: - @verbatim - child = 0; - while( child = parent->IterateChildren( child ) ) - @endverbatim - - IterateChildren takes the previous child as input and finds - the next one. If the previous child is null, it returns the - first. IterateChildren will return null when done. - */ - const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); - } - - /// This flavor of IterateChildren searches for children with a particular 'value' - const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. - TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. - #endif - - /** Add a new node related to this. Adds a child past the LastChild. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); - - - /** Add a new node related to this. Adds a child past the LastChild. - - NOTE: the node to be added is passed by pointer, and will be - henceforth owned (and deleted) by tinyXml. This method is efficient - and avoids an extra copy, but should be used with care as it - uses a different memory model than the other insert functions. - - @sa InsertEndChild - */ - TiXmlNode* LinkEndChild( TiXmlNode* addThis ); - - /** Add a new node related to this. Adds a child before the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); - - /** Add a new node related to this. Adds a child after the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); - - /** Replace a child of this node. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); - - /// Delete a child of this node. - bool RemoveChild( TiXmlNode* removeThis ); - - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling() const { return prev; } - TiXmlNode* PreviousSibling() { return prev; } - - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling( const char * ) const; - TiXmlNode* PreviousSibling( const char *_prev ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. - const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. - #endif - - /// Navigate to a sibling node. - const TiXmlNode* NextSibling() const { return next; } - TiXmlNode* NextSibling() { return next; } - - /// Navigate to a sibling node with the given 'value'. - const TiXmlNode* NextSibling( const char * ) const; - TiXmlNode* NextSibling( const char* _next ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement() const; - TiXmlElement* NextSiblingElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement( const char * ) const; - TiXmlElement* NextSiblingElement( const char *_next ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. - TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. - #endif - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement() const; - TiXmlElement* FirstChildElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); - } - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement( const char * _value ) const; - TiXmlElement* FirstChildElement( const char * _value ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. - TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. - #endif - - /** Query the type (as an enumerated value, above) of this node. - The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT, - TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION. - */ - int Type() const { return type; } - - /** Return a pointer to the Document this node lives in. - Returns null if not in a document. - */ - const TiXmlDocument* GetDocument() const; - TiXmlDocument* GetDocument() { - return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); - } - - /// Returns true if this node has no children. - bool NoChildren() const { return !firstChild; } - - virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - /** Create an exact duplicate of this node and return it. The memory must be deleted - by the caller. - */ - virtual TiXmlNode* Clone() const = 0; - - /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the TiXmlVisitor interface. - - This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - TiXmlPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( TiXmlVisitor* visitor ) const = 0; - -protected: - TiXmlNode( NodeType _type ); - - // Copy to the allocated object. Shared functionality between Clone, Copy constructor, - // and the assignment operator. - void CopyTo( TiXmlNode* target ) const; - - #ifdef TIXML_USE_STL - // The real work of the input operator. - virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; - #endif - - // Figure out what is at *p, and parse it. Returns null if it is not an xml node. - TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); - - TiXmlNode* parent; - NodeType type; - - TiXmlNode* firstChild; - TiXmlNode* lastChild; - - TIXML_STRING value; - - TiXmlNode* prev; - TiXmlNode* next; -}; - - -/** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. - - @note The attributes are not TiXmlNodes, since they are not - part of the tinyXML document object model. There are other - suggested ways to look at this problem. -*/ -class TiXmlAttribute : public TiXmlBase -{ - friend class TiXmlAttributeSet; - -public: - /// Construct an empty attribute. - TiXmlAttribute() : TiXmlBase() - { - document = 0; - prev = next = 0; - } - - #ifdef TIXML_USE_STL - /// std::string constructor. - TiXmlAttribute( const std::string& _name, const std::string& _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - #endif - - /// Construct an attribute with a name and value. - TiXmlAttribute( const char * _name, const char * _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - - const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. - const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. - #ifdef TIXML_USE_STL - const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. - #endif - int IntValue() const; ///< Return the value of this attribute, converted to an integer. - double DoubleValue() const; ///< Return the value of this attribute, converted to a double. - - // Get the tinyxml string representation - const TIXML_STRING& NameTStr() const { return name; } - - /** QueryIntValue examines the value string. It is an alternative to the - IntValue() method with richer error checking. - If the value is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. - - A specialized but useful call. Note that for success it returns 0, - which is the opposite of almost all other TinyXml calls. - */ - int QueryIntValue( int* _value ) const; - /// QueryDoubleValue examines the value string. See QueryIntValue(). - int QueryDoubleValue( double* _value ) const; - - void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. - void SetValue( const char* _value ) { value = _value; } ///< Set the value. - - void SetIntValue( int _value ); ///< Set the value from an integer. - void SetDoubleValue( double _value ); ///< Set the value from a double. - - #ifdef TIXML_USE_STL - /// STL std::string form. - void SetName( const std::string& _name ) { name = _name; } - /// STL std::string form. - void SetValue( const std::string& _value ) { value = _value; } - #endif - - /// Get the next sibling attribute in the DOM. Returns null at end. - const TiXmlAttribute* Next() const; - TiXmlAttribute* Next() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); - } - - /// Get the previous sibling attribute in the DOM. Returns null at beginning. - const TiXmlAttribute* Previous() const; - TiXmlAttribute* Previous() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); - } - - bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } - bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } - bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } - - /* Attribute parsing starts: first letter of the name - returns: the next char after the value end quote - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - // Prints this Attribute to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - - // [internal use] - // Set the document pointer so the attribute can report errors. - void SetDocument( TiXmlDocument* doc ) { document = doc; } - -private: - TiXmlAttribute( const TiXmlAttribute& ); // not implemented. - void operator=( const TiXmlAttribute& base ); // not allowed. - - TiXmlDocument* document; // A pointer back to a document, for error reporting. - TIXML_STRING name; - TIXML_STRING value; - TiXmlAttribute* prev; - TiXmlAttribute* next; -}; - - -/* A class used to manage a group of attributes. - It is only used internally, both by the ELEMENT and the DECLARATION. - - The set can be changed transparent to the Element and Declaration - classes that use it, but NOT transparent to the Attribute - which has to implement a next() and previous() method. Which makes - it a bit problematic and prevents the use of STL. - - This version is implemented with circular lists because: - - I like circular lists - - it demonstrates some independence from the (typical) doubly linked list. -*/ -class TiXmlAttributeSet -{ -public: - TiXmlAttributeSet(); - ~TiXmlAttributeSet(); - - void Add( TiXmlAttribute* attribute ); - void Remove( TiXmlAttribute* attribute ); - - const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - - TiXmlAttribute* Find( const char* _name ) const; - TiXmlAttribute* FindOrCreate( const char* _name ); - -# ifdef TIXML_USE_STL - TiXmlAttribute* Find( const std::string& _name ) const; - TiXmlAttribute* FindOrCreate( const std::string& _name ); -# endif - - -private: - //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), - //*ME: this class must be also use a hidden/disabled copy-constructor !!! - TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed - void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) - - TiXmlAttribute sentinel; -}; - - -/** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. -*/ -class TiXmlElement : public TiXmlNode -{ -public: - TiXmlElement( const std::string& _value ); - TiXmlElement( const TiXmlElement& ); - TiXmlElement& operator=( const TiXmlElement& base ); - - virtual ~TiXmlElement(); - - template - inline T readType(const std::string& str) const - { - T ret; - int r = QueryValueAttribute(str, &ret); - if(r == TIXML_NO_ATTRIBUTE || r == TIXML_WRONG_TYPE) - return T(); - return ret; - } - - /** Template form of the attribute query which will try to read the - attribute into the specified type. Very easy, very powerful, but - be careful to make sure to call this with the correct type. - - NOTE: This method doesn't work correctly for 'string' types that contain spaces. - - @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE - */ - template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - - std::stringstream sstream( node->ValueStr() ); - sstream >> *outValue; - if ( !sstream.fail() ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; - } - - int QueryValueAttribute( const std::string& name, std::string* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - *outValue = node->ValueStr(); - return TIXML_SUCCESS; - } - - std::string Attribute( const std::string& name ) const; - std::string Attribute( const std::string& name, int* i ) const; - std::string Attribute( const std::string& name, double* d ) const; - - void SetAttribute( const std::string& name, const std::string& _value ); - void SetAttribute( const std::string& name, int _value) { SetAttribute(name, stdext::to_string(_value)); } - - void RemoveAttribute( const std::string& name ); - - const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. - TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } - const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. - TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the TiXmlText child - and accessing it directly. - - If the first child of 'this' is a TiXmlText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - This is text - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - This is text - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - This is text - @endverbatim - GetText() will return "This is ". - - WARNING: GetText() accesses a child node - don't become confused with the - similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are - safe type casts on the referenced node. - */ - const char* GetText() const; - - /// Creates a new Element and returns it - the returned element is a copy. - virtual TiXmlNode* Clone() const; - // Print the Element to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: next char past '<' - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - - void CopyTo( TiXmlElement* target ) const; - void ClearThis(); // like clear, but initializes 'this' object as well - - // Used to be public [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - /* [internal use] - Reads the "value" of the element -- another element, or text. - This should terminate with the current end tag. - */ - const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - -private: - TiXmlAttributeSet attributeSet; -}; - - -/** An XML comment. -*/ -class TiXmlComment : public TiXmlNode -{ -public: - /// Constructs an empty comment. - TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {} - /// Construct a comment from text. - TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) { - SetValue( _value ); - } - TiXmlComment( const TiXmlComment& ); - TiXmlComment& operator=( const TiXmlComment& base ); - - virtual ~TiXmlComment() {} - - /// Returns a copy of this Comment. - virtual TiXmlNode* Clone() const; - // Write this Comment to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: at the ! of the !-- - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - void CopyTo( TiXmlComment* target ) const; - - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif -// virtual void StreamOut( TIXML_OSTREAM * out ) const; - -private: - -}; - - -/** XML text. A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCDATA() and query it with CDATA(). -*/ -class TiXmlText : public TiXmlNode -{ - friend class TiXmlElement; -public: - /** Constructor for text element. By default, it is treated as - normal, encoded text. If you want it be output as a CDATA text - element, set the parameter _cdata to 'true' - */ - TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) - { - SetValue( initValue ); - cdata = false; - } - virtual ~TiXmlText() {} - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) - { - SetValue( initValue ); - cdata = false; - } - #endif - - TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); } - TiXmlText& operator=( const TiXmlText& base ) { base.CopyTo( this ); return *this; } - - // Write this text object to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /// Queries whether this represents text using a CDATA section. - bool CDATA() const { return cdata; } - /// Turns on or off a CDATA representation of text. - void SetCDATA( bool _cdata ) { cdata = _cdata; } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected : - /// [internal use] Creates a new Element and returns it. - virtual TiXmlNode* Clone() const; - void CopyTo( TiXmlText* target ) const; - - bool Blank() const; // returns true if all white space and new lines - // [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - bool cdata; // true if this should be input and output as a CDATA style text element -}; - - -/** In correct XML the declaration is the first entry in the file. - @verbatim - - @endverbatim - - TinyXml will happily read or write files without a declaration, - however. There are 3 possible attributes to the declaration: - version, encoding, and standalone. - - Note: In this version of the code, the attributes are - handled as special cases, not generic attributes, simply - because there can only be at most 3 and they are always the same. -*/ -class TiXmlDeclaration : public TiXmlNode -{ -public: - /// Construct an empty declaration. - TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {} - -#ifdef TIXML_USE_STL - /// Constructor. - TiXmlDeclaration( const std::string& _version, - const std::string& _encoding, - const std::string& _standalone ); -#endif - - /// Construct. - TiXmlDeclaration( const char* _version, - const char* _encoding, - const char* _standalone ); - - TiXmlDeclaration( const TiXmlDeclaration& copy ); - TiXmlDeclaration& operator=( const TiXmlDeclaration& copy ); - - virtual ~TiXmlDeclaration() {} - - /// Version. Will return an empty string if none was found. - const char *Version() const { return version.c_str (); } - /// Encoding. Will return an empty string if none was found. - const char *Encoding() const { return encoding.c_str (); } - /// Is this a standalone document? - const char *Standalone() const { return standalone.c_str (); } - - /// Creates a copy of this Declaration and returns it. - virtual TiXmlNode* Clone() const; - // Print this declaration to a FILE stream. - virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - void CopyTo( TiXmlDeclaration* target ) const; - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - - TIXML_STRING version; - TIXML_STRING encoding; - TIXML_STRING standalone; -}; - - -/** Any tag that tinyXml doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. - - DTD tags get thrown into TiXmlUnknowns. -*/ -class TiXmlUnknown : public TiXmlNode -{ -public: - TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {} - virtual ~TiXmlUnknown() {} - - TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); } - TiXmlUnknown& operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); return *this; } - - /// Creates a copy of this Unknown and returns it. - virtual TiXmlNode* Clone() const; - // Print this Unknown to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected: - void CopyTo( TiXmlUnknown* target ) const; - - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - -}; - - -/** Always the top level node. A document binds together all the - XML pieces. It can be saved, loaded, and printed to the screen. - The 'value' of a document node is the xml file name. -*/ -class TiXmlDocument : public TiXmlNode -{ -public: - /// Create an empty document, that has no name. - TiXmlDocument(); - /// Create a document with a name. The name of the document is also the filename of the xml. - TiXmlDocument( const char * documentName ); - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlDocument( const std::string& documentName ); - #endif - - TiXmlDocument( const TiXmlDocument& copy ); - TiXmlDocument& operator=( const TiXmlDocument& copy ); - - virtual ~TiXmlDocument() {} - - /** Load a file using the current document value. - Returns true if successful. Will delete any existing - document data before loading. - */ - bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the current document value. Returns true if successful. - bool SaveFile() const; - /// Load a file using the given filename. Returns true if successful. - bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given filename. Returns true if successful. - bool SaveFile( const char * filename ) const; - /** Load a file using the given FILE*. Returns true if successful. Note that this method - doesn't stream - the entire object pointed at by the FILE* - will be interpreted as an XML file. TinyXML doesn't stream in XML from the current - file location. Streaming may be added in the future. - */ - bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given FILE*. Returns true if successful. - bool SaveFile( FILE* ) const; - - #ifdef TIXML_USE_STL - bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. - { - return LoadFile( filename.c_str(), encoding ); - } - bool SaveFile( const std::string& filename ) const ///< STL std::string version. - { - return SaveFile( filename.c_str() ); - } - #endif - - /** Parse the given null terminated block of xml data. Passing in an encoding to this - method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml - to use that encoding, regardless of what TinyXml might otherwise try to detect. - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - - /** Get the root element -- the only top level element -- of the document. - In well formed XML, there should only be one. TinyXml is tolerant of - multiple elements at the document level. - */ - const TiXmlElement* RootElement() const { return FirstChildElement(); } - TiXmlElement* RootElement() { return FirstChildElement(); } - - /** If an error occurs, Error will be set to true. Also, - - The ErrorId() will contain the integer identifier of the error (not generally useful) - - The ErrorDesc() method will return the name of the error. (very useful) - - The ErrorRow() and ErrorCol() will return the location of the error (if known) - */ - bool Error() const { return error; } - - /// Contains a textual (english) description of the error if one occurs. - const char * ErrorDesc() const { return errorDesc.c_str (); } - - /** Generally, you probably want the error string ( ErrorDesc() ). But if you - prefer the ErrorId, this function will fetch it. - */ - int ErrorId() const { return errorId; } - - /** Returns the location (if known) of the error. The first column is column 1, - and the first row is row 1. A value of 0 means the row and column wasn't applicable - (memory errors, for example, have no row/column) or the parser lost the error. (An - error in the error reporting, in that case.) - - @sa SetTabSize, Row, Column - */ - int ErrorRow() const { return errorLocation.row+1; } - int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() - - /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) - to report the correct values for row and column. It does not change the output - or input in any way. - - By calling this method, with a tab size - greater than 0, the row and column of each node and attribute is stored - when the file is loaded. Very useful for tracking the DOM back in to - the source file. - - The tab size is required for calculating the location of nodes. If not - set, the default of 4 is used. The tabsize is set per document. Setting - the tabsize to 0 disables row/column tracking. - - Note that row and column tracking is not supported when using operator>>. - - The tab size needs to be enabled before the parse or load. Correct usage: - @verbatim - TiXmlDocument doc; - doc.SetTabSize( 8 ); - doc.Load( "myfile.xml" ); - @endverbatim - - @sa Row, Column - */ - void SetTabSize( int _tabsize ) { tabsize = _tabsize; } - - int TabSize() const { return tabsize; } - - /** If you have handled the error, it can be reset with this call. The error - state is automatically cleared if you Parse a new XML block. - */ - void ClearError() { error = false; - errorId = 0; - errorDesc = ""; - errorLocation.row = errorLocation.col = 0; - //errorLocation.last = 0; - } - - /** Write the document to standard out using formatted printing ("pretty print"). */ - void Print() const { Print( stdout, 0 ); } - - /* Write the document to a string using formatted printing ("pretty print"). This - will allocate a character array (new char[]) and return it as a pointer. The - calling code pust call delete[] on the return char* to avoid a memory leak. - */ - //char* PrintToMemory() const; - - /// Print this Document to a FILE stream. - virtual void Print( FILE* cfile, int depth = 0 ) const; - // [internal use] - void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - - virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected : - // [internal use] - virtual TiXmlNode* Clone() const; - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - void CopyTo( TiXmlDocument* target ) const; - - bool error; - int errorId; - TIXML_STRING errorDesc; - int tabsize; - TiXmlCursor errorLocation; - bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. -}; - - -/** - A TiXmlHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - - - - - - - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - TiXmlElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - TiXmlElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - TiXmlElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - TiXmlElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity - of such code. A TiXmlHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - TiXmlHandle docHandle( &document ); - TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - TiXmlHandle handleCopy = handle; - @endverbatim - - What they should not be used for is iteration: - - @verbatim - int i=0; - while ( true ) - { - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); - if ( !child ) - break; - // do something - ++i; - } - @endverbatim - - It seems reasonable, but it is in fact two embedded while loops. The Child method is - a linear walk to find the element, so this code would iterate much more than it needs - to. Instead, prefer: - - @verbatim - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); - - for( child; child; child=child->NextSiblingElement() ) - { - // do something - } - @endverbatim -*/ -class TiXmlHandle -{ -public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } - /// Copy constructor - TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } - TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; } - - /// Return a handle to the first child node. - TiXmlHandle FirstChild() const; - /// Return a handle to the first child node with the given name. - TiXmlHandle FirstChild( const char * value ) const; - /// Return a handle to the first child element. - TiXmlHandle FirstChildElement() const; - /// Return a handle to the first child element with the given name. - TiXmlHandle FirstChildElement( const char * value ) const; - - /** Return a handle to the "index" child with the given name. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( const char* value, int index ) const; - /** Return a handle to the "index" child. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( int index ) const; - /** Return a handle to the "index" child element with the given name. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( const char* value, int index ) const; - /** Return a handle to the "index" child element. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( int index ) const; - - #ifdef TIXML_USE_STL - TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } - TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } - - TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } - TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } - #endif - - /** Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* ToNode() const { return node; } - /** Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } - /** Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } - /** Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } - - /** @deprecated use ToNode. - Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* Node() const { return ToNode(); } - /** @deprecated use ToElement. - Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* Element() const { return ToElement(); } - /** @deprecated use ToText() - Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* Text() const { return ToText(); } - /** @deprecated use ToUnknown() - Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* Unknown() const { return ToUnknown(); } - -private: - TiXmlNode* node; -}; - - -/** Print to memory functionality. The TiXmlPrinter is useful when you need to: - - -# Print to memory (especially in non-STL mode) - -# Control formatting (line endings, etc.) - - When constructed, the TiXmlPrinter is in its default "pretty printing" mode. - Before calling Accept() you can call methods to control the printing - of the XML document. After TiXmlNode::Accept() is called, the printed document can - be accessed via the CStr(), Str(), and Size() methods. - - TiXmlPrinter uses the Visitor API. - @verbatim - TiXmlPrinter printer; - printer.SetIndent( "\t" ); - - doc.Accept( &printer ); - fprintf( stdout, "%s", printer.CStr() ); - @endverbatim -*/ -class TiXmlPrinter : public TiXmlVisitor -{ -public: - TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), - buffer(), indent( " " ), lineBreak( "\n" ) {} - - virtual bool VisitEnter( const TiXmlDocument& doc ); - virtual bool VisitExit( const TiXmlDocument& doc ); - - virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); - virtual bool VisitExit( const TiXmlElement& element ); - - virtual bool Visit( const TiXmlDeclaration& declaration ); - virtual bool Visit( const TiXmlText& text ); - virtual bool Visit( const TiXmlComment& comment ); - virtual bool Visit( const TiXmlUnknown& unknown ); - - /** Set the indent characters for printing. By default 4 spaces - but tab (\t) is also useful, or null/empty string for no indentation. - */ - void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } - /// Query the indention string. - const char* Indent() { return indent.c_str(); } - /** Set the line breaking string. By default set to newline (\n). - Some operating systems prefer other characters, or can be - set to the null/empty string for no indenation. - */ - void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } - /// Query the current line breaking string. - const char* LineBreak() { return lineBreak.c_str(); } - - /** Switch over to "stream printing" which is the most dense formatting without - linebreaks. Common when the XML is needed for network transmission. - */ - void SetStreamPrinting() { indent = ""; - lineBreak = ""; - } - /// Return the result. - const char* CStr() { return buffer.c_str(); } - /// Return the length of the result string. - size_t Size() { return buffer.size(); } - - #ifdef TIXML_USE_STL - /// Return the result. - const std::string& Str() { return buffer; } - #endif - -private: - void DoIndent() { - for( int i=0; i -#include "tinyxml.h" - -// The goal of the seperate error file is to make the first -// step towards localization. tinyxml (currently) only supports -// english error messages, but the could now be translated. -// -// It also cleans up the code a bit. -// - -const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] = -{ - "No error", - "Error", - "Failed to open file", - "Error parsing Element.", - "Failed to read Element name", - "Error reading Element value.", - "Error reading Attributes.", - "Error: empty tag.", - "Error reading end tag.", - "Error parsing Unknown.", - "Error parsing Comment.", - "Error parsing Declaration.", - "Error document empty.", - "Error null (0) or unexpected EOF found in input stream.", - "Error parsing CDATA.", - "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", -}; diff --git a/src/framework/xml/tinyxmlparser.cpp b/src/framework/xml/tinyxmlparser.cpp deleted file mode 100644 index 9a972b0..0000000 --- a/src/framework/xml/tinyxmlparser.cpp +++ /dev/null @@ -1,1644 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include - -#include -#include - -#include "tinyxml.h" - -//#define DEBUG_PARSER -#if defined( DEBUG_PARSER ) -# if defined( DEBUG ) && defined( _MSC_VER ) -# include -# define TIXML_LOG OutputDebugString -# else -# define TIXML_LOG printf -# endif -#endif - -// Note tha "PutString" hardcodes the same list. This -// is less flexible than it appears. Changing the entries -// or order will break putstring. -TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] = -{ - { "&", 5, '&' }, - { "<", 4, '<' }, - { ">", 4, '>' }, - { """, 6, '\"' }, - { "'", 6, '\'' } -}; - -// Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html -// Including the basic of this table, which determines the #bytes in the -// sequence from the lead byte. 1 placed for invalid sequences -- -// although the result will be junk, pass it through as much as possible. -// Beware of the non-characters in UTF-8: -// ef bb bf (Microsoft "lead bytes") -// ef bf be -// ef bf bf - -const unsigned char TIXML_UTF_LEAD_0 = 0xefU; -const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; -const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - -const int TiXmlBase::utf8ByteTable[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte - 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -}; - - -void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -{ - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) - *length = 1; - else if ( input < 0x800 ) - *length = 2; - else if ( input < 0x10000 ) - *length = 3; - else if ( input < 0x200000 ) - *length = 4; - else - { *length = 0; return; } // This code won't covert this correctly anyway. - - output += *length; - - // Scary scary fall throughs. - switch (*length) - { - /* FALLTHROUGH */ - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - /* FALLTHROUGH */ - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - /* FALLTHROUGH */ - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - /* FALLTHROUGH */ - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - } -} - - -/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) -{ - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalpha( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalpha( anyByte ); -// } -} - - -/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) -{ - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalnum( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalnum( anyByte ); -// } -} - - -class TiXmlParsingData -{ - friend class TiXmlDocument; - public: - void Stamp( const char* now, TiXmlEncoding encoding ); - - const TiXmlCursor& Cursor() const { return cursor; } - - private: - // Only used by the document! - TiXmlParsingData( const char* start, int _tabsize, int row, int col ) - { - VALIDATE( start ); - stamp = start; - tabsize = _tabsize; - cursor.row = row; - cursor.col = col; - } - - TiXmlCursor cursor; - const char* stamp; - int tabsize; -}; - - -void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) -{ - VALIDATE( now ); - - // Do nothing if the tabsize is 0. - if ( tabsize < 1 ) - { - return; - } - - // Get the current row, column. - int row = cursor.row; - int col = cursor.col; - const char* p = stamp; - VALIDATE( p ); - - while ( p < now ) - { - // Treat p as unsigned, so we have a happy compiler. - const unsigned char* pU = (const unsigned char*)p; - - // Code contributed by Fletcher Dunn: (modified by lee) - switch (*pU) { - case 0: - // We *should* never get here, but in case we do, don't - // advance past the terminating null character, ever - return; - - case '\r': - // bump down to the next line - ++row; - col = 0; - // Eat the character - ++p; - - // Check for \r\n sequence, and treat this as a single character - if (*p == '\n') { - ++p; - } - break; - - case '\n': - // bump down to the next line - ++row; - col = 0; - - // Eat the character - ++p; - - // Check for \n\r sequence, and treat this as a single - // character. (Yes, this bizarre thing does occur still - // on some arcane platforms...) - if (*p == '\r') { - ++p; - } - break; - - case '\t': - // Eat the character - ++p; - - // Skip to next tab stop - col = (col / tabsize + 1) * tabsize; - break; - - case TIXML_UTF_LEAD_0: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( *(p+1) && *(p+2) ) - { - // In these cases, don't advance the column. These are - // 0-width spaces. - if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) - p += 3; - else - { p +=3; ++col; } // A normal character. - } - } - else - { - ++p; - ++col; - } - break; - - default: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // Eat the 1 to 4 byte utf8 character. - int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; - if ( step == 0 ) - step = 1; // Error case from bad encoding, but handle gracefully. - p += step; - - // Just advance one column, of course. - ++col; - } - else - { - ++p; - ++col; - } - break; - } - } - cursor.row = row; - cursor.col = col; - VALIDATE( cursor.row >= -1 ); - VALIDATE( cursor.col >= -1 ); - stamp = p; - VALIDATE( stamp ); -} - - -const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) -{ - if ( !p || !*p ) - { - return 0; - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - while ( *p ) - { - const unsigned char* pU = (const unsigned char*)p; - - // Skip the stupid Microsoft UTF-8 Byte order marks - if ( *(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==TIXML_UTF_LEAD_1 - && *(pU+2)==TIXML_UTF_LEAD_2 ) - { - p += 3; - continue; - } - else if(*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbeU ) - { - p += 3; - continue; - } - else if(*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbfU ) - { - p += 3; - continue; - } - - if ( IsWhiteSpace( *p ) ) // Still using old rules for white space. - ++p; - else - break; - } - } - else - { - while ( *p && IsWhiteSpace( *p ) ) - ++p; - } - - return p; -} - -#ifdef TIXML_USE_STL -/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) -{ - for( ;; ) - { - if ( !in->good() ) return false; - - int c = in->peek(); - // At this scope, we can't get to a document. So fail silently. - if ( !IsWhiteSpace( c ) || c <= 0 ) - return true; - - *tag += (char) in->get(); - } -} - -/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) -{ - //VALIDATE( character > 0 && character < 128 ); // else it won't work in utf-8 - while ( in->good() ) - { - int c = in->peek(); - if ( c == character ) - return true; - if ( c <= 0 ) // Silent failure: can't get document at this scope - return false; - - in->get(); - *tag += (char) c; - } - return false; -} -#endif - -// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The -// "assign" optimization removes over 10% of the execution time. -// -const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) -{ - // Oddly, not supported on some comilers, - //name->clear(); - // So use this: - *name = ""; - VALIDATE( p ); - - // Names start with letters or underscores. - // Of course, in unicode, tinyxml has no idea what a letter *is*. The - // algorithm is generous. - // - // After that, they can be letters, underscores, numbers, - // hyphens, or colons. (Colons are valid ony for namespaces, - // but tinyxml can't tell namespaces from names.) - if ( p && *p - && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) - { - const char* start = p; - while( p && *p - && ( IsAlphaNum( (unsigned char ) *p, encoding ) - || *p == '_' - || *p == '-' - || *p == '.' - || *p == ':' ) ) - { - //(*name) += *p; // expensive - ++p; - } - if ( p-start > 0 ) { - name->assign( start, p-start ); - } - return p; - } - return 0; -} - -const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) -{ - // Presume an entity, and pull it out. - TIXML_STRING ent; - int i; - *length = 0; - - if ( *(p+1) && *(p+1) == '#' && *(p+2) ) - { - unsigned long ucs = 0; - ptrdiff_t delta = 0; - unsigned mult = 1; - - if ( *(p+2) == 'x' ) - { - // Hexadecimal. - if ( !*(p+3) ) return 0; - - const char* q = p+3; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != 'x' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else if ( *q >= 'a' && *q <= 'f' ) - ucs += mult * (*q - 'a' + 10); - else if ( *q >= 'A' && *q <= 'F' ) - ucs += mult * (*q - 'A' + 10 ); - else - return 0; - mult *= 16; - --q; - } - } - else - { - // Decimal. - if ( !*(p+2) ) return 0; - - const char* q = p+2; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != '#' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else - return 0; - mult *= 10; - --q; - } - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - } - else - { - *value = (char)ucs; - *length = 1; - } - return p + delta + 1; - } - - // Now try to match it. - for( i=0; iappend( cArr, len ); - } - } - else - { - bool whitespace = false; - - // Remove leading white space: - p = SkipWhiteSpace( p, encoding ); - while ( p && *p - && !StringEqual( p, endTag, caseInsensitive, encoding ) ) - { - if ( *p == '\r' || *p == '\n' ) - { - whitespace = true; - ++p; - } - else if ( IsWhiteSpace( *p ) ) - { - whitespace = true; - ++p; - } - else - { - // If we've found whitespace, add it before the - // new character. Any whitespace just becomes a space. - if ( whitespace ) - { - (*text) += ' '; - whitespace = false; - } - int len; - char cArr[4] = { 0, 0, 0, 0 }; - p = GetChar( p, cArr, &len, encoding ); - if ( len == 1 ) - (*text) += cArr[0]; // more efficient - else - text->append( cArr, len ); - } - } - } - if ( p && *p ) - p += strlen( endTag ); - return ( p && *p ) ? p : 0; -} - -#ifdef TIXML_USE_STL - -void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - // The basic issue with a document is that we don't know what we're - // streaming. Read something presumed to be a tag (and hope), then - // identify it, and call the appropriate stream method on the tag. - // - // This "pre-streaming" will never read the closing ">" so the - // sub-tag can orient itself. - - if ( !StreamTo( in, '<', tag ) ) - { - SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - while ( in->good() ) - { - int tagIndex = (int) tag->length(); - while ( in->good() && in->peek() != '>' ) - { - int c = in->get(); - if ( c <= 0 ) - { - SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - break; - } - (*tag) += (char) c; - } - - if ( in->good() ) - { - // We now have something we presume to be a node of - // some sort. Identify it, and call the node to - // continue streaming. - TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); - - if ( node ) - { - node->StreamIn( in, tag ); - bool isElement = node->ToElement() != 0; - delete node; - node = 0; - - // If this is the root element, we're done. Parsing will be - // done by the >> operator. - if ( isElement ) - { - return; - } - } - else - { - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - } - } - // We should have returned sooner. - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); -} - -#endif - -const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) -{ - ClearError(); - - // Parse away, at the document level. Since a document - // contains nothing but other tags, most of what happens - // here is skipping white space. - if ( !p || !*p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - // Note that, for a document, this needs to come - // before the while space skip, so that parsing - // starts from the pointer we are given. - location.Clear(); - if ( prevData ) - { - location.row = prevData->cursor.row; - location.col = prevData->cursor.col; - } - else - { - location.row = 0; - location.col = 0; - } - TiXmlParsingData data( p, TabSize(), location.row, location.col ); - location = data.Cursor(); - - if ( encoding == TIXML_ENCODING_UNKNOWN ) - { - // Check for the Microsoft UTF-8 lead bytes. - const unsigned char* pU = (const unsigned char*)p; - if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 - && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 - && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) - { - encoding = TIXML_ENCODING_UTF8; - useMicrosoftBOM = true; - } - } - - p = SkipWhiteSpace( p, encoding ); - if ( !p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - while ( p && *p ) - { - TiXmlNode* node = Identify( p, encoding ); - if ( node ) - { - p = node->Parse( p, &data, encoding ); - LinkEndChild( node ); - } - else - { - break; - } - - // Did we get encoding info? - if ( encoding == TIXML_ENCODING_UNKNOWN - && node->ToDeclaration() ) - { - TiXmlDeclaration* dec = node->ToDeclaration(); - const char* enc = dec->Encoding(); - VALIDATE( enc ); - - if ( *enc == 0 ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice - else - encoding = TIXML_ENCODING_LEGACY; - } - - p = SkipWhiteSpace( p, encoding ); - } - - // Was this empty? - if ( !firstChild ) { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); - return 0; - } - - // All is well. - return p; -} - -void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - // The first error in a chain is more accurate - don't set again! - if ( error ) - return; - - VALIDATE( err > 0 && err < TIXML_ERROR_STRING_COUNT ); - error = true; - errorId = err; - errorDesc = errorString[ errorId ]; - - errorLocation.Clear(); - if ( pError && data ) - { - data->Stamp( pError, encoding ); - errorLocation = data->Cursor(); - } -} - - -TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) -{ - TiXmlNode* returnNode = 0; - - p = SkipWhiteSpace( p, encoding ); - if( !p || !*p || *p != '<' ) - { - return 0; - } - - p = SkipWhiteSpace( p, encoding ); - - if ( !p || !*p ) - { - return 0; - } - - // What is this thing? - // - Elements start with a letter or underscore, but xml is reserved. - // - Comments: "; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - if ( document ) - document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // [ 1475201 ] TinyXML parses entities in comments - // Oops - ReadText doesn't work, because we don't want to parse the entities. - // p = ReadText( p, &value, false, endTag, false, encoding ); - // - // from the XML spec: - /* - [Definition: Comments may appear anywhere in a document outside other markup; in addition, - they may appear within the document type declaration at places allowed by the grammar. - They are not part of the document's character data; an XML processor MAY, but need not, - make it possible for an application to retrieve the text of comments. For compatibility, - the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity - references MUST NOT be recognized within comments. - - An example of a comment: - - - */ - - value = ""; - // Keep all the white space. - while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) - { - value.append( p, 1 ); - ++p; - } - if ( p && *p ) - p += strlen( endTag ); - - return p; -} - - -const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) return 0; - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - // Read the name, the '=' and the value. - const char* pErr = p; - p = ReadName( p, &name, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); - return 0; - } - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p || *p != '=' ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - ++p; // skip '=' - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - const char* end; - const char SINGLE_QUOTE = '\''; - const char DOUBLE_QUOTE = '\"'; - - if ( *p == SINGLE_QUOTE ) - { - ++p; - end = "\'"; // single quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else if ( *p == DOUBLE_QUOTE ) - { - ++p; - end = "\""; // double quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else - { - // All attribute values should be in single or double quotes. - // But this is such a common error that the parser will try - // its best, even without them. - value = ""; - while ( p && *p // existence - && !IsWhiteSpace( *p ) // whitespace - && *p != '/' && *p != '>' ) // tag end - { - if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { - // [ 1451649 ] Attribute values with trailing quotes not handled correctly - // We did not have an opening quote but seem to have a - // closing one. Give up and throw an error. - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - value += *p; - ++p; - } - } - return p; -} - -#ifdef TIXML_USE_STL -void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->peek(); - if ( !cdata && (c == '<' ) ) - { - return; - } - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - (*tag) += (char) c; - in->get(); // "commits" the peek made above - - if ( cdata && c == '>' && tag->size() >= 3 ) { - size_t len = tag->size(); - if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { - // terminator of cdata. - return; - } - } - } -} -#endif - -const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - value = ""; - TiXmlDocument* document = GetDocument(); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - - const char* const startTag = ""; - - if ( cdata || StringEqual( p, startTag, false, encoding ) ) - { - cdata = true; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - if ( document ) - document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // Keep all the white space, ignore the encoding, etc. - while ( p && *p - && !StringEqual( p, endTag, false, encoding ) - ) - { - value += *p; - ++p; - } - - TIXML_STRING dummy; - p = ReadText( p, &dummy, false, endTag, false, encoding ); - return p; - } - else - { - bool ignoreWhite = true; - - const char* end = "<"; - p = ReadText( p, &value, ignoreWhite, end, false, encoding ); - if ( p && *p ) - return p-1; // don't truncate the '<' - return 0; - } -} - -#ifdef TIXML_USE_STL -void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - (*tag) += (char) c; - - if ( c == '>' ) - { - // All is well. - return; - } - } -} -#endif - -const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) -{ - p = SkipWhiteSpace( p, _encoding ); - // Find the beginning, find the end, and look for - // the stuff in-between. - TiXmlDocument* document = GetDocument(); - if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); - return 0; - } - if ( data ) - { - data->Stamp( p, _encoding ); - location = data->Cursor(); - } - p += 5; - - version = ""; - encoding = ""; - standalone = ""; - - while ( p && *p ) - { - if ( *p == '>' ) - { - ++p; - return p; - } - - p = SkipWhiteSpace( p, _encoding ); - if ( StringEqual( p, "version", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - version = attrib.Value(); - } - else if ( StringEqual( p, "encoding", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - encoding = attrib.Value(); - } - else if ( StringEqual( p, "standalone", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - standalone = attrib.Value(); - } - else - { - // Read over whatever it is. - while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) - ++p; - } - } - return 0; -} - -bool TiXmlText::Blank() const -{ - for ( unsigned i=0; i - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, const char* argv[]) { - std::vector args(argv, argv + argc); - -#ifdef CRASH_HANDLER - installCrashHandler(); -#endif - - // initialize resources - g_resources.init(argv[0]); - std::string compactName = g_resources.getCompactName(); - g_logger.setLogFile(compactName + ".log"); - - // setup application name and version - g_app.setName("OTClientV8"); - g_app.setCompactName(compactName); - g_app.setVersion("2.4"); - -#ifdef WITH_ENCRYPTION - if (std::find(args.begin(), args.end(), "--encrypt") != args.end()) { - g_lua.init(); - g_resources.encrypt(args.size() >= 3 ? args[2] : ""); - std::cout << "Encryption complete" << std::endl; -#ifdef WIN32 - MessageBoxA(NULL, "Encryption complete", "Success", 0); -#endif - return 0; - } -#endif - - if (g_resources.launchCorrect(g_app.getName(), g_app.getCompactName())) { - return 0; // started other executable - } - - // initialize application framework and otclient - g_app.init(args); - g_client.init(args); - g_http.init(); - - // find script init.lua and run it - g_resources.setupWriteDir(g_app.getName(), g_app.getCompactName()); - g_resources.setup(); - - if (!g_lua.safeRunScript("init.lua")) { - if (g_resources.isLoadedFromArchive() && !g_resources.isLoadedFromMemory() && - g_resources.loadDataFromSelf(true)) { - g_logger.error("Unable to run script init.lua! Trying to run version from memory."); - if (!g_lua.safeRunScript("init.lua")) { - g_resources.deleteFile("data.zip"); // remove incorrect data.zip - g_logger.fatal("Unable to run script init.lua from binary file!\nTry to run client again."); - } - } else { - g_logger.fatal("Unable to run script init.lua!"); - } - } - -#ifdef WIN32 - // support for progdn proxy system, if you don't have this dll nothing will happen - // however, it is highly recommended to use otcv8 proxy system - LoadLibraryA("progdn32.dll"); -#endif - - // the run application main loop - g_app.run(); - -#ifdef CRASH_HANDLER - uninstallCrashHandler(); -#endif - - // unload modules - g_app.deinit(); - - // terminate everything and free memory - g_http.terminate(); - g_client.terminate(); - g_app.terminate(); - return 0; -} - -#ifdef ANDROID -#include - -android_app* g_androidState = nullptr; -void android_main(struct android_app* state) -{ - g_mainThreadId = g_dispatcherThreadId = std::this_thread::get_id(); - g_androidState = state; - - state->userData = nullptr; - state->onAppCmd = +[](android_app* app, int32_t cmd) -> void { - return g_androidWindow.handleCmd(cmd); - }; - state->onInputEvent = +[](android_app* app, AInputEvent* event) -> int32_t { - return g_androidWindow.handleInput(event); - }; - state->activity->callbacks->onNativeWindowResized = +[](ANativeActivity* activity, ANativeWindow* window) -> void { - g_graphicsDispatcher.scheduleEventEx("updateWindowSize", [] { - g_androidWindow.updateSize(); - }, 500); - }; - state->activity->callbacks->onContentRectChanged = +[](ANativeActivity* activity, const ARect* rect) -> void { - g_graphicsDispatcher.scheduleEventEx("updateWindowSize", [] { - g_androidWindow.updateSize(); - }, 500); - }; - - bool terminated = false; - g_window.setOnClose([&] { - terminated = true; - }); - while(!g_window.isVisible() && !terminated) - g_window.poll(); // init window - // run app - const char* args[] = { "otclientv8.apk" }; - main(1, args); - std::exit(0); // required! -} -#endif diff --git a/tutorials/HTTP.md b/tutorials/HTTP.md deleted file mode 100644 index dfb6a25..0000000 --- a/tutorials/HTTP.md +++ /dev/null @@ -1,127 +0,0 @@ -## OTClientV8 HTTP protocol - -OTClientV8 comes with HTTP/HTTPS and JSON support in lua. - -### Available functions -``` -HTTP.get(url, callback) -HTTP.getJSON(url, callback) -- website should return json -HTTP.post(url, data, callback) -HTTP.postJSON(url, data, callback) -- data should be a table {} and website should return json -HTTP.download(url, file, downloadCallback, progressCallback) -- progressCallback can be null -HTTP.downloadImage(url, downloadImageCallback) -HTTP.cancel(operationId) -``` - -Each function, except `cancel` return operationId, you can use it to cancel http request. -Those functions came from `modules/corelib/http.lua` and they use more advanced g_http API. -Files from download are available in virtual "/downloads" directory. Downloading of images is using cache based on url (so if you change image it won't refresh until restart or change url). - -### Callbacks -For get, getJSON, post and postJSON HTTP callback should look like this: -``` -function callback(data, err) - if err then - -- handle error, if err is not null then err is a string - return - end - -- handle data - -- if it's data from getJSON/postJSON then data is a table {} -end -``` - -For download: -``` -function downloadCallback(path, checksum, err) - if err then - -- handle error, if err is not null then err is a string - return - end - -- do something with path and checksum -end - -function progressCallback(progress, speed) - -- progress is from 0 to 100 - -- speed is in kbps -end -``` - -For downloadImage: -``` -function downloadImageCallback(path, err) - if err then - -- handle error, if err is not null then err is a string - return - end - -- do something with path to downloaded image -end -``` - -### Support for images from base64 -If you want to load image from base64 there's special function for it: `Image:setImageSourceBase64(base64code)` -You can find an example of that in `modules/client_news/news.lua`. Only PNG images are supported. - -### Timeout -Default timeout for every operations is 5s, you can change it in `modules/corelib/http.lua`. - -### Examples -There are few lua scripts using HTTP api: -``` -modules/client_entergame/entergame.lua -modules/client_feedback/feedback.lua -modules/client_news/news.lua -modules/client_updater/updater.lua -modules/game_shop/shop.lua -``` - -Examples: -``` -HTTP.get("https://api.ipify.org/", function(data, err) - if err then - g_logger.info("Whoops! Error occured: " .. err) - return - end - g_logger.info("My IP is: " .. data) -end) - -HTTP.getJSON("https://api.ipify.org/?format=json", function(data, err) - if err then - g_logger.info("Whoops! Error occured: " .. err) - return - end - g_logger.info("My IP is: " .. tostring(data['ip'])) -end) -``` - -### Regex -If you're pro, there's also support for simple regex in lua which look like this: -``` -let clients = new Set(); - -require('uWebSockets.js').App().ws('/*', { - open: (ws, req) => { - clients.add(ws); - }, - message: (ws, message, isBinary) => { - console.log("Message: " + message); - let ok = ws.send(message, isBinary); - }, - close: (ws, code, message) => { - clients.delete(ws); - } -}).any('/*', (res, req) => { - /* Let's deny all Http */ - res.end('Nothing to see here!'); -}).listen(9000, (listenSocket) => { - if (listenSocket) { - console.log('Listening to port 9000'); - } -}); - - -setInterval(() => { - for(let client of clients) { - client.send("hello", false); - } -}, 1000); -``` diff --git a/tutorials/OTML.md b/tutorials/OTML.md deleted file mode 100644 index 52bda7e..0000000 --- a/tutorials/OTML.md +++ /dev/null @@ -1,59 +0,0 @@ -## OTClientV8 OTML extension - -In many modules which are using OTML, you can see such code: -``` -... -spelllistWindow = g_ui.displayUI('spelllist', modules.game_interface.getRightPanel()) -spelllistWindow:hide() - -nameValueLabel = spelllistWindow:getChildById('labelNameValue') -formulaValueLabel = spelllistWindow:getChildById('labelFormulaValue') -vocationValueLabel = spelllistWindow:getChildById('labelVocationValue') -groupValueLabel = spelllistWindow:getChildById('labelGroupValue') -typeValueLabel = spelllistWindow:getChildById('labelTypeValue') -cooldownValueLabel = spelllistWindow:getChildById('labelCooldownValue') -levelValueLabel = spelllistWindow:getChildById('labelLevelValue') -manaValueLabel = spelllistWindow:getChildById('labelManaValue') -premiumValueLabel = spelllistWindow:getChildById('labelPremiumValue') -descriptionValueLabel = spelllistWindow:getChildById('labelDescriptionValue') -... -``` - -Calling getChildById for every element in our OTML is annoying, taking unnecessary cpu time and looks awful. That's why there's new feature which creates reference to children automatically so you don't need to use getChildById ever again. -Instead of using: -``` -spelllistWindow = g_ui.displayUI('spelllist', modules.game_interface.getRightPanel()) -nameValueLabel = spelllistWindow:getChildById('labelNameValue') -formulaValueLabel = spelllistWindow:getChildById('labelFormulaValue') -vocationValueLabel = spelllistWindow:getChildById('labelVocationValue') -``` - -In OTClientV8 you can use: -``` -spelllistWindow = g_ui.displayUI('spelllist', modules.game_interface.getRightPanel()) -spelllistWindow.nameValueLabel -spelllistWindow.formulaValueLabel -spelllistWindow.vocationValueLabel -``` - -It has been added recently so most of the modules don't use this feature, but you can see it in action for example in `modules/game_shop` module. -In `shop.lua` there're 0 calls for getChildById, code looks like this: -``` -shop = g_ui.displayUI('shop') - -connect(shop.categories, { onChildFocusChange = changeCategory }) - -while shop.offers:getChildCount() > 0 do - local child = shop.offers:getLastChild() - shop.offers:destroyChildren(child) -end - -shop.adPanel:setHeight(shop.infoPanel:getHeight()) -shop.adPanel.ad:setText("") - -category = g_ui.createWidget('ShopCategoryItem', shop.categories) -category.item:setItemId(data["item"]) -category.item:setItemCount(data["count"]) -``` - -So whenever possible, don't use getChildById. Use this new feature which is nicer and faster. diff --git a/tutorials/Updater_encryption_compression.md b/tutorials/Updater_encryption_compression.md deleted file mode 100644 index c8fc7e7..0000000 --- a/tutorials/Updater_encryption_compression.md +++ /dev/null @@ -1,59 +0,0 @@ -## OTClientV8 Updater, encryption and compression - -OTClientV8 comes with updater, encryption and file compression, here's how to use it. - -## Video version: https://www.youtube.com/watch?v=RzEZ__Iq9-s -[![Video tutorial](https://img.youtube.com/vi/RzEZ__Iq9-s/0.jpg)](https://www.youtube.com/watch?v=RzEZ__Iq9-s) - - -## Encryption and compression -First of all, encryption and compression is basically the same, wherever you encrypt file, first it's being compressed. For example, otcv8 is able to compress Tibia.dat from Tibia 10.99 from 177 MB to 49 MB. - -### Steps: -1. First edit init.lua, make sure you set correct APP_NAME (just keep it unique), Services and Servers -2. Copy directory with everything, if you encrypt it by mistake you won't be able to recover it back. From now we work in copied directory -3. Open cmd, run otclient_gl.exe --encrypt -4. Wait 10-30s for message "encryption complete", close this message -5. Now create zip archive with data, modules and init.lua. To create zip archive use default windows feature for that, just select data, modules and init.lua, right click, send to -> Compress (zipped) folder. Rename this archive to data.zip -6. That's it. Copy otclient_gl.exe, otclient_dx.exe, libEGL.dll, libGLESv2.dll, d3dcompiler_46.dll and data.zip to another folder, compress this new folder and send it to players - -### Extra steps if you don't want to have data.zip: -7. We will add data.zip to .exe files, because there are 2 exes, if you're using updater and your data.zip is big, let's say bigger than 20MB, remove Tibia.dat and Tibia.spr from data.zip to make it smaller. OTCv8 will download them from updater. -8. Open cmd, and run 2 commands -``` -type data.zip >> otclient_gl.exe -type data.zip >> otclient_dx.exe -``` -It will append data.zip archive to .exe file, `type` is windows equivalent of linux `cat`. - -9. Remove data.zip, send otclient_gl.exe, otclient_dx.exe, libEGL.dll, libGLESv2.dll and d3dcompiler_46.dll to players. - -### WARNING: When using data.zip (also inside .exe), all files must be encrypted, otherwise otclient won't start (will display decryption error) - -## Updater -1. On your website server, upload somewhere updater.php and set link to updater service in init.lua, for example: `updater = "http://otclient.ovh/test/updater.php"` -2. Now create directory for your files, let's make directory called `files` -3. Upload otclient_gl.exe, otclient_dx.exe, libEGL.dll, libGLESv2.dll, d3dcompiler_46.dll and data.zip (with spr and dat) -4. Unpack data.zip, you can use linux command `unzip data.zip` -5. Open updater.php and configure it, especially: -``` -$data_dir = "/var/www/otclient/test/files"; -$things_dir = "/data/things"; // files from that dir won't be downloaded automaticly, you can set it to null to download everything automaticly (useful if you have only 1 version of data/sprites) -$files_url = "http://otclient.ovh/test/files"; -``` -6. Set chmod 777 to dir with updater.php, it must be able to create checksum files, so for example: `chmod 777 /var/www/html/otclient/test` - -That's it your updater is configured. If you change something just remember to encrypt it first and then put it to your `files` directory. - -### Updated files and binaries are kept in %appdata%\otclientv8\APP_NAME - -## OTClientV8 failsafe and startup procedure -Sometimes you may fuckup something, and after update your client won't launch correctly. For your luck there's failsafe mode which can help recover from that state. But before explaing that, let's see how startup procedure looks like: - -1. If there's init.lua in directory launch using this init.lua, don't use updater and finish startup sequence. -2. Scan files in %appdata%\otclientv8\APP_NAME, if there's an exe of same type (dx/gl in file name) newer than current running file, launch this exe. If new exe has been launched, wait 10s, if it's still working correctly then finish working, if not, then launch failsafe mode. -3. If there's no any newer exe to launch, check if there's data.zip in %appdata%\otclientv8\APP_NAME, if there is, use that data.zip. If it doesn't exist, use data.zip from current directory and if that doesn't exist too, try to use data.zip inside .exe file. -4. If anything goes wrong, fatal error, crash or anything else within 10s from start, start failsafe mode - -In failsafe mode, otcv8 will load data.zip inside .exe file, not from %appdata%\otclientv8\APP_NAME. It will download all files again and create new data.zip in %appdata%\otclientv8\APP_NAME, then it will restart and try to run itself again using data.zip from %appdata%\otclientv8\APP_NAME. -So if you by mistake uploaded wrong file and otcv8 won't start (for example it won't start if you use data.zip and some files are unencrypted), you still can fix that by uploading correct file. Players won't need to download everything again. diff --git a/tutorials/Walking.md b/tutorials/Walking.md deleted file mode 100644 index aca967d..0000000 --- a/tutorials/Walking.md +++ /dev/null @@ -1,3 +0,0 @@ -# OTClientV8 New walking - -## Check out: https://github.com/OTCv8/otclientv8-tfs \ No newline at end of file diff --git a/tutorials/Websockets.md b/tutorials/Websockets.md deleted file mode 100644 index b533be9..0000000 --- a/tutorials/Websockets.md +++ /dev/null @@ -1,91 +0,0 @@ -## OTClientV8 Websockets - -From version 1.4 OTClientV8 supports websockets and secure websockets. They can be also used in bot. - -### Usage -``` -local url = "ws://otclient.ovh/" -local websocket = HTTP.WebSocket(url, { - onOpen = function(message, websocketId) - - end, - onMessage = function(message, websocketId) - - end, - onClose = function(message, websocketId) - - end, - onError = function(message, websocketId) - - end -}) --- it returns -print(websocket.id) -print(websocket.url) -websocket.send("Hello") -scheduleEvent(function() - websocket.close() -end, 5000) -``` - -If your websocket is only using json then you can use HTTP.WebSocketJSON -``` -local url = "wss://otclient.ovh:3000/" -local websocket = HTTP.WebSocketJSON(url, { - onOpen = function(message, websocketId) - - end, - onMessage = function(message, websocketId) - -- message is table, after json.decode - end, - onClose = function(message, websocketId) - - end, - onError = function(message, websocketId) - -- will also return json errors - end -}) --- it returns -print(websocket.id) -print(websocket.url) -websocket.send({message="Hello"}) -scheduleEvent(function() - websocket.close() -end, 5000) -``` - -A working example with reconnect can be found in `client_entergame/entergame.lua` - -### Websockets have 15s timeout by default, you can change it in `corelib/http.lua` - -### WebSocket server -Creating websocket server is easy, here are some links: -https://github.com/websockets/ws -https://medium.com/@martin.sikora/node-js-websocket-simple-chat-tutorial-2def3a841b61 -https://medium.com/hackernoon/implementing-a-websocket-server-with-node-js-d9b78ec5ffa8 - -Personally, I use: -https://github.com/uNetworking/uWebSockets -https://github.com/uNetworking/uWebSockets.js - -### Example server in nodejs -You need to install nodejs and then `npm install uNetworking/uWebSockets.js#v16.4.0` -Name it server.js and run it by using command: `nodejs server.js` - -``` -require('uWebSockets.js').App().ws('/*', { - message: (ws, message, isBinary) => { - console.log("message"); - let ok = ws.send(message, isBinary); - } -}).any('/*', (res, req) => { - /* Let's deny all Http */ - res.end('Nothing to see here!'); -}).listen(9000, (listenSocket) => { - if (listenSocket) { - console.log('Listening to port 9000'); - } -}); -``` - -More examples: https://github.com/uNetworking/uWebSockets.js/tree/master/examples \ No newline at end of file