Exemple #1
0
        public static BinaryMap Decode(string gameToken, byte[] bytes)
        {
            tokens = new BinaryTokens("eu4bin.csv");
            map = new BinaryMap(bytes.Length, tokens);
            raw = bytes;
            map.AddString(ANSI.GetString(raw, 0, 6), false);
            int i = 6;

            SpecialCode specialcode = SpecialCode.None;

            SpecialCode type = SpecialCode.None;
            string handler = "";
            bool quoted = false;
            bool? list = null;

            bool oneLineInheritance = false;

            BinaryToken code = null;
            BinaryToken inheritedCode = null;

            while (i < raw.Length - 1)
            {

                // 1. Check for a special code first
                specialcode = GetSpecialCode(i);

                if (specialcode != 0)
                {
                    if ((int)specialcode < 4) // brace or equals sign
                    {
                        ReadSpecial(ref i);
                        // Right-brace sign clears current inheritance.
                        if (specialcode == SpecialCode.RightBrace)
                        {
                            inheritedCode = null;
                            type = SpecialCode.None;
                            handler = "";
                            quoted = false;
                            list = null;
                        }
                        continue;
                    }
                    else
                    {
                        // If there is attempt to redefine inherited properties, ignore it and read regardless.
                        if (inheritedCode == null)
                        {
                            type = specialcode;
                        }

                        // Now interpret the special code.
                        i += 2;
                        switch (type)
                        {
                            case SpecialCode.String: ReadString(ref i, quoted); continue;
                            case SpecialCode.Integer: ReadInteger(ref i); continue;
                            case SpecialCode.Float: ReadFloat(ref i); continue;
                            case SpecialCode.Float5: ReadFloat5(ref i); continue;
                            case SpecialCode.Boolean: ReadBoolean(ref i); continue;
                            case SpecialCode.Date: ReadDate(ref i, false); continue; // never quoted in practice
                            default: break;
                        }
                        continue;
                    }

                }

                // 2. No special code encountered, we are looking for a token now

                code = tokens.TryGetCode(raw[i], raw[i + 1]); // from little-endian code

                // If the token does not match anything, try to continue to read data in the same format as previously.
                if (code == null)
                {
                    // Maybe it is an unknown token
                    SpecialCode sc1 = GetSpecialCode(i - 2);
                    SpecialCode sc2 = GetSpecialCode(i + 2);
                    if (sc1 == SpecialCode.Equals || sc2 == SpecialCode.Equals)
                    {
                        map.AddToken("UNKNOWN_" + GetHexString(i));
                        i += 2;
                        if (TryAddSpecials(ref i)) continue;
                        TryReadTypeDefinition(ref i, ref type);
                    }

                    switch (type)
                    {
                        case SpecialCode.String: ReadString(ref i, quoted); continue;
                        case SpecialCode.Integer: ReadInteger(ref i); continue;
                        case SpecialCode.Float: ReadFloat(ref i); continue;
                        case SpecialCode.Float5: ReadFloat5(ref i); continue;
                        case SpecialCode.Boolean: ReadBoolean(ref i); continue;
                        case SpecialCode.Date: ReadDate(ref i, quoted); continue;
                        default: break;
                    }
                    i += 2;
                    continue;
                }

                // 3. We have found the token

                // Tackle inheritance: if it is on for a given token, enforce properties until the next right-brace sign.
                if (code.InheritType)
                {
                    inheritedCode = code;
                    type = inheritedCode.DataType;
                    handler = inheritedCode.Text;
                    quoted = inheritedCode.Quoted;
                    list = inheritedCode.List;
                    oneLineInheritance = true;
                }
                // If no inheritance, read properties from the current token.
                else if (inheritedCode == null)
                {
                    type = code.DataType;
                    handler = code.Text;
                    quoted = code.Quoted;
                    list = code.List;
                }

                if (type == SpecialCode.Variable) // variable
                {
                    // Get parent token
                    string[] parents = map.GetParents();
                    InterpretCode(gameToken, handler, ref map, ref i, ref type, ref quoted, parents);
                    continue;
                }
                else
                {
                    map.AddToken(code.Text);
                    i += 2;
                    if (TryAddSpecials(ref i))
                    {
                        oneLineInheritance = false;
                        continue;
                    }
                    if (oneLineInheritance) inheritedCode = null;
                    TryReadTypeDefinition(ref i, ref type);
                    switch (type)
                    {
                        case SpecialCode.String: ReadString(ref i, quoted); continue;
                        case SpecialCode.Integer: ReadInteger(ref i); continue;
                        case SpecialCode.Float: ReadFloat(ref i); continue;
                        case SpecialCode.Float5: ReadFloat5(ref i); continue;
                        case SpecialCode.Boolean: ReadBoolean(ref i); continue;
                        case SpecialCode.Date: ReadDate(ref i, quoted); continue;
                        default: continue; // map.AddAttribToken(i); break;
                    }
                }
            }

            map.Finish();
            return map;
        }
Exemple #2
0
        private static void InterpretCode(string gameToken, string text, ref BinaryMap map, ref int i, ref SpecialCode type, ref bool quoted, string[] parents)
        {
            if (gameToken == "eu4")
            {
                switch (text)
                {
                    case "type":
                        map.AddToken(text);
                        i += 2;
                        if (TryAddSpecials(ref i)) break;
                        TryReadTypeDefinition(ref i, ref type);

                        if (IsParent(parents, 1, "id") ||
                            IsParent(parents, 1, "leader") ||
                            (IsParent(parents, 1, "rebel_faction") && IsParent(parents, -1, "provinces")) ||
                            (IsParent(parents, 1, "advisor") && IsParent(parents, -1, "active_advisors")) ||
                            IsParent(parents, 1, "monarch"))
                        {
                            ReadInteger(ref i);
                        }
                        else if ((IsParent(parents, 1, "advisor") && IsParent(parents, 3, "history")) ||
                                 (IsParent(parents, 1, "advisor") && IsParent(parents, 2, "history")))
                        {
                            ReadString(ref i, false);
                        }
                        else if (IsParent(parents, 1, "advisor"))
                        {
                            ReadInteger(ref i);
                        }
                        else if (IsParent(parents, 1, "war_goal"))
                        {
                            ReadString(ref i, true);
                        }
                        else if (IsParent(parents, 1, "general"))
                        {
                            map.AddToken(GetTokenText(i));
                            i += 2;
                        }
                        else if (IsParent(parents, 1, "rebel_faction") ||
                            IsParent(parents, 1, "revolt") ||
                            IsParent(parents, 1, "mercenary") ||
                            IsParent(parents, 2, "previous_war"))
                        {
                            ReadString(ref i, true);
                        }
                        else if ((IsParent(parents, 1, "regiment") && !IsParent(parents, 2, "military_construction")) ||
                            IsParent(parents, 1, "ship") ||
                            IsParent(parents, 1, "faction") ||
                            IsParent(parents, 1, "military_construction") ||
                            IsParent(parents, 1, "possible_mercenary") ||
                            IsParent(parents, 1, "active_major_mission") ||
                            IsParent(parents, 1, "casus_belli") ||
                            IsParent(parents, 1, "take_province") ||
                            IsParent(parents, 1, "take_core") ||
                            IsParent(parents, 2, "active_war"))
                        {
                            ReadString(ref i, false);
                        }
                        else
                        {
                            ReadInteger(ref i);
                        }
                        break;
                    case "discovered_by":
                        map.AddToken(text);
                        i += 2;
                        if (parents.Length > 0 && parents[parents.Length - 1].StartsWith("-"))
                        {
                            quoted = false;
                        }
                        if (TryAddSpecials(ref i)) break;
                        TryReadTypeDefinition(ref i, ref type);

                        ReadString(ref i, true);
                        break;

                    case "action":
                        map.AddToken(text);
                        i += 2;
                        if (TryAddSpecials(ref i)) break;
                        TryReadTypeDefinition(ref i, ref type);

                        if (IsParent(parents, 1, "diplomacy_construction"))
                        {
                            ReadString(ref i, true);
                        }
                        else if (IsParent(parents, 1, "previous_war"))
                        {
                            ReadDate(ref i, false);
                        }
                        else
                        {
                            ReadInteger(ref i);
                        }
                        break;

                    case "steer_power":
                        map.AddToken(text);
                        i += 2;
                        if (TryAddSpecials(ref i)) break;
                        TryReadTypeDefinition(ref i, ref type);

                        if (IsParent(parents, 1, "node"))
                            ReadFloat(ref i);
                        else
                            ReadInteger(ref i);
                        break;

                    case "value":
                        map.AddToken(text);
                        i += 2;
                        if (TryAddSpecials(ref i)) break;
                        TryReadTypeDefinition(ref i, ref type);

                        if (IsParent(parents, 1, "improve_relation") ||
                            IsParent(parents, 1, "warningaction"))
                            ReadBoolean(ref i);
                        else
                        {
                            ReadFloat(ref i);
                        }
                        break;

                    case "unit_type":
                        map.AddToken(text);
                        i += 2;
                        if (TryAddSpecials(ref i)) break;
                        TryReadTypeDefinition(ref i, ref type);

                        if (parents.Length > 0 && parents[parents.Length - 1].StartsWith("O0"))
                        {
                            map.AddToken(GetTokenText(i));
                            i += 2;
                        }
                        else
                        {
                            ReadString(ref i, false);
                        }
                        break;

                    case "active":
                        map.AddToken(text);
                        i += 2;
                        if (TryAddSpecials(ref i)) break;
                        TryReadTypeDefinition(ref i, ref type);

                        if (IsParent(parents, 1, "rebel_faction") ||
                            IsParent(parents, 1, "siege_combat") ||
                            IsParent(parents, 1, "combat"))
                        {
                            map.AddToken(GetTokenText(i));
                            i += 2;
                        }
                        else
                        {
                            ReadBoolean(ref i);
                        }
                        break;

                    case "revolution_target":
                        map.AddToken(text);
                        i += 2;
                        if (TryAddSpecials(ref i)) break;
                        TryReadTypeDefinition(ref i, ref type);

                        if (IsParent(parents, 2, "history"))
                        {
                            map.AddToken(GetTokenText(i));
                            i += 2;
                        }
                        else
                        {
                            ReadString(ref i, true);
                        }
                        break;

                    default:
                        i += 2;
                        break;
                }
            }
            else
            {
                i += 2;
            }
        }