Version 0.95 BETA

This commit is contained in:
OTCv8 2019-10-02 03:38:52 +02:00
parent 9219c78f15
commit 5220a3bdd2
501 changed files with 38097 additions and 2 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
OTClient is made available under the MIT License
Copyright (c) 2010-2017 OTClient <https://github.com/edubart/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.

View File

@ -1,2 +1,42 @@
# otclientv8 # OTClientV8
Free version of an alternative tibia client for otserv
Preview version of OTClientV8, it's v0.95 beta, version v1.0 with all tutorial will be released soon
It's based on https://github.com/edubart/otclient. It's not backward compatible
## Quick Start
Open `init.lua` and edit:
```
-- CONFIG
APP_NAME = "otclientv8" -- important, change it, it's name for config dir and files in appdata
APP_VERSION = 1337 -- client version for updater and login to indentify outdated client
-- If you don't use updater or other service, set it to updater = ""
Services = {
website = "http://otclient.ovh", -- currently not used
updater = "http://otclient.ovh/api/updater.php",
news = "http://otclient.ovh/api/news.php",
stats = "",
crash = "http://otclient.ovh/api/crash.php",
feedback = "http://otclient.ovh/api/feedback.php"
}
-- Servers accept http login url or ip:port:version
Servers = {
OTClientV8 = "http://otclient.ovh/api/login.php",
OTClientV8proxy = "http://otclient.ovh/api/login.php?proxy=1",
OTClientV8c = "otclient.ovh:7171:1099"
}
ALLOW_CUSTOM_SERVERS = true -- if true it will show option ANOTHER on server list
-- CONFIG END
```
Also remember to add your sprite and data file to data/things
That's it, you're ready to use OTClientV8.
Soon I will add tutorial how to activate extra features (there are a lot of them)
DirectX version requires 3 dlls: libEGL.dll libGLESv2.dll d3dcompiler_46.dll
If it can't start (missing dlls) then user need to install visual studio 2019 redistributable x86: https://aka.ms/vs/16/release/vc_redist.x86.exe

11
api/crash.php Normal file
View File

@ -0,0 +1,11 @@
<?php
$data = file_get_contents("php://input", false, stream_context_get_default(), 0, $_SERVER["CONTENT_LENGTH"]);
if($_REQUEST['txt'] == 1) {
file_put_contents("crashes/".time()."_".$_SERVER['REMOTE_ADDR'].".txt", $data);
} else if($_REQUEST['txt'] == 2) {
file_put_contents("crashes/".time()."_".$_SERVER['REMOTE_ADDR'].".log", $data);
} else {
file_put_contents("crashes/".time()."_".$_SERVER['REMOTE_ADDR'].".dmp", $data);
}
echo "OK";
?>

11
api/feedback.php Normal file
View File

@ -0,0 +1,11 @@
<?php
$data = file_get_contents("php://input");
//$data = json_decode($data);
if(empty($data)) {
return http_response_code(400);
}
file_put_contents("feedback.txt", $data."\n\n\n", FILE_APPEND);
echo "OK";
?>

BIN
api/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

182
api/login.php Normal file
View File

@ -0,0 +1,182 @@
<?php
// author otclient@otclient.ovh
// config
$dbserver = "127.0.0.1";
$username = "otclient";
$password = "otclient";
$dbname = "otclient";
$serverName = "OTClientV8";
$serverIp = "otclient.ovh";
//$serverIp = "proxy"; // if serverIp set to 0.0.0.0 or proxy it will connect to server using proxies, set proxies bellow
$serverPort = 7172; // GAME PORT (7172 usually)
$version = 1099;
$maxLogins = 10; // 0 or null to disable
$blockTime = 60; // after too many logins, in seconds
// CREATE TABLE `login_attmpts` ( `acc` varchar(50) NOT NULL, `ip` varchar(30) NOT NULL, `date` datetime NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
$encryption = "sha1"; // sha1 or md5, everything else == none
// required files in things, type => (filename, md5 checksum in hex)
// $things = null; things can be null if you want to use default values, but then enable auto download of sprites and dat in updater
/* //for 860
$things = array(
"sprites" => array("$version/Tibia.spr", "3db8c0098d34ca3d9a8ec29d40ef1b7b"),
"data" => array("$version/Tibia.dat", "85785b5d67b4c111f780a74895c85c75")
);
*/
// for 1099
$things = array(
"sprites" => array("$version/Tibia.spr", "63d38646597649a55a8be463d6c0fb49"),
"data" => array("$version/Tibia.dat", "ae7157cfff42f14583d6363e77044df7")
);
$customProtocol = nil; // if not nil it will replace client version in protocolgame, may be used to detect outdated client
// executes modules.client_options.setOption(option, value, true)
$settings = array(
);
// it's from src/client/const.h, executes g_game.enableFeature/g_game.disableFeature
$features = array(
22 => true, // GameFormatCreatureName
25 => true, // GameExtendedClientPing
30 => true, // GameChangeMapAwareRange
// 56 => true, // GameSpritesAlphaChannel
80 => true,
90 => true, // GameNewWalking
// 91 => true, // GameSmootherWalking
95 => true, // GameBot
97 => true, // light
);
$rsa = "1091201329673994292788609605089955415282375029027981291234687579" .
"3726629149257644633073969600111060390723088861007265581882535850" .
"3429057592827629436413108566029093628212635953836686562675849720" .
"6207862794310902180176810615217550567108238764764442605581471797" .
"07119674283982419152118103759076030616683978566631413";
// proxies (it's custom feature, not available for free)
$proxies = array(
array(
"localPort" => 7172,
"host" => "51.158.184.57",
"port" => 7162,
"priority" => 0
),
array(
"localPort" => 7172,
"host" => "54.39.190.20",
"port" => 7162,
"priority" => 0
),
array(
"localPort" => 7172,
"host" => "51.83.226.109",
"port" => 7162,
"priority" => 0,
),
array(
"localPort" => 7172,
"host" => "35.247.201.100",
"port" => 443,
"priority" => 0
)
);
// config end
$data = file_get_contents("php://input");
$data = json_decode($data);
if(empty($data)) {
http_response_code(400);
}
if($data->quick == 1) {
// under development
http_response_code(404);
die();
}
$conn = new mysqli($dbserver, $username, $password, $dbname);
if ($conn->connect_error) {
die("SQL connection failed: " . $conn->connect_error);
}
$account = $data->account;
if($encryption == "sha1")
$password = sha1($data->password);
else if($encryption == "md5")
$password = md5($data->password);
else
$password = $data->password;
$token = $data->token;
$account = preg_replace("/[^A-Za-z0-9 ._-]/", '', $account);
$password = preg_replace("/[^A-Za-z0-9 ._-]/", '', $password);
$token = preg_replace("/[^A-Za-z0-9 ._-]/", '', $token);
$ip = preg_replace("/[^A-Za-z0-9 ._-]/", '', $_SERVER['REMOTE_ADDR']);
if($maxLogins != null && $maxLogins > 0) {
$result = $conn->query("select count(*) as `attempts` from `login_attmpts` where `ip` = '".$ip."' and `date` > NOW() - INTERVAL ".$blockTime." SECOND");
$result = $result->fetch_assoc();
if($result['attempts'] > $maxLogins) {
die(json_encode(array("error" => "Too many login attempts, please wait ".$blockTime." seconds.")));
}
$conn->query("INSERT INTO `login_attmpts` (`acc`, `ip`, `date`) VALUES ('".$conn->real_escape_string($account)."', '".$ip."', NOW())");
}
$result = $conn->query("select * from accounts where `name` = '".$conn->real_escape_string($account)."' and `password` = '".$conn->real_escape_string($password)."'");
if ($result->num_rows != 1) {
die(json_encode(array("error" => "Invalid account/password")));
}
$acc = $result->fetch_assoc();
$session = "".$data->account."\n".$data->password."\n$token\n".time();
if($serverIp != "proxy" && $serverIp != "0.0.0.0") {
$proxies = null;
}
$response = array(
"error" => "",
"rsa" => $rsa,
"version" => $version,
"things" => $things,
"customProtocol" => $customProtocol,
"session" => $session,
"characters" => array(),
"account" => array(),
"settings" => $settings,
"features" => $features,
"proxies" => $proxies
);
$response["account"]["status"] = 0; // 0=ok, 1=frozen, 2=supsended
$response["account"]["subStatus"] = 1; // 0=free, 1=premium
$response["account"]["premDays"] = 65535;
$characters = $conn->query("select * from `players` where `account_id` = '".$acc['id']."'");
if ($characters->num_rows == 0) {
die(json_encode(array("error" => "Account doesn't have any characters")));
}
while($character = $characters->fetch_assoc()) {
$response["characters"][] = array(
"name" => $character['name'],
"worldName" => $serverName,
"worldIp" => $serverIp,
"worldPort" => $serverPort
// if you are good enough and can code it in lua, you can add outfit, level, vocation, whatever you want here
);
}
echo json_encode($response);
?>

28
api/newlogin.php Normal file
View File

@ -0,0 +1,28 @@
<?php
function generateRandomString($length = 6) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
$code = generateRandomString();
require_once("phpqrcode.php");
ob_start();
QRCode::png($code, null, QR_ECLEVEL_H, 7, 1);
$qrcode = base64_encode( ob_get_contents() );
ob_end_clean();
$data = array(
"qrcode" => $qrcode,
"code" => $code,
"status" => "waiting"
);
echo json_encode($data);
?>

35
api/news.php Normal file
View File

@ -0,0 +1,35 @@
<?php
$news = array();
$lang = "en";
if(isset($_GET['lang']))
$lang = $_GET['lang'];
$jokes = array();
$jokes[] = "How do you make a tissue dance? You put a little boogie in it.";
$jokes[] = "Why did the policeman smell bad? He was on duty.";
$jokes[] = "Why does Snoop Dogg carry an umbrella? FO DRIZZLE!";
$jokes[] = "Why can't you hear a pterodactyl in the bathroom? Because it has a silent pee.";
$jokes[] = "What did the Zen Buddist say to the hotdog vendor? Make me one with everything.";
$jokes[] = "What kind of bees make milk instead of honey? Boobies.";
$jokes[] = "Horse walks into a bar. Bartender says, 'Why the long face?'";
$jokes[] = "A mushroom walks into a bar. The bartender says, 'Hey, get out of here! We don't serve mushrooms here'. Mushroom says, 'why not? I'm a fungai!'";
$jokes[] = "I never make mistakes…I thought I did once; but I was wrong.";
$jokes[] = "What's Beethoven's favorite fruit? Ba-na-na-naaa!";
$jokes[] = "What did the little fish say when he swam into a wall? DAM!";
$jokes[] = "Knock knock. Who's there? Smell mop. (finish this joke in your head)";
$jokes[] = "Where does a sheep go for a haircut? To the baaaaa baaaaa shop!";
$jokes[] = "What does a nosey pepper do? Gets jalapeno business!";
$jokes[] = "Your mom is so poor, she even can't pay attention";
$news[] = array("title" => "TEST SERVERS", "text" => "OTCLIENTV8 Accs:\nacc1/acc\nacc2/acc\nacc3/acc");
$news[] = array("title" => "First title",
"text" => "This is example of lua g_http api. Those news are from http://otclient.ovh/news.php
\nRequest was for language '".$lang."', however, there's only english version of this, don't have time to create more versions");
$news[] = array("title" => "Random joke", "text" => $jokes[array_rand($jokes)]);
$news[] = array("title" => "Image test", "image" => base64_encode(file_get_contents("image.png")));
echo json_encode($news);
?>

3312
api/phpqrcode.php Normal file

File diff suppressed because it is too large Load Diff

13
api/stats.php Normal file
View File

@ -0,0 +1,13 @@
<?php
$data = file_get_contents("php://input");
$json = json_decode($data);
if(!$json || !$json->uid) {
die();
}
if($json->uid) {
file_put_contents("stats/".($json->uid).".log", "\n".$data."\n", FILE_APPEND);
}
echo "OK";
?>

96
api/updater.php Normal file
View File

@ -0,0 +1,96 @@
<?php
// set chmod 777 to dir with this file to create checksum files
$data = file_get_contents("php://input");
$data = json_decode($data);
if(!empty($data)) {
$platform = $data->platform;
$version = $data->version; // currently not used
}
if($platform == "WIN32-WGL") { // opengl
$binary_path = "/otclient_gl.exe";
$checksums_file = "checksums_gl.txt";
} else if($platform == "WIN32-EGL") { // dx
$binary_path = "/otclient_dx.exe";
$checksums_file = "checksums_dx.txt";
} else {
$binary_path = "";
$checksums_file = "checksums.txt";
}
$data_dir = "/var/www/otclient/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/files";
$update_checksum_interval = 60; // caling updater 100x/s would lag disc, we need to cache it
$main_files_and_dirs = array("data", "modules", "init.lua"); // used to ignore other files/dirs in data_dir
// CONFIG END
$data = array("url" => $files_url, "files" => array(), "things" => array(), "binary" => $binary_path);
function getDirFiles($dir, &$results = array()){
$files = scandir($dir);
foreach($files as $key => $value){
$path = realpath($dir.DIRECTORY_SEPARATOR.$value);
if(!is_dir($path)) {
$results[] = $path;
} else if($value != "." && $value != "..") {
getDirFiles($path, $results);
}
}
return $results;
}
function updateChecksums() {
global $data_dir;
global $main_files_and_dirs;
global $binary_path;
global $checksums_file;
global $data;
global $things_dir;
$ret = array();
$data_dir_realpath = realpath($data_dir);
$files = getDirFiles($data_dir);
foreach($files as $file) {
$relative_path = str_replace($data_dir_realpath, "", $file);
$ps = explode("/", $relative_path);
if($relative_path == $binary_path || (count($ps) >= 2 && in_array($ps[1], $main_files_and_dirs)))
$ret[$relative_path] = md5_file($file);
}
foreach($ret as $file => $checksum) {
if($things_dir != null && !empty($things_dir) && strpos($file, $things_dir) === 0) {
$data["things"][$file] = $checksum;
} else {
$data["files"][$file] = $checksum;
}
}
$ret = json_encode($data);
if(file_put_contents($checksums_file, $ret) === FALSE) {
echo "Can't create checksum file (try to set correct chmod) ". - $checksums_file;
exit();
}
return $ret;
}
if (function_exists('sem_get')) {
$semaphore = sem_get(18237192837, 1, 0666, 1);
if(!$semaphore)
{
echo "Failed to get semaphore - sem_get().\n";
exit();
}
sem_acquire($semaphore);
}
$ft = filemtime($checksums_file);
if($ft === false || $ft + $update_checksum_interval < time()) {
echo updateChecksums();
} else {
echo file_get_contents($checksums_file);
}
if (function_exists('sem_get')) {
sem_release($semaphore);
}
?>

BIN
d3dcompiler_46.dll Normal file

Binary file not shown.

13
data/cursors/cursors.otml Normal file
View File

@ -0,0 +1,13 @@
Cursors
target:
image: targetcursor
hot-spot: 9 9
horizontal:
image: horizontalcursor
hot-spot: 9 4
vertical:
image: verticalcursor
hot-spot: 4 9
text:
image: textcursor
hot-spot: 4 9

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

BIN
data/cursors/textcursor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

View File

@ -0,0 +1,7 @@
Font
name: cipsoftFont
texture: cipsoftFont
height: 8
glyph-size: 8 8
space-width: 2
default: true

BIN
data/fonts/cipsoftFont.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,6 @@
Font
name: sans-bold-16px
texture: sans-bold-16px_cp1252
height: 20
glyph-size: 24 24
space-width: 3

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1,8 @@
Font
name: terminus-10px
texture: terminus-10px
height: 12
y-offset: 0
glyph-size: 16 16
fixed-glyph-width: 6
space-width: 6

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,8 @@
Font
name: terminus-14px-bold
texture: terminus-14px-bold
height: 16
y-offset: 2
glyph-size: 16 16
fixed-glyph-width: 8
space-width: 8

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,7 @@
Font
name: verdana-11px-antialised
texture: verdana-11px-antialised_cp1252
height: 14
glyph-size: 16 16
space-width: 4
default: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -0,0 +1,6 @@
Font
name: verdana-11px-monochrome
texture: verdana-11px-monochrome_cp1252
height: 14
glyph-size: 16 16
space-width: 3

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1,8 @@
Font
name: verdana-11px-rounded
texture: verdana-11px-rounded_cp1252
height: 16
glyph-size: 16 16
y-offset: -2
spacing: -1 -3
space-width: 4

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
data/images/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

BIN
data/images/clienticon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

BIN
data/images/flags/de.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
data/images/flags/en.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
data/images/flags/es.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
data/images/flags/pl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
data/images/flags/pt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
data/images/flags/sv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Some files were not shown because too many files have changed in this diff Show More