From dd396bfad27cddb5598a0c7512dbe0f98d140eb2 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Fri, 25 Sep 2015 22:46:42 +0200 Subject: [PATCH] Upload C# source code, raw --- MT_skins_updater.cs | 200 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 MT_skins_updater.cs diff --git a/MT_skins_updater.cs b/MT_skins_updater.cs new file mode 100644 index 0000000..6d27da0 --- /dev/null +++ b/MT_skins_updater.cs @@ -0,0 +1,200 @@ +using System; +//Json.NET library (http://json.codeplex.com/) +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Net; +using System.IO; + +// MT skins updater for the u_skins mod +// Creator: Krock +// License: zlib (http://www.zlib.net/zlib_license.html) +namespace MT_skins_updater { + class Program { + static void Main(string[] args) { + Console.WriteLine("Welcome to the MT skins updater!"); + Console.WriteLine("# Created by: Krock (2014-07-10)"); + Engine e = new Engine(); + Console.WriteLine(@"Path to the u_skins mod: (ex. 'E:\Minetest\mods\u_skinsdb\u_skins\')"); + string path = Console.ReadLine(); + Console.WriteLine("Start updating at page: ('0' to update everything)"); + int page = getInt(Console.ReadLine()); + e.Start(path, page); + Console.WriteLine("Press any key to exit."); + Console.ReadKey(false); + } + public static int getInt(string i) { + int ret = 0; + int.TryParse(i, out ret); + return (ret > 0)? ret : 0; + } + } + class Engine { + string root = "http://minetest.fensta.bplaced.net"; + bool alternate = true; //should it use the special version of medadata saving? + + public void Start(string path, int page) { + if (path.Length < 5) { + Console.WriteLine("Too short path. STOP."); + return; + } + if (path[path.Length - 1] != '\\') { + path += '\\'; + } + if(!Directory.Exists(path + "meta")){ + Console.WriteLine("Folder 'meta' not found. STOP."); + return; + } + if(!Directory.Exists(path + "textures")){ + Console.WriteLine("Folder 'textures' not found. STOP."); + return; + } + WebClient cli = new WebClient(); + //add useragent to identify + cli.Headers.Add("User-Agent", "MT_skin_grabber 1.1"); + + bool firstSkin = true; + List skin_local = new List(); + int pages = page, + updated = 0; + + for (; page <= pages; page++) { + string contents = ""; + try { + contents = cli.DownloadString(root + "/api/get.json.php?getlist&page=" + page); + } catch(WebException e) { + Console.WriteLine("Whoops! Error at page ID: " + page + ". WebClient sais: " + e.Message); + Console.WriteLine("Press any key to skip this page."); + Console.ReadKey(false); + continue; + } + Data o = JsonConvert.DeserializeObject(contents); + if (o.pages != pages) { + pages = o.pages; + } + + Console.WriteLine("# Page " + page + " (" + o.per_page + " skins)"); + for (int i = 0; i < o.skins.Length; i++) { + int id = o.skins[i].id; + if(o.skins[i].type != "image/png"){ + Console.WriteLine("Image type '" + o.skins[i].type + "' not supported at skin ID: " + id); + Console.WriteLine("Press any key to continue."); + Console.ReadKey(false); + continue; + } + //eliminate special chars! + o.skins[i].name = WebUtility.HtmlDecode(o.skins[i].name); + o.skins[i].author = WebUtility.HtmlDecode(o.skins[i].author); + + //to delete old, removed skins + if (firstSkin) { + firstSkin = false; + + string[] files = Directory.GetFiles(path + "textures\\"); + for (int f = 0; f < files.Length; f++) { + string[] filePath = stringSplitLast(files[f], '\\'), + fileName = stringSplitLast(filePath[1], '.'), + fileVer = stringSplitLast(fileName[0], '_'); + if (fileVer[1] == "" || fileVer[0] != "character") continue; + + int skinNr = Program.getInt(fileVer[1]); + if (skinNr <= id) continue; + skin_local.Add(fileName[0]); + } + } else skin_local.Remove("character_" + id); + + //get file size, only override changed + FileInfo localImg = new FileInfo(path + "textures\\character_" + id + ".png"); + byte[] imageData = Convert.FromBase64String(o.skins[i].img); + bool isDif = true; + if (localImg.Exists) isDif = (Math.Abs(imageData.Length - localImg.Length) >= 3); + + if (isDif) { + File.WriteAllBytes(localImg.FullName, imageData); + imageData = null; + //previews + try { + cli.DownloadFile(root + "/skins/1/" + id + ".png", path + "textures\\character_" + id + "_preview.png"); + } catch (WebException e) { + Console.WriteLine("Whoops! Error at skin ID: " + id + ". WebClient sais: " + e.Message); + Console.WriteLine("Press any key to continue."); + Console.ReadKey(false); + } + } else { + Console.WriteLine("[SKIP] character_" + id); + continue; + } + + string meta = ""; + if (!alternate) { + meta = "name = \"" + o.skins[i].name + "\",\n"; + meta += "author = \"" + o.skins[i].author + "\",\n"; + meta += "comment = \"" + o.skins[i].license + '"'; + } else { + meta = o.skins[i].name + '\n' + o.skins[i].author + '\n' + o.skins[i].license; + } + File.WriteAllText(path + "meta\\character_" + id + ".txt", meta); + updated++; + Console.WriteLine("[" + id + "] " + shorten(o.skins[i].name, 20) + "\t by: " + o.skins[i].author + "\t (" + o.skins[i].license + ")"); + } + } + foreach (string fileName in skin_local) { + if(File.Exists(path + "textures\\" + fileName + ".png")) { + File.Delete(path + "textures\\" + fileName + ".png"); + } + if(File.Exists(path + "textures\\" + fileName + "_preview.png")) { + File.Delete(path + "textures\\" + fileName + "_preview.png"); + } + if(File.Exists(path + "meta\\" + fileName + ".txt")) { + File.Delete(path + "meta\\" + fileName + ".txt"); + } + Console.WriteLine("[DEL] " + fileName + " (deleted skin)"); + } + Console.WriteLine("Done. Updated " + updated + " skins!"); + } + string shorten(string inp, int len) { + char[] shr = new char[len]; + for (int i = 0; i < len; i++) { + if (i < inp.Length) { + shr[i] = inp[i]; + } else shr[i] = ' '; + } + return new string(shr); + } + + string[] stringSplitLast(string path, char limiter) { + int found = 0; + int totalLen = path.Length - 1; + for (int i = totalLen; i >= 0; i--) { + if (path[i] == limiter) { + found = i; + break; + } + } + if (found == 0) { + return new string[] { "", "" }; + } + + int len = totalLen - found; + char[] str_1 = new char[found], + str_2 = new char[len]; + + for (int i = 0; i < path.Length; i++) { + if (i == found) continue; + if (i < found) { + str_1[i] = path[i]; + } else { + str_2[i - found - 1] = path[i]; + } + } + return new string[] { new string(str_1), new string(str_2) }; + } + } + class Data { + public Skins_data[] skins; + public int page, pages, per_page; + } + class Skins_data { + public string name, author, uploaded, type, license, img; + public int id, license_id; + } +}