Пример #1
0
        /// <summary>
        /// Replace strings with the device dependent ones.
        /// </summary>
        /// <param name="zip">ZipFile, which contains the Lua file.</param>
        /// <param name="player">Device, for which we would change the strings.</param>
        /// <returns>The updated Lua code.</returns>
		public string UpdateLua ( ZipFile zip, Player player)
		{
			// 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
			// This time we know, that the Lua file is ok, so we didn't ceare about errors
			TokenReader tr = null;
			tr = lexer.Lex ( luaCode );
			// Go to the beginning of the token stream
			tr.p = 0;

			// Now replace all strings with the right special character strings
			foreach ( Token t in tr.tokens )
				if ( t.Type == TokenType.DoubleQuoteString || t.Type == TokenType.LongString || t.Type == TokenType.SingleQuoteString )
					t.Data = player.ConvertString ( t.Data );

			// Now create the Lua file again
			StringBuilder result = new StringBuilder ( luaCode.Length );

            for (int i = 0; i < tr.tokens.Count - 3;i++ )
            {
                if (tr.tokens[i].Leading.Count > 0)
                    foreach (Token lt in tr.tokens[i].Leading)
                        result.Append(lt.Data);
                switch (tr.tokens[i].Type)
                {
                    case TokenType.DoubleQuoteString:
                        result.AppendFormat("\"{0}\"", tr.tokens[i].Data);
                        break;
                    case TokenType.LongString:
                        result.Append(tr.tokens[i].Data);
                        break;
                    case TokenType.SingleQuoteString:
                        result.AppendFormat("\'{0}\'", tr.tokens[i].Data);
                        break;
                    case TokenType.EndOfStream:
                        break;
                    default:
                        result.Append(tr.tokens[i].Data);
                        break;
                }
            }

            result.Append("\n\n");

            // If there are code, we should insert for this device, we do this now
            if (player.HasCode())
            {
                string code = player.GetCode(tr.tokens[tr.tokens.Count - 2].Data);
                if (code != "")
                    result.Append(code);
            }

            // If there is a library, we should insert, we do it now

            // Append "return cartridge" at the end
            result.Append("\n\n");
            result.Append(tr.tokens[tr.tokens.Count - 3].Data);
            result.Append(" ");
            result.Append(tr.tokens[tr.tokens.Count - 2].Data);

			return result.ToString ();
		}
Пример #2
0
        /// <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;
        }