C client: Fix skins using all 64 characters not working

This commit is contained in:
UnknownShadow200 2018-09-10 14:00:32 +10:00
parent 446098e82c
commit 5f12a5b869
6 changed files with 99 additions and 100 deletions

View File

@ -309,7 +309,6 @@ namespace ClassicalSharp.Gui.Widgets {
struct Portion { public int Beg, Len, LineBeg, LineLen; } struct Portion { public int Beg, Len, LineBeg, LineLen; }
unsafe int Reduce(char* chars, int target, Portion* portions) { unsafe int Reduce(char* chars, int target, Portion* portions) {
Portion* start = portions;
int charsLen = 0, count = 0; int charsLen = 0, count = 0;
int* begs = stackalloc int[lines.Length]; int* begs = stackalloc int[lines.Length];
int* ends = stackalloc int[lines.Length]; int* ends = stackalloc int[lines.Length];

View File

@ -17,11 +17,8 @@ namespace ClassicalSharp.Map {
public WorldEnv Env; public WorldEnv Env;
public Guid Uuid; public Guid Uuid;
public string TextureUrl = null; public string TextureUrl = null;
public World(Game game) { Env = new WorldEnv(); }
public World(Game game) {
Env = new WorldEnv(game);
}
public void Reset() { public void Reset() {
Env.Reset(); Env.Reset();

View File

@ -53,13 +53,8 @@ namespace ClassicalSharp.Map {
public int SidesOffset = -2; public int SidesOffset = -2;
public float SkyboxHorSpeed, SkyboxVerSpeed; public float SkyboxHorSpeed, SkyboxVerSpeed;
public bool ExpFog; public bool ExpFog;
public WorldEnv() { ResetLight(); }
Game game;
public WorldEnv(Game game) {
this.game = game;
ResetLight();
}
public void Reset() { public void Reset() {
EdgeHeight = -1; SidesOffset = -2; CloudHeight = -1; EdgeHeight = -1; SidesOffset = -2; CloudHeight = -1;

View File

@ -15,8 +15,6 @@ namespace ClassicalSharp.Textures {
/// <summary> Extracts resources from a .zip texture pack. </summary> /// <summary> Extracts resources from a .zip texture pack. </summary>
public sealed class TexturePack { public sealed class TexturePack {
static Game game;
public static void ExtractDefault(Game game) { public static void ExtractDefault(Game game) {
ExtractZip(game.DefaultTexturePack, game); ExtractZip(game.DefaultTexturePack, game);
game.World.TextureUrl = null; game.World.TextureUrl = null;
@ -46,7 +44,6 @@ namespace ClassicalSharp.Textures {
} }
static void ExtractZip(Stream stream, Game game) { static void ExtractZip(Stream stream, Game game) {
TexturePack.game = game;
Events.RaiseTexturePackChanged(); Events.RaiseTexturePackChanged();
if (game.Graphics.LostContext) return; if (game.Graphics.LostContext) return;

View File

@ -27,8 +27,8 @@ struct AsyncRequest {
void* ResultData; void* ResultData;
UInt32 ResultSize; UInt32 ResultSize;
UInt64 LastModified; /* Time item cached at (if at all) */ UInt64 LastModified; /* Time item cached at (if at all) */
UInt8 Etag[STRING_SIZE]; /* ETag of cached item (if any) */ char Etag[STRING_SIZE]; /* ETag of cached item (if any) */
UInt8 RequestType; UInt8 RequestType;
}; };

View File

@ -897,8 +897,11 @@ void Http_Init(void) {
static ReturnCode Http_Make(struct AsyncRequest* req, HINTERNET* handle) { static ReturnCode Http_Make(struct AsyncRequest* req, HINTERNET* handle) {
String url = String_FromRawArray(req->URL); String url = String_FromRawArray(req->URL);
WCHAR urlStr[300]; Platform_ConvertString(urlStr, &url);
char headersBuffer[STRING_SIZE * 2] = { 0 }; char headersBuffer[STRING_SIZE * 2] = { 0 };
String headers = String_FromArray(headersBuffer); String headers = String_FromArray(headersBuffer);
WCHAR headersStr[STRING_SIZE * 2 + 1];
/* https://stackoverflow.com/questions/25308488/c-wininet-custom-http-headers */ /* https://stackoverflow.com/questions/25308488/c-wininet-custom-http-headers */
if (req->Etag[0] || req->LastModified) { if (req->Etag[0] || req->LastModified) {
@ -917,7 +920,13 @@ static ReturnCode Http_Make(struct AsyncRequest* req, HINTERNET* handle) {
String_AppendConst(&headers, "\r\n\r\n"); String_AppendConst(&headers, "\r\n\r\n");
} else { headers.buffer = NULL; } } else { headers.buffer = NULL; }
*handle = InternetOpenUrlA(hInternet, url.buffer, headers.buffer, headers.length, Int32 i;
for (i = 0; i < headers.length; i++) {
headersStr[i] = headers.buffer[i];
}
headersStr[headers.length] = '\0';
*handle = InternetOpenUrlW(hInternet, urlStr, headersStr, headers.length,
INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD, 0); INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD, 0);
return Win_Return(*handle); return Win_Return(*handle);
} }
@ -996,122 +1005,124 @@ ReturnCode Http_Free(void) { return Win_Return(InternetCloseHandle(hInternet));
CURL* curl; CURL* curl;
void Http_Init(void) { void Http_Init(void) {
CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT); CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT);
if (res) ErrorHandler_FailWithCode(res, "Failed to init curl"); if (res) ErrorHandler_FailWithCode(res, "Failed to init curl");
curl = curl_easy_init(); curl = curl_easy_init();
if (!curl) ErrorHandler_Fail("Failed to init easy curl"); if (!curl) ErrorHandler_Fail("Failed to init easy curl");
} }
static int Http_Progress(Int32* progress, double total, double received, double a, double b) { static int Http_Progress(Int32* progress, double total, double received, double a, double b) {
if (total == 0) return 0; if (total == 0) return 0;
*progress = (Int32)(100 * received / total); *progress = (Int32)(100 * received / total);
return 0; return 0;
} }
static struct curl_slist* Http_Make(struct AsyncRequest* req) { static struct curl_slist* Http_Make(struct AsyncRequest* req) {
struct curl_slist* list = NULL; struct curl_slist* list = NULL;
char buffer1[STRING_SIZE + 1] = { 0 }; char buffer1[STRING_SIZE + 1] = { 0 };
char buffer2[STRING_SIZE + 1] = { 0 }; char buffer2[STRING_SIZE + 1] = { 0 };
if (req->Etag[0]) { if (req->Etag[0]) {
String tmp = { buffer1, 0, STRING_SIZE }; String tmp = { buffer1, 0, STRING_SIZE };
String_AppendConst(&tmp, "If-None-Match: "); String_AppendConst(&tmp, "If-None-Match: ");
String etag = String_FromRawArray(req->Etag); String etag = String_FromRawArray(req->Etag);
String_AppendString(&tmp, &etag); String_AppendString(&tmp, &etag);
list = curl_slist_append(list, tmp.buffer); list = curl_slist_append(list, tmp.buffer);
} }
if (req->LastModified) { if (req->LastModified) {
String tmp = { buffer2, 0, STRING_SIZE }; String tmp = { buffer2, 0, STRING_SIZE };
String_AppendConst(&tmp, "Last-Modified: "); String_AppendConst(&tmp, "Last-Modified: ");
DateTime_HttpDate(req->LastModified, &tmp); DateTime_HttpDate(req->LastModified, &tmp);
list = curl_slist_append(list, tmp.buffer); list = curl_slist_append(list, tmp.buffer);
} }
return list; return list;
} }
static size_t Http_GetHeaders(char *buffer, size_t size, size_t nitems, struct AsyncRequest* req) { static size_t Http_GetHeaders(char *buffer, size_t size, size_t nitems, struct AsyncRequest* req) {
size_t total = size * nitems; size_t total = size * nitems;
if (size != 1) return total; /* non byte header */ if (size != 1) return total; /* non byte header */
String line = String_Init(buffer, nitems, nitems), name, value; String line = String_Init(buffer, nitems, nitems), name, value;
if (!String_UNSAFE_Separate(&line, ':', &name, &value)) return total; if (!String_UNSAFE_Separate(&line, ':', &name, &value)) return total;
/* value usually has \r\n at end */ /* value usually has \r\n at end */
if (value.length && value.buffer[value.length - 1] == '\n') value.length--; if (value.length && value.buffer[value.length - 1] == '\n') value.length--;
if (value.length && value.buffer[value.length - 1] == '\r') value.length--; if (value.length && value.buffer[value.length - 1] == '\r') value.length--;
if (!value.length) return total; if (!value.length) return total;
if (String_CaselessEqualsConst(&name, "ETag")) { if (String_CaselessEqualsConst(&name, "ETag")) {
String etag = String_ClearedArray(req->Etag); String etag = String_ClearedArray(req->Etag);
String_AppendString(&etag, &value); String_AppendString(&etag, &value);
} else if (String_CaselessEqualsConst(&name, "Content-Length")) { } else if (String_CaselessEqualsConst(&name, "Content-Length")) {
Convert_TryParseInt32(&value, &req->ResultSize); Convert_TryParseInt32(&value, &req->ResultSize);
} else if (String_CaselessEqualsConst(&name, "Last-Modified")) { } else if (String_CaselessEqualsConst(&name, "Last-Modified")) {
char tmpBuffer[STRING_SIZE + 1] = { 0 }; char tmpBuffer[STRING_SIZE + 1] = { 0 };
String tmp = { tmpBuffer, 0, STRING_SIZE }; String tmp = { tmpBuffer, 0, STRING_SIZE };
String_AppendString(&tmp, &value); String_AppendString(&tmp, &value);
time_t time = curl_getdate(tmp.buffer, NULL); time_t time = curl_getdate(tmp.buffer, NULL);
if (time == -1) return total; if (time == -1) return total;
req->LastModified = (UInt64)time * 1000 + UNIX_EPOCH; req->LastModified = (UInt64)time * 1000 + UNIX_EPOCH;
} }
return total; return total;
} }
static size_t Http_GetData(char *buffer, size_t size, size_t nitems, struct AsyncRequest* req) { static size_t Http_GetData(char *buffer, size_t size, size_t nitems, struct AsyncRequest* req) {
UInt32 total = req->ResultSize; UInt32 total = req->ResultSize;
if (!total || req->RequestType == REQUEST_TYPE_CONTENT_LENGTH) return 0; if (!total || req->RequestType == REQUEST_TYPE_CONTENT_LENGTH) return 0;
if (!req->ResultData) req->ResultData = Mem_Alloc(total, 1, "http get data"); if (!req->ResultData) req->ResultData = Mem_Alloc(total, 1, "http get data");
/* reuse Result as an offset */ /* reuse Result as an offset */
UInt32 left = total - req->Result; UInt32 left = total - req->Result;
left = min(left, nitems); left = min(left, nitems);
UInt8* dst = (UInt8*)req->ResultData + req->Result; UInt8* dst = (UInt8*)req->ResultData + req->Result;
Mem_Copy(dst, buffer, left); Mem_Copy(dst, buffer, left);
req->Result += left; req->Result += left;
return nitems; return nitems;
} }
ReturnCode Http_Do(struct AsyncRequest* req, volatile Int32* progress) { ReturnCode Http_Do(struct AsyncRequest* req, volatile Int32* progress) {
curl_easy_reset(curl); curl_easy_reset(curl);
String url = String_FromRawArray(req->URL); String url = String_FromRawArray(req->URL);
struct curl_slist* list = Http_Make(req); char urlStr[600]; Platform_ConvertString(urlStr, &url);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(curl, CURLOPT_URL, url.buffer); struct curl_slist* list = Http_Make(req);
curl_easy_setopt(curl, CURLOPT_USERAGENT, PROGRAM_APP_NAME); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(curl, CURLOPT_URL, urlStr);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, Http_Progress); curl_easy_setopt(curl, CURLOPT_USERAGENT, PROGRAM_APP_NAME);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progress); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, Http_GetHeaders); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, req); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, Http_Progress);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Http_GetData); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progress);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, req);
*progress = ASYNC_PROGRESS_FETCHING_DATA; curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, Http_GetHeaders);
CURLcode res = curl_easy_perform(curl); curl_easy_setopt(curl, CURLOPT_HEADERDATA, req);
*progress = 100; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Http_GetData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, req);
long status = 0; *progress = ASYNC_PROGRESS_FETCHING_DATA;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); CURLcode res = curl_easy_perform(curl);
req->StatusCode = status; *progress = 100;
curl_slist_free_all(list); long status = 0;
return res; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
req->StatusCode = status;
curl_slist_free_all(list);
return res;
} }
ReturnCode Http_Free(void) { ReturnCode Http_Free(void) {
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
curl_global_cleanup(); curl_global_cleanup();
return 0; return 0;
} }
#endif #endif