public void Check() { // Is there a valid input stream if (_stream == null) throw new FileNotFoundException("No valid file"); // Any compilation errors of the Lua file _stream.Position = 0; LUA.Check(_stream, _luaFileName); // Extract cartridge data from Lua file _stream.Position = 0; cartridge = LUA.Extract(_stream); // Save Lua file name for later use cartridge.LuaFileName = _luaFileName; // All media files should be in the same directory as the Lua file string path = Path.GetDirectoryName(_luaFileName); // Now check, if all media resources files exist foreach(Media media in cartridge.Medias) { foreach(MediaResource resource in media.Resources) { // Check, if filename is in list of files if (!File.Exists(Path.Combine(path, resource.Filename))) throw new FileNotFoundException("Folder don't contain file", resource.Filename); } } // Now all is checked without any problems // So it seams, that this folder is valid }
/// <summary> /// Converts the Cartridge object in a format valid for the given engine. /// </summary> /// <remarks> /// - Convert Lua code /// - Convert strings in special format and insert any special code /// - Convert medias /// </remarks> /// <returns>Cartridge object in for this engine correct format.</returns> /// <param name="cartridge">Cartridge object to convert.</param> public Cartridge ConvertCartridge(Cartridge cartridge) { foreach(Media m in cartridge.Medias) m.Resource = ConvertMedia(m); return cartridge; }
/// <summary> /// Converts the Cartridge object in a format valid for the given engine. /// </summary> /// <remarks> /// - Convert Lua code /// - Convert strings in special format and insert any special code /// - Convert medias /// </remarks> /// <returns>Cartridge object in for this engine correct format.</returns> /// <param name="cartridge">Cartridge object to convert.</param> public Cartridge ConvertCartridge(Cartridge cartridge) { foreach (Media m in cartridge.Medias) { m.Resource = ConvertMedia(m); } return(cartridge); }
public void Check() { // Is there a valid input stream if (_stream == null) throw new FileNotFoundException("No valid file"); // Now read gwz file and save for later use _zip = ZipFile.Read(_stream); if (_zip == null) throw new FileLoadException("No valid gwz file"); foreach(ZipEntry zipEntry in _zip.Entries) { switch(Path.GetExtension(zipEntry.FileName).ToLower()) { case ".lua": _luaFile = zipEntry; _luaFiles += 1; break; } } // Is there a Lua file? if (_luaFile == null) throw new FileNotFoundException("No valid Lua file found"); // Is there more than one Lua file if (_luaFiles > 1) throw new FileLoadException("More than one Lua file found"); // Any compilation errors of the Lua file LUA.Check(_zip[_luaFile.FileName].OpenReader(), _luaFile.FileName); // Extract cartridge data from Lua file cartridge = LUA.Extract(_zip[_luaFile.FileName].OpenReader()); // Save Lua file name for later use cartridge.LuaFileName = _luaFile.FileName; // Now check, if all media resources files exist foreach(Media media in cartridge.Medias) { foreach(MediaResource resource in media.Resources) { // Check, if filename is in list of files if (!_zip.EntryFileNames.Contains(resource.Filename)) { if (string.IsNullOrWhiteSpace(resource.Filename)) throw new FileNotFoundException("The Lua file is referencing a file without a filename"); else throw new FileNotFoundException(String.Format("The GWZ is missing a file referred to by the cartridge's code. The file name is: {0}", resource.Filename)); } } } // Now all is checked without any problems // So it seams, that this GWZ file is valid }
/// <summary> /// Compiler entry for online compilation. /// </summary> /// <param name="ifs">Stream of the input file.</param> /// <param name="device">Device.</param> /// <param name="userName">User name.</param> /// <param name="completitionCode">Completition code.</param> public static MemoryStream Download(Stream ifs, DeviceType device = DeviceType.Emulator, string userName = "******", string completitionCode = "1234567890ABCDE") { // ---------- Check device ---------- // ---------- Create GWZ file only (required for upload and download of GWZ file) ---------- // Create object für reading input file (could be also any other format implementing IInput) var inputFormat = new GWZ(ifs); // ---------- Check GWZ file (only required for upload of GWZ file) ---------- // Check gwz file for errors (Lua code and all files included) // Now there shouldn't be any errors, because files on the server are checked. inputFormat.Check(); // ---------- Load cartridge from GWZ file (required when downloading cartridge) ---------- // Load Lua code and extract all required data Cartridge cartridge = inputFormat.Load(); // ---------- Convert cartridge for engine ---------- // Create selected player IEngine engine = CreateEngine(device); // Convert Lua code and insert special code for this player cartridge = engine.ConvertCartridge(cartridge); userName = engine.ConvertString(userName); // Now we can close the input, because we don't require it anymore ifs.Close(); // ---------- Compile Lua code into binary chunk ---------- // Compile Lua code cartridge.Chunk = LUA.Compile(cartridge.LuaCode, cartridge.LuaFileName); // ---------- Save cartridge as GWC file ---------- // Create object for output format (could be also WFC or any other IOutput) var outputFormat = new GWC(); // Write output file try { // Create output in correct format var ms = outputFormat.Create(cartridge, userName, 0, completitionCode); return(ms); } catch (Exception e) { Console.WriteLine(e.Message); return(null); } }
/// <summary> /// Converts the Cartridge object in a format valid for the given engine. /// </summary> /// <remarks> /// - Convert Lua code /// - Convert strings in special format and insert any special code /// - Convert medias /// </remarks> /// <returns>Cartridge object in for this engine correct format.</returns> /// <param name="cartridge">Cartridge object to convert.</param> public Cartridge ConvertCartridge(Cartridge cartridge) { cartridge.Activity = ConvertString(cartridge.Activity); cartridge.Name = ConvertString(cartridge.Name); cartridge.Description = ConvertString(cartridge.Description); cartridge.StartingLocationDescription = ConvertString(cartridge.StartingLocationDescription); cartridge.Author = ConvertString(cartridge.Author); cartridge.Company = ConvertString(cartridge.Company); cartridge.TargetDevice = ConvertString(cartridge.TargetDevice); foreach (Media m in cartridge.Medias) { m.Resource = ConvertMedia(m); } cartridge.LuaCode = ConvertCode(cartridge.LuaCode, cartridge.Variable); return(cartridge); }
public Cartridge Load() { if (cartridge == null) // Extract cartridge data from Lua file cartridge = LUA.Extract(_stream); // All media files should be in the same directory as the Lua file string path = Path.GetDirectoryName(_luaFileName); // Retrive input streams for medias foreach(Media media in cartridge.Medias) { foreach(MediaResource r in media.Resources) { // Load data of file into byte array var br = new BinaryReader(new FileStream(Path.Combine(path, r.Filename), FileMode.Open)); r.Data = new byte[br.BaseStream.Length]; r.Data = br.ReadBytes(r.Data.Length); br = null; } } return cartridge; }
public void Check() { // Is there a valid input stream if (_stream == null) { throw new FileNotFoundException("No valid file"); } // Any compilation errors of the Lua file _stream.Position = 0; LUA.Check(_stream, _luaFileName); // Extract cartridge data from Lua file _stream.Position = 0; cartridge = LUA.Extract(_stream); // Save Lua file name for later use cartridge.LuaFileName = _luaFileName; // All media files should be in the same directory as the Lua file string path = Path.GetDirectoryName(_luaFileName); // Now check, if all media resources files exist foreach (Media media in cartridge.Medias) { foreach (MediaResource resource in media.Resources) { // Check, if filename is in list of files if (!File.Exists(Path.Combine(path, resource.Filename))) { throw new FileNotFoundException("Folder don't contain file", resource.Filename); } } } // Now all is checked without any problems // So it seams, that this folder is valid }
/// <summary> /// Extract cartridge data from the given specified luaCode in given string. /// </summary> /// <param name="luaCode">String with Lua code.</param> public static Cartridge Extract(string luaCode) { LuaTable ltMedia = null; LuaTable ltIcon = null; // Create Lua runtime LuaRuntime luaState = new Eluant.LuaRuntime (); // Load Wherigo.lua var wigInternal = new WIGInternalImpl(luaState); // Run Lua var cart = (LuaTable)((LuaVararg)luaState.DoString(luaCode, "Cartridge"))[0]; if (cart == null) throw new ArgumentNullException("ZCartridge"); // Get table for all ZObjects var objs = (LuaTable)cart["AllZObjects"]; if (objs == null) throw new ArgumentException("AllZObjects"); // Get all relevant data for cartridge Cartridge result = new Cartridge(); // Now we check the Lua code for old newlines like <BR>\n or long strings with only a \n as content // All this should replaced by normal \n newlines result.LuaCode = ConvertToPlain(luaCode); // Extract variable for cartridge var regex = new Regex(@"return\s*([_0-9a-zA-Z]*)\s*$", RegexOptions.Singleline & RegexOptions.IgnoreCase); var match = regex.Match(luaCode); if (match.Success) result.Variable = match.Groups[1].Value; result.Id = (LuaString)cart["Id"]; result.Name = cart["Name"].ToString(); result.Description = cart["Description"].ToString(); result.Activity = cart["Activity"].ToString(); result.StartingLocationDescription = cart["StartingLocationDescription"].ToString(); LuaTable zp = cart["StartingLocation"] is LuaBoolean ? null : (LuaTable)cart["StartingLocation"]; result.Latitude = zp == null ? 0 : (double)((LuaNumber)zp["latitude"]).ToNumber(); result.Longitude = zp == null ? 0 : (double)((LuaNumber)zp["longitude"]).ToNumber(); result.Altitude = zp == null ? 0 : (cart["StartingLocation"] is LuaBoolean ? 0 : (double)((LuaNumber)((LuaTable)zp["altitude"])["value"]).ToNumber()); result.Version = cart["Version"].ToString(); result.Company = cart["Company"].ToString(); result.Author = cart["Author"].ToString(); result.BuilderVersion = cart["BuilderVersion"].ToString(); result.CreateDate = cart["CreateDate"].ToString(); result.PublishDate = cart["PublishDate"].ToString(); result.UpdateDate = cart["UpdateDate"].ToString(); result.LastPlayedDate = cart["LastPlayedDate"].ToString(); result.TargetDevice = cart["TargetDevice"].ToString(); result.TargetDeviceVersion = cart["TargetDeviceVersion"].ToString(); result.StateId = cart["StateId"].ToString(); result.CountryId = cart["CountryId"].ToString(); result.Visible = ((LuaBoolean)cart["Visible"]).ToBoolean(); result.Complete = ((LuaBoolean)cart["Complete"]).ToBoolean(); result.UseLogging = ((LuaBoolean)cart["UseLogging"]).ToBoolean(); ltMedia = (cart["Media"] is LuaBoolean || cart["Media"] is LuaNil) ? null : (LuaTable)cart["Media"]; ltIcon = (cart["Icon"] is LuaBoolean || cart["Icon"] is LuaNil) ? null : (LuaTable)cart["Icon"]; // Check for medias of cartridge var table = (LuaTable)luaState.Globals["table"]; var contains = (LuaFunction)table["Contains"]; var p = contains.Call(cart["AllZObjects"], ltMedia); if (p[0] is LuaBoolean && p[0].ToBoolean()) result.Poster = p[1] is LuaNumber ? (int)((LuaNumber)p[1]) : -1; else result.Poster = -1; var i = contains.Call(cart["AllZObjects"], ltIcon); if (i[0] is LuaBoolean && i[0].ToBoolean()) result.Icon = i[1] is LuaNumber ? (int)((LuaNumber)i[1]) : -1; else result.Icon = -1; // Get all other medias foreach(KeyValuePair<LuaValue, LuaValue> pair in objs) { int idx = (int)(LuaNumber)pair.Key; LuaTable obj = ((LuaTable)pair.Value); // Get type of ZObject string className = (LuaString)obj["ClassName"]; string name = (LuaString)obj["Name"]; // Check type of ZObject if (className.Equals("ZMedia")) { Media media = ExtractMedia (obj); result.Medias.Add (media); } } // Get all variable names foreach(KeyValuePair<LuaValue, LuaValue> pair in luaState.Globals) { var k = pair.Key; var v = pair.Value; if (v is LuaTable) { var className = ((LuaTable)v)["ClassName"]; if (className != null && className.ToString().Equals("Zone")) result.Zones.Add(k.ToString()); if (className != null && className.ToString().Equals("ZItem")) result.Items.Add(k.ToString()); if (className != null && className.ToString().Equals("ZCharacter")) { if (!k.ToString().Equals("Player")) result.Characters.Add(k.ToString()); } if (className != null && className.ToString().Equals("ZTimer")) result.Timers.Add(k.ToString()); if (className != null && className.ToString().Equals("ZInput")) result.Inputs.Add(k.ToString()); if (className != null && className.ToString().Equals("ZCartridge")) result.Variable = k.ToString(); } } return result; }
public void Check() { // Is there a valid input stream if (_stream == null) { throw new FileNotFoundException("No valid file"); } // Now read gwz file and save for later use _zip = ZipFile.Read(_stream); if (_zip == null) { throw new FileLoadException("No valid gwz file"); } foreach (ZipEntry zipEntry in _zip.Entries) { switch (Path.GetExtension(zipEntry.FileName).ToLower()) { case ".lua": _luaFile = zipEntry; _luaFiles += 1; break; } } // Is there a Lua file? if (_luaFile == null) { throw new FileNotFoundException("No valid Lua file found"); } // Is there more than one Lua file if (_luaFiles > 1) { throw new FileLoadException("More than one Lua file found"); } // Any compilation errors of the Lua file LUA.Check(_zip[_luaFile.FileName].OpenReader(), _luaFile.FileName); // Extract cartridge data from Lua file cartridge = LUA.Extract(_zip[_luaFile.FileName].OpenReader()); // Save Lua file name for later use cartridge.LuaFileName = _luaFile.FileName; // Now check, if all media resources files exist foreach (Media media in cartridge.Medias) { foreach (MediaResource resource in media.Resources) { // Check, if filename is in list of files if (!_zip.EntryFileNames.Contains(resource.Filename)) { if (string.IsNullOrWhiteSpace(resource.Filename)) { throw new FileNotFoundException("The Lua file is referencing a file without a filename"); } else { throw new FileNotFoundException(String.Format("The GWZ is missing a file referred to by the cartridge's code. The file name is: {0}", resource.Filename)); } } } } // Now all is checked without any problems // So it seams, that this GWZ file is valid }
public MemoryStream Create(Cartridge cartridge, string username, long userId, string completionCode) { // Create memory stream to write gwc file MemoryStream stream = new MemoryStream(); BinaryWriter output = new BinaryWriter(stream); long savePosition; // Write gwc signature output.Write(new byte[7] { 0x02, 0x0a, 0x43, 0x41, 0x52, 0x54, 0x00 }); // Write number of images output.Write(GetShort((short)(cartridge.Medias.Count + 1))); // Write media table for (int i = 0; i <= cartridge.Medias.Count; i++) { output.Write(GetShort((short)i)); output.Write(GetInt((int)0)); } // Write size of header output.Write(GetInt(0)); // Save position, where header starts long startHeader = output.BaseStream.Position; // Write header // Write position output.Write(GetDouble((float)cartridge.Latitude)); output.Write(GetDouble((float)cartridge.Longitude)); output.Write(GetDouble((float)cartridge.Altitude)); // Write creation date // TODO: Replace with creation date string date = cartridge.CreateDate; output.Write(GetLong(0)); // Write poster and icon index output.Write(GetShort((short)cartridge.Poster)); output.Write(GetShort((short)cartridge.Icon)); // Write cartridge type output.Write(GetAscii(cartridge.Activity)); // Write player data output.Write(GetAscii(username)); output.Write(GetLong(userId)); // Write cartridge relevant information output.Write(GetAscii(cartridge.Name)); output.Write(GetAscii(cartridge.Id)); output.Write(GetAscii(cartridge.Description)); output.Write(GetAscii(cartridge.StartingLocationDescription)); output.Write(GetAscii(cartridge.Version)); output.Write(GetAscii(cartridge.Author)); output.Write(GetAscii(cartridge.Company)); output.Write(GetAscii(cartridge.TargetDevice)); // Write CompletionCode length output.Write(GetInt(completionCode.Length + 1)); // Write CompletionCode output.Write(GetAscii(completionCode)); // Save position for later writing savePosition = output.BaseStream.Position; // Goto header length position and save the length output.BaseStream.Position = startHeader - 4; output.Write(GetInt((int)(savePosition - startHeader))); output.BaseStream.Position = savePosition; // Write Lua binary code WriteToMediaTable(output, 0); output.Write(GetInt((int)cartridge.Chunk.Length)); output.Write(cartridge.Chunk); // Now save all media files for (short i = 0; i < cartridge.Medias.Count; i++) { // Write position for media table WriteToMediaTable(output, (short)(i + 1)); // Check media for right entry MediaResource mr = cartridge.Medias[i].Resource; // Save media if (mr == null) { // No valid media file is found in resource list output.Write((byte)0); } else { // Valid file found, so save type, length and bytes output.Write((byte)1); output.Write(GetInt((int)mr.Type)); output.Write(GetInt((int)mr.Data.Length)); output.Write(mr.Data); } } // Go to begining of memory stream stream.Position = 0; return(stream); }
/// <summary> /// Extract cartridge data from the given specified luaCode in given string. /// </summary> /// <param name="luaCode">String with Lua code.</param> public static Cartridge Extract(string luaCode) { LuaTable ltMedia = null; LuaTable ltIcon = null; // Create Lua runtime LuaRuntime luaState = new Eluant.LuaRuntime(); // Load Wherigo.lua var wigInternal = new WIGInternalImpl(luaState); // Run Lua var cart = (LuaTable)((LuaVararg)luaState.DoString(luaCode, "Cartridge"))[0]; if (cart == null) { throw new ArgumentNullException("ZCartridge"); } // Get table for all ZObjects var objs = (LuaTable)cart["AllZObjects"]; if (objs == null) { throw new ArgumentException("AllZObjects"); } // Get all relevant data for cartridge Cartridge result = new Cartridge(); // Now we check the Lua code for old newlines like <BR>\n or long strings with only a \n as content // All this should replaced by normal \n newlines result.LuaCode = ConvertToPlain(luaCode); // Extract variable for cartridge var regex = new Regex(@"return\s*([_0-9a-zA-Z]*)\s*$", RegexOptions.Singleline & RegexOptions.IgnoreCase); var match = regex.Match(luaCode); if (match.Success) { result.Variable = match.Groups[1].Value; } result.Id = (LuaString)cart["Id"]; result.Name = cart["Name"].ToString(); result.Description = cart["Description"].ToString(); result.Activity = cart["Activity"].ToString(); result.StartingLocationDescription = cart["StartingLocationDescription"].ToString(); LuaTable zp = cart["StartingLocation"] is LuaBoolean ? null : (LuaTable)cart["StartingLocation"]; result.Latitude = zp == null ? 0 : (double)((LuaNumber)zp["latitude"]).ToNumber(); result.Longitude = zp == null ? 0 : (double)((LuaNumber)zp["longitude"]).ToNumber(); result.Altitude = zp == null ? 0 : (cart["StartingLocation"] is LuaBoolean ? 0 : (double)((LuaNumber)((LuaTable)zp["altitude"])["value"]).ToNumber()); result.Version = cart["Version"].ToString(); result.Company = cart["Company"].ToString(); result.Author = cart["Author"].ToString(); result.BuilderVersion = cart["BuilderVersion"].ToString(); result.CreateDate = cart["CreateDate"].ToString(); result.PublishDate = cart["PublishDate"].ToString(); result.UpdateDate = cart["UpdateDate"].ToString(); result.LastPlayedDate = cart["LastPlayedDate"].ToString(); result.TargetDevice = cart["TargetDevice"].ToString(); result.TargetDeviceVersion = cart["TargetDeviceVersion"].ToString(); result.StateId = cart["StateId"].ToString(); result.CountryId = cart["CountryId"].ToString(); result.Visible = ((LuaBoolean)cart["Visible"]).ToBoolean(); result.Complete = ((LuaBoolean)cart["Complete"]).ToBoolean(); result.UseLogging = ((LuaBoolean)cart["UseLogging"]).ToBoolean(); ltMedia = (cart["Media"] is LuaBoolean || cart["Media"] is LuaNil) ? null : (LuaTable)cart["Media"]; ltIcon = (cart["Icon"] is LuaBoolean || cart["Icon"] is LuaNil) ? null : (LuaTable)cart["Icon"]; // Check for medias of cartridge var table = (LuaTable)luaState.Globals["table"]; var contains = (LuaFunction)table["Contains"]; var p = contains.Call(cart["AllZObjects"], ltMedia); if (p[0] is LuaBoolean && p[0].ToBoolean()) { result.Poster = p[1] is LuaNumber ? (int)((LuaNumber)p[1]) : -1; } else { result.Poster = -1; } var i = contains.Call(cart["AllZObjects"], ltIcon); if (i[0] is LuaBoolean && i[0].ToBoolean()) { result.Icon = i[1] is LuaNumber ? (int)((LuaNumber)i[1]) : -1; } else { result.Icon = -1; } // Get all other medias foreach (KeyValuePair <LuaValue, LuaValue> pair in objs) { int idx = (int)(LuaNumber)pair.Key; LuaTable obj = ((LuaTable)pair.Value); // Get type of ZObject string className = (LuaString)obj["ClassName"]; string name = (LuaString)obj["Name"]; // Check type of ZObject if (className.Equals("ZMedia")) { Media media = ExtractMedia(obj); result.Medias.Add(media); } } // Get all variable names foreach (KeyValuePair <LuaValue, LuaValue> pair in luaState.Globals) { var k = pair.Key; var v = pair.Value; if (v is LuaTable) { var className = ((LuaTable)v)["ClassName"]; if (className != null && className.ToString().Equals("Zone")) { result.Zones.Add(k.ToString()); } if (className != null && className.ToString().Equals("ZItem")) { result.Items.Add(k.ToString()); } if (className != null && className.ToString().Equals("ZCharacter")) { if (!k.ToString().Equals("Player")) { result.Characters.Add(k.ToString()); } } if (className != null && className.ToString().Equals("ZTimer")) { result.Timers.Add(k.ToString()); } if (className != null && className.ToString().Equals("ZInput")) { result.Inputs.Add(k.ToString()); } if (className != null && className.ToString().Equals("ZCartridge")) { result.Variable = k.ToString(); } } } return(result); }
public Cartridge Load() { // Is there a valid gwz file if (_zip == null) return null; // Is there a valid Lua file if (_luaFile == null) return null; if (cartridge == null) // Extract cartridge data from Lua file cartridge = LUA.Extract(_zip[_luaFile.FileName].OpenReader()); // Retrive input streams for medias foreach(Media media in cartridge.Medias) { foreach(MediaResource r in media.Resources) { // Load data of file into byte array var br = new BinaryReader(_zip[r.Filename].OpenReader()); r.Data = new byte[br.BaseStream.Length]; r.Data = br.ReadBytes(r.Data.Length); br = null; } } return cartridge; }
/// <summary> /// The entry point of the program, where the program control starts and ends when used from command line. /// </summary> /// <param name="args">The command line arguments.</param> public static void Main(string[] args) { var start = DateTime.Now; var device = DeviceType.Unknown; Console.WriteLine("WF.Compiler, Version {0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); Console.WriteLine("Copyright 2014 by Wherigo Foundation"); Console.WriteLine(); string fileInput = null; string fileOutput = null; int userId = 0; string userName = "******"; string completitionCode = "123456789ABCDEF"; int i = 0; while (i < args.Length) { switch (args[i].ToLower()) { case "-d": case "-device": if (i + 1 >= args.Length) { Usage(); return; } string deviceName = args[i + 1].ToLower(); i++; foreach (DeviceType d in Enum.GetValues(typeof(DeviceType))) { if (d.ToString().ToLower() == deviceName) { device = d; } } break; case "-o": case "-output": if (i + 1 >= args.Length) { Usage(); return; } fileOutput = args[i + 1].ToLower(); i++; break; case "-u": case "-username": if (i + 1 >= args.Length) { Usage(); return; } userName = args[i + 1]; i++; break; case "-c": case "-code": if (i + 1 >= args.Length) { Usage(); return; } completitionCode = args[i + 1]; i++; break; default: fileInput = args[i]; break; } i++; } if (fileInput == null) { Usage(); return; } if (!File.Exists(fileInput)) { Usage(); return; } if (fileOutput == null) { fileOutput = Path.ChangeExtension(fileInput, ".gwc"); } Console.WriteLine("Input file: " + fileInput); Console.WriteLine("Output file: " + fileOutput); Console.WriteLine("Device: " + device.ToString()); Console.WriteLine("Username: "******"CompletionCode: " + completitionCode); FileStream ifs = new FileStream(fileInput, FileMode.Open); // ---------- Create GWZ file only (required for upload and download of GWZ file) ---------- // Create object für reading input file (could be also any other format implementing IInput) var inputFormat = new GWZ(ifs); // ---------- Check GWZ file (only required for upload of GWZ file) ---------- // Check gwz file for errors (Lua code and all files included) try { inputFormat.Check(); } catch (CompilerLuaException e) { Console.WriteLine(); Console.WriteLine("Error"); Console.WriteLine(e.Message); Console.WriteLine(); Console.WriteLine("Line {0}: {1}", e.Line - 1, e.CodeBefore); Console.WriteLine("Line {0}: {1}", e.Line, e.Code); Console.WriteLine("Line {0}: {1}", e.Line + 1, e.CodeAfter); return; } catch (Exception e) { Console.WriteLine(); Console.WriteLine("Error"); Console.WriteLine(e.Message); ifs.Close(); return; } // ---------- Load cartridge from GWZ file (required when downloading cartridge) ---------- // Load Lua code and extract all required data Cartridge cartridge = inputFormat.Load(); // ---------- Convert cartridge for engine ---------- // Create selected engine IEngine engine = CreateEngine(device); // Convert Lua code and insert special code for this player cartridge = engine.ConvertCartridge(cartridge); userName = engine.ConvertString(userName); // Now we can close the input, because we don't require it anymore ifs.Close(); // ---------- Compile Lua code into binary chunk ---------- try { // Compile Lua code cartridge.Chunk = LUA.Compile(cartridge.LuaCode, cartridge.LuaFileName); } catch (Exception e) { var t = e.Message; } // ---------- Save cartridge as GWC file ---------- // Create object for output format (could be also WFC or any other IOutput) var outputFormat = new GWC(); // Write output file try { // Create output in correct format var ms = outputFormat.Create(cartridge, userName, userId, completitionCode); // Save output to file using (FileStream ofs = new FileStream(fileOutput, FileMode.Create)) { ms.CopyTo(ofs); // Close output ofs.Flush(); ofs.Close(); } } catch (Exception e) { Console.WriteLine(); Console.WriteLine("Error"); Console.WriteLine(e.Message); return; } Console.WriteLine("Compiletime: {0}", DateTime.Now - start); }
/// <summary> /// Checks the gwz file for: /// - Lua file /// - Info file /// - Lua code for right format /// - Media files for completeness. /// Errors could be found in the list Errors (with line and col, if known). /// </summary> /// <param name='zip'> /// Zip file for later use. /// </param> /// <returns> /// <c>true</c>, if the checked gwz was correct and complete, <c>false</c> otherwise. /// </returns> public bool CheckGWZ ( ZipFile zip, Cartridge cartridge ) { // Get input stream for Lua file string luaCode = getLuaCode(zip,filenameGwz); // Now parse the Lua file Lexer lexer = new Lexer (); // Split the Lua code into tokens TokenReader tr = null; try { tr = lexer.Lex ( luaCode ); } catch ( LuaSourceException e ) { // There are something strange in the Lua file, so that the lexer couldn't create tokens Errors.Add ( new Error ( e.Line, e.Column, e.Message ) ); return false; } // Jump to the first token tr.p = 0; // Save cartridge name for later use (the last is allways End of Stream token) cartridge.Variable = tr.tokens[tr.tokens.Count-2].Data; // Now parse the tokens, if it is all right with the Lua file SharpLua.Parser parser = new SharpLua.Parser ( tr ); SharpLua.Ast.Chunk c = null; try { c = parser.Parse(); } catch ( Exception e ) { // Was there an error? if ( parser.Errors.Count > 0 ) { foreach ( SharpLua.LuaSourceException error in parser.Errors ) Errors.Add ( new Error ( error.Line, error.Column, error.Message ) ); return false; } } // Now we are shure, that Lua code is allright, so we could go on // Create a dictionary, so we could get fast connection variable <-> media list entry Dictionary<String,Media> mediaDict = new Dictionary<String,Media> (); // Go through all statements and search cartridge info and all media definitions for ( int i = 0; i < c.Body.Count; i++ ) { // We only check assignments in the parser result if ( c.Body[i] is AssignmentStatement ) { AssignmentStatement statement = (AssignmentStatement) c.Body[i]; // First get the left side ... Expression statementLeft = statement.Lhs[0]; String left = getExpressionAsString ( statementLeft ); // ... and than the right side Expression statementRight = statement.Rhs[0]; String right = getExpressionAsString ( statementRight ); // Is it an entry for the cartridge if ( left.Contains ( "." ) && cartridge.Variable.Equals ( left.Split ( '.' )[0] ) ) { string key = left.Split ( '.' )[1]; switch ( key ) { case "Id": cartridge.Id = right; break; case "Name": cartridge.Name = right; break; case "Description": cartridge.Description = removeLongString(right); break; case "Activity": cartridge.Activity = right; break; case "StartingLocationDescription": cartridge.StartingLocationDescription = removeLongString(right); break; case "StartingLocation": if (statementRight is SharpLua.Ast.Expression.MemberExpr) { // Play anywhere cartridge with starting location at 360.0 / 360.0 / 360.0 cartridge.Latitude = 360.0; cartridge.Longitude = 360.0; cartridge.Altitude = 360.0; } else getZonePoints ( (SharpLua.Ast.Expression.CallExpr) statementRight, ref cartridge.Latitude, ref cartridge.Longitude, ref cartridge.Altitude ); break; case "Version": cartridge.Version = right; break; case "Company": cartridge.Company = right; break; case "Author": cartridge.Author = right; break; case "BuilderVersion": cartridge.BuilderVersion = right; break; case "CreateDate": cartridge.CreateDate = right; break; case "PublishDate": cartridge.PublishDate = right; break; case "UpdateDate": cartridge.UpdateDate = right; break; case "LastPlayedDate": cartridge.LastPlayedDate = right; break; case "TargetDevice": cartridge.TargetDevice = right; break; case "TargetDeviceVersion": cartridge.TargetDeviceVersion = right; break; case "StateId": cartridge.StateId = right; break; case "CountryId": cartridge.CountryId = right; break; case "Visible": cartridge.Visible = right.Equals ( "true" ) ? true : false; break; case "Complete": cartridge.Complete = right.Equals ( "true" ) ? true : false; break; case "UseLogging": cartridge.UseLogging = right.Equals ( "true" ) ? true : false; break; case "Media": cartridge.Splash = right; break; case "Icon": cartridge.Icon = right; break; } } // Is it a ZMedia definition? if ( right.Equals ( "Wherigo.ZMedia" ) ) { Media media = new Media (); media.Variable = left; cartridge.MediaList.Add ( media ); mediaDict.Add ( left, media ); } // Is it a ZMedia entry? if ( left.Contains ( "." ) && mediaDict.ContainsKey ( left.Split ( '.' )[0] ) ) { // We found an entry to a ZMedia string key = left.Split ( '.' )[0]; string value = left.Split ( '.' )[1]; // Which key did we have found? switch ( value ) { case "Name": mediaDict[key].Name = right; break; case "Description": mediaDict[key].Description = right; break; case "AltText": mediaDict[key].AltText = right; break; case "Id": mediaDict[key].Id = right; break; case "Resources": getMediaResources ( (SharpLua.Ast.Expression.TableConstructorExpr) statementRight, mediaDict[key].Resources ); break; } } } } // Now check, if each media has a file in the gwz foreach ( Media m in cartridge.MediaList ) { foreach ( MediaResource resource in m.Resources ) { if ( !files.Contains ( resource.Filename.ToLower () ) ) { // This filename couldn't be found in the gwz file Errors.Add ( new Error ( 0, 0, "Media file not found: " + resource.Filename ) ); } } } // If there are no errors, than return true return Errors.Count == 0; }
/// <summary> /// Converts the Cartridge object in a format valid for the given engine. /// </summary> /// <remarks> /// - Convert Lua code /// - Convert strings in special format and insert any special code /// - Convert medias /// </remarks> /// <returns>Cartridge object in for this engine correct format.</returns> /// <param name="cartridge">Cartridge object to convert.</param> public Cartridge ConvertCartridge(Cartridge cartridge) { cartridge.Activity = ConvertString(cartridge.Activity); cartridge.Name = ConvertString(cartridge.Name); cartridge.Description = ConvertString(cartridge.Description); cartridge.StartingLocationDescription = ConvertString(cartridge.StartingLocationDescription); cartridge.Author = ConvertString(cartridge.Author); cartridge.Company = ConvertString(cartridge.Company); cartridge.TargetDevice = ConvertString(cartridge.TargetDevice); foreach(Media m in cartridge.Medias) m.Resource = ConvertMedia(m); string luaCode = cartridge.LuaCode; // Now make special operations with the source code for different builders if (Builders.IsUrwigo(cartridge.LuaCode)) { luaCode = ReplaceSpecialCharacters(luaCode); } cartridge.LuaCode = ConvertCode(luaCode, cartridge.Variable); return cartridge; }
public MemoryStream Create (Cartridge cartridge, string username, long userId, string completionCode) { // Create memory stream to write gwc file MemoryStream stream = new MemoryStream(); BinaryWriter output = new BinaryWriter(stream); long savePosition; // Write gwc signature output.Write(new byte[7] { 0x02, 0x0a, 0x43, 0x41, 0x52, 0x54, 0x00 }); // Write number of images output.Write(GetShort((short)(cartridge.Medias.Count+1))); // Write media table for (int i = 0; i <= cartridge.Medias.Count; i++) { output.Write(GetShort((short)i)); output.Write(GetInt((int)0)); } // Write size of header output.Write(GetInt(0)); // Save position, where header starts long startHeader = output.BaseStream.Position; // Write header // Write position output.Write(GetDouble((float) cartridge.Latitude)); output.Write(GetDouble((float) cartridge.Longitude)); output.Write(GetDouble((float) cartridge.Altitude)); // Write creation date // TODO: Replace with creation date string date = cartridge.CreateDate; output.Write(GetLong(0)); // Write poster and icon index output.Write(GetShort((short)cartridge.Poster)); output.Write(GetShort((short)cartridge.Icon)); // Write cartridge type output.Write(GetAscii(cartridge.Activity)); // Write player data output.Write(GetAscii(username)); output.Write(GetLong(userId)); // Write cartridge relevant information output.Write(GetAscii(cartridge.Name)); output.Write(GetAscii(cartridge.Id)); output.Write(GetAscii(cartridge.Description)); output.Write(GetAscii(cartridge.StartingLocationDescription)); output.Write(GetAscii(cartridge.Version)); output.Write(GetAscii(cartridge.Author)); output.Write(GetAscii(cartridge.Company)); output.Write(GetAscii(cartridge.TargetDevice)); // Write CompletionCode length output.Write(GetInt(completionCode.Length + 1)); // Write CompletionCode output.Write(GetAscii(completionCode)); // Save position for later writing savePosition = output.BaseStream.Position; // Goto header length position and save the length output.BaseStream.Position = startHeader - 4; output.Write(GetInt((int) (savePosition - startHeader))); output.BaseStream.Position = savePosition; // Write Lua binary code WriteToMediaTable(output, 0); output.Write(GetInt((int)cartridge.Chunk.Length)); output.Write(cartridge.Chunk); // Now save all media files for (short i = 0; i < cartridge.Medias.Count; i++) { // Write position for media table WriteToMediaTable(output, (short)(i + 1)); // Check media for right entry MediaResource mr = cartridge.Medias[i].Resource; // Save media if (mr == null) { // No valid media file is found in resource list output.Write((byte) 0); } else { // Valid file found, so save type, length and bytes output.Write((byte) 1); output.Write(GetInt((int)mr.Type)); output.Write(GetInt((int)mr.Data.Length)); output.Write(mr.Data); } } // Go to begining of memory stream stream.Position = 0; return stream; }
/// <summary> /// Compile the file filename for device and place user and completionCode into the resulting gwc file /// </summary> /// <param name="filename">Filename of the gwz file with path.</param> /// <param name="device">Name of the device for which the resulting gwc is compiled.</param> /// <param name="username">Username, which is wrote to gwc file and later used as Player.Name.</param> /// <param name="userid">User ID from Groundspeak, which is wrote to gwc file.</param> /// <param name="completionCode">CompletionCode, which is wrote to gwc file and later used as Player.CompletionCode.</param> /// <returns>Memory stream with the gwc file.</returns> public MemoryStream Compile(string filename, DeviceType device, string username = "", long userid = 0, string completionCode = "") { // Create object for player specific code Player player = new Player(device); // Create parser with filename Parser parser = new Parser(filename); // Open gwz for later use ZipFile zip = new ZipFile(parser.FilenameGwz); // Create object for all data belonging to the cartridge Cartridge cartridge = new Cartridge (); // Check, if the gwz file has the right format if (!parser.CheckGWZ(zip, cartridge)) { // Error in parsing gwz file throw new InvalidOperationException(String.Format("Line {0}, Column {1}: {2}", parser.Errors[0].Line, parser.Errors[0].Column, parser.Errors[0].Message)); } // Create LuaInterface LuaInterface lua = new LuaInterface(); string luaCode; // Create new Lua file with player specific characters and all other stuff luaCode = parser.UpdateLua(zip,player); // Only for debug reasons // saveLuaCode(luaCode); // Now we have a string with the Lua code, which have the right coding // So go on and compile the Lua code // LoadString of Lua code = compile Lua code LuaFunction func = lua.LoadString(luaCode, cartridge.Name); // Dump Lua code to memory stream, so we could later save it to gwc file MemoryStream luaBinary = new MemoryStream(); dumpCode(lua.LuaState,luaBinary); // Create memory stream to write gwc file MemoryStream stream = new MemoryStream(); BinaryWriter output = new BinaryWriter(stream); long savePosition; // Write gwc signature output.Write(new byte[7] { 0x02, 0x0a, 0x43, 0x41, 0x52, 0x54, 0x00 }); // Write number of images output.Write(getShort((short)(cartridge.MediaList.Count+1))); // Write media table for (int i = 0; i <= cartridge.MediaList.Count; i++) { output.Write(getShort((short)i)); output.Write(getInt((int)0)); } // Write size of header output.Write(getInt(0)); // Save position, where header starts long startHeader = output.BaseStream.Position; // Write header // Write position output.Write(getDouble((float) cartridge.Latitude)); output.Write(getDouble((float) cartridge.Longitude)); output.Write(getDouble((float) cartridge.Altitude)); // Write creation date // TODO: Replace with creation date string date = cartridge.CreateDate; output.Write(getLong(0)); // Write media index short splash = -1; for (int i = 0; i < cartridge.MediaList.Count; i++) if (cartridge.Splash != null && cartridge.Splash.Equals(cartridge.MediaList[i].Variable)) splash = (short)(i + 1); output.Write(getShort(splash)); // Write icon index short icon = -1; for (int i = 0; i < cartridge.MediaList.Count; i++) if (cartridge.Icon != null && cartridge.Icon.Equals(cartridge.MediaList[i].Variable)) icon = (short)(i + 1); output.Write(getShort(icon)); // Write cartridge type output.Write(getAscii(player.ConvertGWCString(cartridge.Activity))); // Write player data output.Write(getAscii(player.ConvertGWCString(username))); output.Write(getLong(userid)); // Write cartridge relevant information output.Write(getAscii(player.ConvertGWCString(cartridge.Name))); output.Write(getAscii(cartridge.Id)); output.Write(getAscii(player.ConvertGWCString(cartridge.Description))); output.Write(getAscii(player.ConvertGWCString(cartridge.StartingLocationDescription))); output.Write(getAscii(cartridge.Version)); output.Write(getAscii(player.ConvertGWCString(cartridge.Author))); output.Write(getAscii(player.ConvertGWCString(cartridge.Company))); output.Write(getAscii(player.ConvertGWCString(cartridge.TargetDevice))); // Write CompletionCode length output.Write(getInt(completionCode.Length+1)); // Write CompletionCode output.Write(getAscii(completionCode)); // Save position for later writing savePosition = output.BaseStream.Position; // Goto header length position and save the length output.BaseStream.Position = startHeader - 4; output.Write(getInt((int) (savePosition - startHeader))); output.BaseStream.Position = savePosition; // Write Lua binary code writeToMediaTable(output,0); output.Write(getInt((int)luaBinary.Length)); output.Write(luaBinary.ToArray()); // Now save all media files for (short i = 0; i < cartridge.MediaList.Count; i++) { // Write position for media table writeToMediaTable(output, (short)(i+1)); // Check media for right entry cartridge.MediaList[i].Entry = player.CheckMedia(cartridge.MediaList[i]); // Save media if (cartridge.MediaList[i].Entry == -1) { // No valid media file is found in resource list output.Write((byte) 0); } else { // Valid file found, so save type, length and bytes output.Write((byte) 1); output.Write(getInt(cartridge.MediaList[i].MediaType)); byte[] media = cartridge.MediaList[i].GetMediaAsByteArray(zip); output.Write(getInt(media.Length)); output.Write(media); } } return stream; }
/// <summary> /// Converts the Cartridge object in a format valid for the given engine. /// </summary> /// <remarks> /// - Convert Lua code /// - Convert strings in special format and insert any special code /// - Convert medias /// </remarks> /// <returns>Cartridge object in for this engine correct format.</returns> /// <param name="cartridge">Cartridge object to convert.</param> public Cartridge ConvertCartridge(Cartridge cartridge) { cartridge.Activity = ConvertString(cartridge.Activity); cartridge.Name = ConvertString(cartridge.Name); cartridge.Description = ConvertString(cartridge.Description); cartridge.StartingLocationDescription = ConvertString(cartridge.StartingLocationDescription); cartridge.Author = ConvertString(cartridge.Author); cartridge.Company = ConvertString(cartridge.Company); cartridge.TargetDevice = ConvertString(cartridge.TargetDevice); foreach(Media m in cartridge.Medias) m.Resource = ConvertMedia(m); cartridge.LuaCode = ConvertCode(cartridge.LuaCode, cartridge.Variable); return cartridge; }