public StarSystem(UniverseIni universe, Section section, FreelancerData data) : base(data) { if (universe == null) { throw new ArgumentNullException("universe"); } if (section == null) { throw new ArgumentNullException("section"); } SelfFromSection(section); if (systemFile == null) //TODO: MultiUniverse { FLLog.Warning("Ini", "Unimplemented: Possible MultiUniverse system " + Nickname); MultiUniverse = true; return; } ParseAndFill(data.Freelancer.DataPath + "universe\\" + systemFile, data.Freelancer.DataPath, data.VFS); }
public static EditorConfiguration Load() { try { if (File.Exists(configPath)) { using (var s = File.OpenRead(configPath)) { return((EditorConfiguration)serializer.Deserialize(s)); } } else { return(new EditorConfiguration()); } } catch (Exception) { FLLog.Error("Config", "Error loading lanceredit.xml"); return(new EditorConfiguration()); } }
private void setMeshes(IntermediateNode vMeshLibrary, ILibFile materialLibrary) { foreach (IntermediateNode vmsNode in vMeshLibrary) { var vMeshDataNode = vmsNode.FirstOrDefault(x => x.Name.Equals("VMeshData", StringComparison.OrdinalIgnoreCase)); if (vMeshDataNode == null) { FLLog.Error("VMS", "Invalid VMeshLibrary: No VMeshData: " + vmsNode.Name); continue; } LeafNode vmsdat = vmsNode[0] as LeafNode; if (vmsdat == null) { FLLog.Error("VMS", "Invalid VMeshLibrary: VMeshData has no bytes: " + vmsNode.Name); } else { Meshes.Add(CrcTool.FLModelCrc(vmsNode.Name), new VMeshData(vmsdat.DataSegment, materialLibrary, vmsNode.Name)); } } }
public void AddLoadoutsIni(string path, FreelancerData gdata) { foreach (Section s in ParseFile(path, gdata.VFS)) { switch (s.Name.ToLowerInvariant()) { case "loadout": var l = new Loadout(s, gdata); if (string.IsNullOrEmpty(l.Nickname)) { FLLog.Error("Loadouts", "Loadout without name at " + s.File + ":" + s.Line); } else { Loadouts[l.Nickname] = l; } break; default: throw new Exception("Invalid Section in " + path + ": " + s.Name); } } }
public override void Run(ThnScriptInstance instance) { if (!instance.Objects.TryGetValue(Targets[0], out var obj)) { FLLog.Error("Thn", $"Entity {Targets[0]} does not exist"); return; } if (obj.Light == null) { FLLog.Error("Thn", $"Entity {Targets[0]} is not a light"); return; } if ((SetFlags & AnimVars.On) == AnimVars.On) { obj.Light.Active = On; } if (Duration > 0) { instance.AddProcessor(new LightPropAnim() { Orig = obj.Light.Light, Dst = obj.Light, Event = this }); } else { if ((SetFlags & AnimVars.Diffuse) == AnimVars.Diffuse) { obj.Light.Light.Color = Diffuse; } if ((SetFlags & AnimVars.Ambient) == AnimVars.Ambient) { obj.Light.Light.Ambient = Ambient; } } }
static bool GdiOpenFace(string face, out byte[] buffer) { int weight = GDI.FW_REGULAR; uint fdwItalic = 0; //Get font data from GDI buffer = null; unsafe { var hfont = GDI.CreateFont(0, 0, 0, 0, weight, fdwItalic, 0, 0, GDI.DEFAULT_CHARSET, GDI.OUT_OUTLINE_PRECIS, GDI.CLIP_DEFAULT_PRECIS, GDI.DEFAULT_QUALITY, GDI.DEFAULT_PITCH, face); //get data var hdc = GDI.CreateCompatibleDC(IntPtr.Zero); GDI.SelectObject(hdc, hfont); var size = GDI.GetFontData(hdc, 0, 0, IntPtr.Zero, 0); if (size == GDI.GDI_ERROR) { FLLog.Warning("GDI", "GetFontData for " + face + " failed"); GDI.DeleteDC(hdc); GDI.DeleteObject(hfont); return(false); } buffer = new byte[size]; fixed(byte *ptr = buffer) { GDI.GetFontData(hdc, 0, 0, (IntPtr)ptr, size); } GDI.DeleteDC(hdc); //delete font GDI.DeleteObject(hfont); return(true); } }
public void ParseAndFill(string filename) { var sections = GetContainerInfo(this.GetType()); foreach (var section in ParseFile(filename)) { var tgt = sections.FirstOrDefault((x) => x.Name.Equals(section.Name, StringComparison.InvariantCultureIgnoreCase)); if (tgt == null) { FLLog.Warning("Ini", "Unknown section " + section.Name + FormatLine(section.File, section.Line)); continue; } var parsed = GetFromSection(section, tgt.Type); if (tgt.Add != null) { var list = tgt.Field.GetValue(this); tgt.Add.Invoke(list, new object[] { parsed }); } else { tgt.Field.SetValue(this, parsed); } } }
public void AddVoicesIni(string path, FileSystem vfs) { Voice currentVoice = null; foreach (var section in ParseFile(path, vfs)) { switch (section.Name.ToLowerInvariant()) { case "voice": var s = FromSection <VoiceSection>(section); var name = s.Extend ?? s.Nickname; if (!Voices.TryGetValue(name, out currentVoice)) { currentVoice = new Voice() { Nickname = name }; Voices.Add(name, currentVoice); } currentVoice.Scripts.AddRange(s.Scripts); break; case "sound": if (currentVoice == null) { FLLog.Error("Ini", string.Format("{0}:{1} [Sound] section without matching [Voice]", section.File, section.Line)); } else { currentVoice.Messages.Add(FromSection <VoiceMessage>(section)); } break; } } }
public void Initialize() { if (data != null && Texture == null) { using (Stream stream = new MemoryStream(data)) { if (type.Equals("mips", StringComparison.OrdinalIgnoreCase)) { Texture = ImageLib.DDS.DDSFromStream2D(stream, 0, true); } else if (type.StartsWith("mip", StringComparison.OrdinalIgnoreCase)) { ; var tga = ImageLib.TGA.FromStream(stream, levels != null); if (levels != null) { foreach (var lv in levels) { using (var s2 = new MemoryStream(lv.Value)) { ImageLib.TGA.FromStream(s2, true, tga, lv.Key); } } } Texture = tga; levels = null; } else if (type.Equals("cube", StringComparison.OrdinalIgnoreCase)) { Texture = ImageLib.DDS.DDSFromStreamCube(stream, 0, true); } } } else { FLLog.Error("Texture " + texname, "data == null"); } }
static void LogError(object o) { FLLog.Error("Lua", o.ToString()); }
public FxBasicAppearance(AlchemyNode ale) : base(ale) { AleParameter temp; if (ale.TryGetParameter("BasicApp_QuadTexture", out temp)) { QuadTexture = (bool)temp.Value; } if (ale.TryGetParameter("BasicApp_TriTexture", out temp)) { if ((bool)temp.Value) { FLLog.Warning("ALE", "BasicApp_TriTexture not implemented"); } } if (ale.TryGetParameter("BasicApp_MotionBlur", out temp)) { MotionBlur = (bool)temp.Value; } if (ale.TryGetParameter("BasicApp_Color", out temp)) { Color = (AlchemyColorAnimation)temp.Value; } if (ale.TryGetParameter("BasicApp_Alpha", out temp)) { Alpha = (AlchemyFloatAnimation)temp.Value; } if (ale.TryGetParameter("BasicApp_HtoVAspect", out temp)) { HToVAspect = (AlchemyFloatAnimation)temp.Value; } if (ale.TryGetParameter("BasicApp_Rotate", out temp)) { Rotate = (AlchemyFloatAnimation)temp.Value; } if (ale.TryGetParameter("BasicApp_TexName", out temp)) { Texture = (string)temp.Value; } if (ale.TryGetParameter("BasicApp_UseCommonTexFrame", out temp)) { UseCommonAnimation = (bool)temp.Value; } if (ale.TryGetParameter("BasicApp_TexFrame", out temp)) { Animation = (AlchemyFloatAnimation)temp.Value; } if (ale.TryGetParameter("BasicApp_CommonTexFrame", out temp)) { CommonAnimation = (AlchemyCurveAnimation)temp.Value; } if (ale.TryGetParameter("BasicApp_FlipTexU", out temp)) { FlipHorizontal = (bool)temp.Value; } if (ale.TryGetParameter("BasicApp_FlipTexV", out temp)) { FlipVertical = (bool)temp.Value; } if (ale.TryGetParameter("BasicApp_Size", out temp)) { Size = (AlchemyFloatAnimation)temp.Value; } if (ale.TryGetParameter("BasicApp_BlendInfo", out temp)) { BlendInfo = BlendMap.Map((Tuple <uint, uint>)temp.Value); } }
public static void Log(string text) { FLLog.Debug("Shader", text); }
public Band(StarSystem parent, Section section) { if (parent == null) { throw new ArgumentNullException("parent"); } if (section == null) { throw new ArgumentNullException("section"); } this.parent = parent; foreach (Entry e in section) { switch (e.Name.ToLowerInvariant()) { case "zone": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (zoneName != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } zoneName = e[0].ToString(); break; case "render_parts": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (RenderParts != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } RenderParts = e[0].ToInt32(); break; case "shape": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Shape != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Shape = e[0].ToString(); break; case "height": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Height != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Height = e[0].ToInt32(); break; case "offset_dist": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (OffsetDist != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } OffsetDist = e[0].ToInt32(); break; case "fade": //if (e.Count != 4) throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); if (Fade != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Fade = new List <float>(); foreach (IValue i in e) { Fade.Add(i.ToSingle()); } break; case "texture_aspect": if (e.Count != 1) { FLLog.Warning("Ini", "Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TextureAspect != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TextureAspect = e[0].ToSingle(); break; case "color_shift": if (e.Count != 3) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (ColorShift != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } ColorShift = new Vector3(e[0].ToSingle(), e[1].ToSingle(), e[2].ToSingle()); break; case "ambient_intensity": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (AmbientIntensity != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } AmbientIntensity = e[0].ToSingle(); break; case "cull_mode": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (CullMode != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } CullMode = e[0].ToInt32(); break; case "vert_increase": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (VertIncrease != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } VertIncrease = e[0].ToInt32(); break; default: throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name); } } }
static ColladaGeometry GetGeometry(CL.UpAxisType up, CL.geometry geo, CL.library_materials matlib, CL.library_effects fxlib) { var conv = new ColladaGeometry() { FVF = D3DFVF.XYZ }; conv.Name = string.IsNullOrEmpty(geo.name) ? geo.id : geo.name; var msh = geo.Item as CL.mesh; if (msh == null) { return(null); } List <VertexPositionNormalDiffuseTextureTwo> vertices = new List <VertexPositionNormalDiffuseTextureTwo>(); List <int> hashes = new List <int>(); List <ushort> indices = new List <ushort>(); List <ColladaDrawcall> drawcalls = new List <ColladaDrawcall>(); Dictionary <string, GeometrySource> sources = new Dictionary <string, GeometrySource>(); Dictionary <string, float[]> arrays = new Dictionary <string, float[]>(); Dictionary <string, GeometrySource> verticesRefs = new Dictionary <string, GeometrySource>(); int placeHolderIdx = 0; //Get arrays foreach (var acc in msh.source) { var arr = acc.Item as CL.float_array; arrays.Add(arr.id, FloatArray(arr.Text)); } //Accessors foreach (var acc in msh.source) { sources.Add(acc.id, new GeometrySource(acc, arrays)); } //Process geometry foreach (var item in msh.Items) { if (!(item is CL.triangles || item is CL.polylist || item is CL.polygons)) { FLLog.Warning("Collada", "Ignoring " + item.GetType().Name + " element."); } } int totalTriangles = 0; foreach (var item in msh.Items.Where(x => x is CL.triangles || x is CL.polylist || x is CL.polygons)) { if (item is CL.triangles) { totalTriangles += (int)((CL.triangles)item).count; } else if (item is CL.polylist plist) { totalTriangles += (int)plist.count; } else { totalTriangles += (int)((CL.polygons)item).count; } } if (totalTriangles > 21845) { throw new Exception(string.Format( "Overflow!\nCollada geometry {0} has {1} triangles\nVMeshData has limit of 21845", string.IsNullOrEmpty(geo.name) ? geo.id : geo.name, totalTriangles)); } foreach (var item in msh.Items.Where(x => x is CL.triangles || x is CL.polylist || x is CL.polygons)) { CL.InputLocalOffset[] inputs; int[] pRefs; int indexCount; string materialRef; ColladaMaterial material; if (item is CL.triangles) { var triangles = (CL.triangles)item; indexCount = (int)(triangles.count * 3); pRefs = IntArray(triangles.p); inputs = triangles.input; materialRef = triangles.material; } else if (item is CL.polygons polygons) { indexCount = (int)(polygons.count * 3); int j = 0; pRefs = new int[indexCount]; foreach (var arr in polygons.Items) { if (!(arr is string)) { throw new Exception("Polygons: ph element unsupported"); } var ints = IntArray((string)arr); if (ints.Length != 3) { throw new Exception("Polygons: non-triangle geometry not supported"); } pRefs[j] = ints[0]; pRefs[j + 1] = ints[1]; pRefs[j + 2] = ints[2]; j += 3; } inputs = polygons.input; materialRef = polygons.material; } else { var plist = (CL.polylist)item; pRefs = IntArray(plist.p); foreach (var c in IntArray(plist.vcount)) { if (c != 3) { throw new Exception("Polylist: non-triangle geometry"); } } materialRef = plist.material; inputs = plist.input; indexCount = (int)(plist.count * 3); } if (indexCount == 0) { continue; //Skip empty } material = ParseMaterial(materialRef, matlib, fxlib); int pStride = 0; foreach (var input in inputs) { pStride = Math.Max((int)input.offset, pStride); } pStride++; GeometrySource sourceXYZ = null; int offXYZ = int.MinValue; GeometrySource sourceNORMAL = null; int offNORMAL = int.MinValue; GeometrySource sourceCOLOR = null; int offCOLOR = int.MinValue; GeometrySource sourceUV1 = null; int offUV1 = int.MinValue; GeometrySource sourceUV2 = null; int offUV2 = int.MinValue; int texCount = 0; int startIdx = indices.Count; foreach (var input in inputs) { switch (input.semantic) { case SEM_VERTEX: if (CheckURI(input.source) != msh.vertices.id) { throw new Exception("VERTEX doesn't match mesh vertices"); } foreach (var ip2 in msh.vertices.input) { switch (ip2.semantic) { case SEM_POSITION: offXYZ = (int)input.offset; sourceXYZ = sources[CheckURI(ip2.source)]; break; case SEM_NORMAL: offNORMAL = (int)input.offset; sourceNORMAL = sources[CheckURI(ip2.source)]; conv.FVF |= D3DFVF.NORMAL; break; case SEM_COLOR: offCOLOR = (int)input.offset; sourceCOLOR = sources[CheckURI(ip2.source)]; conv.FVF |= D3DFVF.DIFFUSE; break; case SEM_TEXCOORD: if (texCount == 2) { throw new Exception("Too many texcoords!"); } if (texCount == 1) { offUV2 = (int)input.offset; sourceUV2 = sources[CheckURI(ip2.source)]; conv.FVF &= ~D3DFVF.TEX1; conv.FVF |= D3DFVF.TEX2; } else { offUV1 = (int)input.offset; sourceUV1 = sources[CheckURI(ip2.source)]; if ((conv.FVF & D3DFVF.TEX2) != D3DFVF.TEX2) { conv.FVF |= D3DFVF.TEX1; } } texCount++; break; } } break; case SEM_POSITION: offXYZ = (int)input.offset; sourceXYZ = sources[CheckURI(input.source)]; break; case SEM_NORMAL: offNORMAL = (int)input.offset; sourceNORMAL = sources[CheckURI(input.source)]; conv.FVF |= D3DFVF.NORMAL; break; case SEM_COLOR: offCOLOR = (int)input.offset; sourceCOLOR = sources[CheckURI(input.source)]; conv.FVF |= D3DFVF.DIFFUSE; break; case SEM_TEXCOORD: if (texCount == 2) { throw new Exception("Too many texcoords!"); } if (texCount == 1) { offUV2 = (int)input.offset; sourceUV2 = sources[CheckURI(input.source)]; conv.FVF &= ~D3DFVF.TEX1; conv.FVF |= D3DFVF.TEX2; } else { offUV1 = (int)input.offset; sourceUV1 = sources[CheckURI(input.source)]; if ((conv.FVF & D3DFVF.TEX2) != D3DFVF.TEX2) { conv.FVF |= D3DFVF.TEX1; } } texCount++; break; } } int vertexOffset = vertices.Count; for (int i = 0; i < indexCount; i++) { int idx = i * pStride; var vert = new VertexPositionNormalDiffuseTextureTwo( VecAxis(up, sourceXYZ.GetXYZ(pRefs[idx + offXYZ])), offNORMAL == int.MinValue ? Vector3.Zero : VecAxis(up, sourceNORMAL.GetXYZ(pRefs[idx + offNORMAL])), offCOLOR == int.MinValue ? (uint)Color4.White.ToRgba() : (uint)sourceCOLOR.GetColor(pRefs[idx + offCOLOR]).ToRgba(), offUV1 == int.MinValue ? Vector2.Zero : sourceUV1.GetUV(pRefs[idx + offUV1]), offUV2 == int.MinValue ? Vector2.Zero : sourceUV2.GetUV(pRefs[idx + offUV2]) ); var hash = HashVert(ref vert); var vertIdx = FindDuplicate(hashes, vertices, vertexOffset, ref vert, hash); if (indices.Count >= ushort.MaxValue) { throw new Exception("Too many indices"); } if (vertIdx == -1) { if (vertices.Count + 1 >= ushort.MaxValue) { throw new Exception("Too many vertices"); } indices.Add((ushort)(vertices.Count - vertexOffset)); vertices.Add(vert); hashes.Add(hash); } else { indices.Add((ushort)(vertIdx - vertexOffset)); } } drawcalls.Add(new ColladaDrawcall() { StartIndex = startIdx, StartVertex = vertexOffset, EndVertex = vertices.Count - 1, TriCount = (indices.Count - startIdx) / 3, Material = material }); } conv.Indices = indices.ToArray(); conv.Vertices = vertices.ToArray(); conv.Drawcalls = drawcalls.ToArray(); conv.CalculateDimensions(); return(conv); }
protected virtual bool parentNode(LeafNode n) { switch (n.Name.ToLowerInvariant()) { //standard flags (Dc*) case "dt_flags": DtFlags = n.Int32ArrayData [0]; break; case "dt_name": DtName = n.StringData; break; case "dc": if (n.ColorData == null) { Dc = new Color4(n.SingleArrayData [0], n.SingleArrayData [1], n.SingleArrayData [2], 1); } else { Dc = n.ColorData.Value; } break; case "ec": if (n.ColorData == null) { Ec = new Color4(n.SingleArrayData [0], n.SingleArrayData [1], n.SingleArrayData [2], 1); } else { Ec = n.ColorData.Value; } break; case "bt_flags": BtFlags = n.Int32ArrayData[0]; break; case "bt_name": btName = n.StringData; break; case "et_flags": EtFlags = n.Int32ArrayData [0]; break; case "et_name": EtName = n.StringData; break; case "oc": Oc = n.SingleArrayData [0]; break; case "type": break; //different material types case "ac": if (n.ColorData == null) { Ac = new Color4(n.SingleArrayData [0], n.SingleArrayData [1], n.SingleArrayData [2], 1); } else { Ac = n.ColorData.Value; } break; case "flip u": FlipU = n.Int32Data.Value; break; case "flip v": FlipV = n.Int32Data.Value; break; case "alpha": Alpha = n.SingleData.Value; break; case "fade": Fade = n.SingleData.Value; break; case "scale": Scale = n.SingleData.Value; break; case "dm0_flags": Dm0Flags = n.Int32Data.Value; break; case "dm0_name": Dm0Name = n.StringData; break; case "dm1_flags": Dm1Flags = n.Int32Data.Value; break; case "dm1_name": Dm1Name = n.StringData; break; case "tilerate0": TileRate0 = n.SingleData.Value; break; case "tilerate1": TileRate1 = n.SingleData.Value; break; case "tilerate": TileRate = n.SingleData.Value; break; case "dm_flags": DmFlags = n.Int32Data.Value; break; case "dm_name": DmName = n.StringData; break; case "nt_name": NtName = n.StringData; break; case "nt_flags": NtFlags = n.Int32Data.Value; break; default: FLLog.Warning("Material", Name + ": Unknown property " + n.Name.ToLowerInvariant()); break; } return(true); }
void Optimize() { needsOptimize = false; List <int> meshes = new List <int>(); bool didOptimise = false; List <MaterialIndices> mats = new List <MaterialIndices>(); for (int i = StartMesh; i < endMesh; i++) { var c = counts.Where((x) => x.Material == Mesh.Meshes[i].MaterialCrc).First(); if (c.Count == 1 || Mesh.Meshes[i].Material == null || Mesh.Meshes[i].Material.Render.IsTransparent) { meshes.Add(i); } else { didOptimise = true; var m = mats.Where((x) => x.Crc == Mesh.Meshes[i].MaterialCrc).FirstOrDefault(); if (m == null) { m = new MaterialIndices() { Crc = Mesh.Meshes[i].MaterialCrc }; mats.Add(m); } for (int j = Mesh.Meshes[i].TriangleStart; j < (Mesh.Meshes[i].TriangleStart + Mesh.Meshes[i].NumRefVertices); j++) { m.Indices.Add(Mesh.Indices[j] + StartVertex + Mesh.Meshes[i].StartVertex); } } } if (didOptimise) { List <OptimizedDrawcall> dcs = new List <OptimizedDrawcall>(); List <ushort> indices = new List <ushort>(); foreach (var m in mats) { var dc = new OptimizedDrawcall(); dc.MaterialCrc = m.Crc; dc.PrimitiveCount = m.Indices.Count / 3; dc.StartIndex = indices.Count + Mesh.IndexHandle.CountIndex; var min = m.Indices.Min(); for (int i = 0; i < m.Indices.Count; i++) { indices.Add((ushort)(m.Indices[i] - min)); } dc.VertexOffset = min + Mesh.VertexOffset; dc.vMeshLibrary = vMeshLibrary; dcs.Add(dc); } if (Mesh.IndexHandle.CountIndex + indices.Count >= Mesh.IndexHandle.TotalIndex) { FLLog.Warning("Vms", "Failed to optimise: Not enough space in element buffer"); return; } var arr = indices.ToArray(); mesh.IndexHandle.Elements.SetData(arr, arr.Length, Mesh.IndexHandle.CountIndex); mesh.IndexHandle.CountIndex += arr.Length; FLLog.Debug("Optimiser", "Reduced from " + MeshCount + " drawcalls to " + (meshes.Count + dcs.Count)); optimized = new OptimizedDraw(); optimized.NormalDraw = meshes.ToArray(); optimized.Optimized = dcs.ToArray(); } }
public SphFile(IntermediateNode root, ILibFile library, string path = "/") { if (root == null) { throw new ArgumentNullException("root"); } if (library == null) { throw new ArgumentNullException("materialLibrary"); } materialsAccessor = new SphMaterials(this); ready = false; this.library = library; sideMaterialNames = new List <string>(); bool sphereSet = false; foreach (Node node in root) { switch (node.Name.ToLowerInvariant()) { case "sphere": if (sphereSet) { throw new Exception("Multiple sphere nodes"); } sphereSet = true; var sphereNode = (IntermediateNode)node; foreach (LeafNode sphereSubNode in sphereNode) { string name = sphereSubNode.Name.ToLowerInvariant(); if (name.StartsWith("m", StringComparison.OrdinalIgnoreCase)) { sideMaterialNames.Add(sphereSubNode.StringData); } else if (name == "radius") { Radius = sphereSubNode.SingleArrayData[0]; } else if (name == "sides") { int count = sphereSubNode.Int32ArrayData[0]; if (count != sideMaterialNames.Count) { throw new Exception("Invalid number of sides in " + node.Name + ": " + count); } } else { throw new Exception("Invalid node in " + node.Name + ": " + sphereSubNode.Name); } } break; case "vmeshlibrary": IntermediateNode vMeshLibraryNode = node as IntermediateNode; if (VMeshLibrary == null) { VMeshLibrary = new VmsFile(vMeshLibraryNode, library); } else { throw new Exception("Multiple vmeshlibrary nodes in 3db root"); } break; case "material library": IntermediateNode materialLibraryNode = node as IntermediateNode; if (MaterialLibrary == null) { MaterialLibrary = new MatFile(materialLibraryNode, library); } else { throw new Exception("Multiple material library nodes in 3db root"); } break; case "texture library": IntermediateNode textureLibraryNode = node as IntermediateNode; if (TextureLibrary == null) { TextureLibrary = new TxmFile(textureLibraryNode); } else { throw new Exception("Multiple texture library nodes in 3db root"); } break; } } if (sideMaterialNames.Count < 6) { FLLog.Warning("Sph", $"Sph {path} does not contain all 6 sides and will not render"); } }
public Base(Section section, FreelancerData data) : base(data) { if (section == null) { throw new ArgumentNullException("section"); } string file = null; foreach (Entry e in section) { switch (e.Name.ToLowerInvariant()) { case "nickname": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Nickname != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Nickname = e[0].ToString(); break; case "system": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (System != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } System = e[0].ToString(); break; case "strid_name": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (IdsName != 0) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } IdsName = e[0].ToInt32(); break; case "file": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (file != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } file = e[0].ToString(); break; case "bgcs_base_run_by": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (BGCSBaseRunBy != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } BGCSBaseRunBy = e[0].ToString(); break; case "terrain_tiny": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TerrainTiny != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TerrainTiny = e[0].ToString(); break; case "terrain_sml": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TerrainSml != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TerrainSml = e[0].ToString(); break; case "terrain_mdm": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TerrainMdm != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TerrainMdm = e[0].ToString(); break; case "terrain_lrg": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TerrainLrg != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TerrainLrg = e[0].ToString(); break; case "terrain_dyna_01": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TerrainDyna1 != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TerrainDyna1 = e[0].ToString(); break; case "terrain_dyna_02": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TerrainDyna2 != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TerrainDyna2 = e[0].ToString(); break; case "autosave_forbidden": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (AutosaveForbidden != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } AutosaveForbidden = e[0].ToBoolean(); break; default: FLLog.Warning("Ini", $"Invalid Entry `{e.Name}` in {section.Name}: {e.File}:{e.Line}"); break; } } Rooms = new List <Room>(); if (data.VFS.FileExists(data.Freelancer.DataPath + file)) { foreach (Section s in ParseFile(data.Freelancer.DataPath + file, data.VFS)) { switch (s.Name.ToLowerInvariant()) { case "baseinfo": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "nickname": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (Name != null) { FLLog.Warning("Base", "Duplicate " + e.Name + " Entry in " + s.Name); } Name = e[0].ToString(); break; case "start_room": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (StartRoom != null) { FLLog.Warning("Base", "Duplicate " + e.Name + " Entry in " + s.Name); } StartRoom = e[0].ToString(); break; case "price_variance": FLLog.Error("Base", "Unimplemented: price_variance"); break; default: FLLog.Warning("Ini", $"Invalid Entry `{e.Name}` in {section.Name}: {e.File}:{e.Line}"); break; } } break; case "room": Rooms.Add(new Room(s, data)); break; default: FLLog.Warning("Ini", $"Invalid Sectiom `{s.Name}` in {s.File}:{s.Line}"); break; } } } else { FLLog.Error("Ini", "Base ini could not find file " + file); } }
public Light(Section section, FreelancerData gdata) { foreach (Entry e in section) { switch (e.Name.ToLowerInvariant()) { case "nickname": Nickname = e[0].ToString(); break; case "inherit": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Inherit != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Inherit = gdata.Equipment.FindEquipment(e[0].ToString()) as Light; break; case "always_on": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (alwaysOn != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } alwaysOn = e[0].ToBoolean(); break; case "docking_light": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (dockingLight != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } dockingLight = e[0].ToBoolean(); break; case "bulb_size": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (bulbSize != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } bulbSize = e[0].ToSingle(); break; case "glow_size": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (glowSize != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } glowSize = e[0].ToSingle(); break; case "glow_color": if (e.Count != 3) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (glowColor != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } glowColor = new Color3f(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f); break; case "color": if (e.Count != 3) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (color != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } color = new Color3f(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f); break; case "flare_cone": if (e.Count != 2) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (flareCone != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } flareCone = new Vector2(e[0].ToInt32(), e[1].ToInt32()); break; case "intensity": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (intensity != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } intensity = e[0].ToInt32(); break; case "lightsource_cone": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (lightsourceCone != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } lightsourceCone = e[0].ToInt32(); break; case "min_color": if (e.Count != 3) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (minColor != null) { FLLog.Warning("Light", "Duplicate " + e.Name + " Entry in " + section.Name); } minColor = new Color3f(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f); break; case "avg_delay": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (avgDelay != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } avgDelay = e[0].ToSingle(); break; case "blink_duration": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (blinkDuration != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } blinkDuration = e[0].ToSingle(); break; case "shape": FLLog.Error("Light", "custom shape not implemented"); break; default: FLLog.Error("Equipment", "Invalid Entry in " + section.Name + ": " + e.Name); break; } } }
public Zone(Section section, FreelancerData data) : base(section, data) { if (section == null) { throw new ArgumentNullException("section"); } MissionType = new List <List <string> >(); FactionWeight = new Dictionary <string, int>(); DensityRestriction = new Dictionary <string, int>(); Encounters = new List <Encounter>(); foreach (Entry e in section) { if (!parentEntry(e)) { switch (e.Name.ToLowerInvariant()) { case "shape": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Shape != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } switch (e[0].ToString().ToLowerInvariant()) { case "sphere": Shape = ZoneShape.SPHERE; break; case "ellipsoid": Shape = ZoneShape.ELLIPSOID; break; case "box": Shape = ZoneShape.BOX; break; case "cylinder": Shape = ZoneShape.CYLINDER; break; case "ring": Shape = ZoneShape.RING; break; } break; case "attack_ids": if (AttackIds != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } AttackIds = new List <IValue>(); foreach (IValue i in e) { AttackIds.Add(i); } break; case "tradelane_attack": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TradelaneAttack != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TradelaneAttack = e[0].ToInt32(); break; case "property_flags": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (PropertyFlags != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } PropertyFlags = e[0].ToInt32(); break; case "property_fog_color": if (e.Count != 3) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (PropertyFogColor != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } PropertyFogColor = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, 1f); break; case "music": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Music != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Music = e[0].ToString(); break; case "edge_fraction": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (EdgeFraction != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } EdgeFraction = e[0].ToSingle(); break; case "spacedust": case "pacedust": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Spacedust != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Spacedust = e[0].ToString(); break; case "spacedust_maxparticles": case "spacedusr_maxparticles": case "spacedust_masparticles": case "spacedust _maxparticles": case "spacedust_maxdust": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (SpacedustMaxparticles != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } SpacedustMaxparticles = e[0].ToInt32(); break; case "interference": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Interference != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Interference = e[0].ToSingle(); break; case "power_modifier": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (PowerModifier != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } PowerModifier = e[0].ToSingle(); break; case "drag_modifier": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (DragModifier != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } DragModifier = e[0].ToSingle(); break; case "comment": if (Comment != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Comment = new List <string>(); foreach (IValue i in e) { Comment.Add(i.ToString()); } break; case "lane_id": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (LaneId != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } LaneId = e[0].ToInt32(); break; case "tradelane_down": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (TradelaneDown != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } TradelaneDown = e[0].ToInt32(); break; case "damage": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Damage != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Damage = e[0].ToSingle(); break; case "mission_type": MissionType.Add(new List <string>()); foreach (IValue i in e) { MissionType[MissionType.Count - 1].Add(i.ToString()); } break; case "sort": if (e.Count != 1) { FLLog.Warning("Ini", "Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Sort != null) { FLLog.Warning("Zone", "Duplicate " + e.Name + " Entry in " + section.Name); } Sort = e[0].ToSingle(); break; case "vignette_type": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (VignetteType != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } VignetteType = e[0].ToString(); break; case "toughness": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Toughness != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Toughness = e[0].ToInt32(); break; case "density": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Density != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Density = e[0].ToInt32(); break; case "population_additive": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (PopulationAdditive != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } PopulationAdditive = e[0].ToBoolean(); break; case "zone_creation_distance": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (ZoneCreationDistance != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } ZoneCreationDistance = e[0]; break; case "repop_time": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (RepopTime != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } RepopTime = e[0].ToInt32();; break; case "max_battle_size": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (MaxBattleSize != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } MaxBattleSize = e[0].ToInt32(); break; case "pop_type": if (PopType != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } PopType = new List <string>(); foreach (IValue i in e) { PopType.Add(i.ToString()); } break; case "relief_time": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (ReliefTime != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } ReliefTime = e[0].ToInt32(); break; case "path_label": if (PathLabel != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } PathLabel = e.ToList <IValue>(); break; case "usage": if (Usage != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Usage = new List <string>(); foreach (IValue i in e) { Usage.Add(i.ToString()); } break; case "mission_eligible": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (MissionEligible != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } MissionEligible = e[0].ToBoolean(); break; case "faction_weight": if (e.Count != 2) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (FactionWeight.ContainsKey(e[0].ToString())) { FLLog.Error("Ini", string.Format("Duplicate faction_weight for {0} in {1}, ignoring.", e[0], Nickname ?? "[undefined]")); } else { FactionWeight.Add(e[0].ToString(), e[1].ToInt32()); } break; case "density_restriction": if (e.Count != 2) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (DensityRestriction.ContainsKey(e[1].ToString())) { FLLog.Error("Ini", string.Format("Duplicate density_restriction for {0} in {1}, ignoring.", e[1], Nickname ?? "[undefined]")); } else { DensityRestriction.Add(e[1].ToString(), e[0].ToInt32()); } break; case "encounter": //if (e.Count != 3) throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); //Encounters.Add(new Encounter(e[0].ToString(), e[1].ToInt32(), e[2].ToSingle())); break; case "faction": //TODO: Re-enable encounter parsing //if (Encounters.Count == 0) throw new Exception(e.Name + " before encounter"); //if (e.Count == 1) { //Encounters[Encounters.Count - 1].Factions.Add(e[0].ToString(), 100); //} //else if (e.Count != 2) throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); //else Encounters[Encounters.Count - 1].Factions.Add(e[0].ToString(), e[1].ToSingle()); break; default: //throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name); FLLog.Warning("Zone", "Invalid Entry in " + section.Name + ": " + e.Name); break; } } } }
public ManagedDllProvider(Stream stream, string name) { var(rsrcOffset, rsrc) = GetRsrcSection(stream); var directory = Struct <IMAGE_RESOURCE_DIRECTORY>(rsrc, 0); List <ResourceTable> resources = new List <ResourceTable>(); for (int i = 0; i < directory.NumberOfNamedEntries + directory.NumberOfIdEntries; i++) { var off = 16 + (i * 8); var entry = Struct <IMAGE_RESOURCE_DIRECTORY_ENTRY>(rsrc, off); if ((IMAGE_RESOURCE_NAME_IS_STRING & entry.Name) == IMAGE_RESOURCE_NAME_IS_STRING) { continue; } resources.Add(ReadResourceTable(rsrcOffset, DirOffset(entry.OffsetToData), rsrc, entry.Name)); } foreach (var table in resources) { if (table.Type == RT_RCDATA) { foreach (var res in table.Resources) { int idx = res.Locales[0].Data.Offset; int count = res.Locales[0].Data.Count; if (res.Locales[0].Data.Count > 2) { if (res.Locales[0].Data[0] == 0xFF && res.Locales[0].Data[1] == 0xFE) { //skip BOM idx += 2; count -= 2; } } try { Infocards.Add((int)res.Name, Encoding.Unicode.GetString(res.Locales[0].Data.Array, idx, count)); } catch (Exception) { FLLog.Error("Infocards", $"{name}: Infocard Corrupt: {res.Name}"); } } } else if (table.Type == RT_STRING) { foreach (var res in table.Resources) { int blockId = (int)((res.Name - 1u) * 16); var seg = res.Locales[0].Data; using (var reader = new BinaryReader(new MemoryStream(seg.Array, seg.Offset, seg.Count))) { for (int j = 0; j < 16; j++) { int length = (int)(reader.ReadUInt16() * 2); if (length != 0) { byte[] bytes = reader.ReadBytes(length); string str = Encoding.Unicode.GetString(bytes); Strings.Add(blockId + j, str); } } } } } } }
protected virtual bool parentEntry(Entry e) { switch (e.Name.ToLowerInvariant()) { case "nickname": //if (e.Count != 1) throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); if (e.Count != 1) { FLLog.Warning("Ini", "Object " + e[0].ToString() + " has multiple values in nickname section"); } if (Nickname != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Nickname = e[0].ToString(); break; case "pos": if (e.Count != 3) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Pos != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Pos = new Vector3(e[0].ToSingle(), e[1].ToSingle(), e[2].ToSingle()); break; case "rotate": if (e.Count == 1) { if (e [0].ToSingle() == 0) { Rotate = Vector3.Zero; } else { FLLog.Warning("INI", "Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } } else { if (e.Count != 3) { FLLog.Error("Universe", "Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); break; } if (Rotate != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Rotate = new Vector3(e [0].ToSingle(), e [1].ToSingle(), e [2].ToSingle()); } break; default: return(false); } return(true); }
private void load(IntermediateNode root, ILibFile additionalLibrary) { this.additionalLibrary = additionalLibrary; ready = false; Hardpoints = new List <HardpointDefinition>(); var lvls = new Dictionary <int, VMeshRef>(); foreach (Node node in root) { switch (node.Name.ToLowerInvariant()) { case "exporter version": break; case "vmeshlibrary": IntermediateNode vMeshLibraryNode = node as IntermediateNode; if (VMeshLibrary == null) { VMeshLibrary = new VmsFile(vMeshLibraryNode, this); } else { throw new Exception("Multiple vmeshlibrary nodes in 3db root"); } break; case "material library": IntermediateNode materialLibraryNode = node as IntermediateNode; if (MaterialLibrary == null) { MaterialLibrary = new MatFile(materialLibraryNode, this); } else { throw new Exception("Multiple material library nodes in 3db root"); } break; case "texture library": IntermediateNode textureLibraryNode = node as IntermediateNode; if (TextureLibrary == null) { TextureLibrary = new TxmFile(textureLibraryNode); } else { throw new Exception("Multiple texture library nodes in 3db root"); } break; case "hardpoints": IntermediateNode hardpointsNode = node as IntermediateNode; if (hardpointsNode == null) { break; } foreach (Node hpn in hardpointsNode) { if (hpn is LeafNode) { continue; //No nodes here } var hardpointTypeNode = (IntermediateNode)hpn; switch (hardpointTypeNode.Name.ToLowerInvariant()) { //OfType<> to avoid crashes with bad models case "fixed": foreach (IntermediateNode fixedNode in hardpointTypeNode.OfType <IntermediateNode>()) { Hardpoints.Add(new FixedHardpointDefinition(fixedNode)); } break; case "revolute": foreach (IntermediateNode revoluteNode in hardpointTypeNode.OfType <IntermediateNode>()) { Hardpoints.Add(new RevoluteHardpointDefinition(revoluteNode)); } break; default: Hardpoints.Add(new FixedHardpointDefinition(hardpointTypeNode)); break; } } break; case "vmeshpart": { IntermediateNode vMeshPartNode = node as IntermediateNode; if (vMeshPartNode.Count == 1) { LeafNode vMeshRefNode = vMeshPartNode[0] as LeafNode; lvls.Add(0, new VMeshRef(vMeshRefNode.DataSegment, this)); } else { throw new Exception("Invalid VMeshPart: More than one child or zero elements"); } } break; case "multilevel": IntermediateNode multiLevelNode = node as IntermediateNode; foreach (Node multiLevelSubNode in multiLevelNode) { if (multiLevelSubNode.Name.StartsWith("level", StringComparison.OrdinalIgnoreCase)) { if (multiLevelSubNode is LeafNode) { continue; } IntermediateNode levelNode = multiLevelSubNode as IntermediateNode; if (levelNode.Count == 1) { int level = 0; if (!int.TryParse(levelNode.Name.Substring(5), out level)) { throw new Exception("Invalid Level: Missing index"); } IntermediateNode vMeshPartNode = levelNode[0] as IntermediateNode; if (vMeshPartNode.Count == 1) { LeafNode vMeshRefNode = vMeshPartNode[0] as LeafNode; if (vMeshRefNode != null && vMeshRefNode.Name.Equals("vmeshref", StringComparison.OrdinalIgnoreCase)) { lvls.Add(level, new VMeshRef(vMeshRefNode.DataSegment, this)); } } else { throw new Exception("Invalid VMeshPart: More than one child or zero elements"); } } //else throw new Exception("Invalid Level: More than one child or zero elements"); } else if (multiLevelSubNode.Name.Equals("switch2", StringComparison.OrdinalIgnoreCase)) { LeafNode switch2Node = multiLevelSubNode as LeafNode; Switch2 = switch2Node.SingleArrayData; } else { throw new Exception("Invalid node in " + multiLevelNode.Name + ": " + multiLevelSubNode.Name); } } break; case "vmeshwire": VMeshWire = new VMeshWire(node as IntermediateNode, this); break; case "mass properties": // TODO 3db Mass Properties break; case "extent tree": // TODO 3db Extent Tree break; case "materialanim": MaterialAnim = new MaterialAnimCollection((IntermediateNode)node); break; default: FLLog.Error("3db", (Path ?? "") + ": Invalid node: " + node.Name); break; } } //Sort levels in order var lvl2 = new List <VMeshRef>(); for (int i = 0; i < 100; i++) { if (lvls.ContainsKey(i)) { lvl2.Add(lvls[i]); } else { break; } } Levels = lvl2.ToArray(); }
public Room(Section section, FreelancerData data) { GameData = data; if (section == null) { throw new ArgumentNullException("section"); } string file = null; SceneScripts = new List <string>(); Hotspots = new List <RoomHotspot>(); foreach (Entry e in section) { switch (e.Name.ToLowerInvariant()) { case "nickname": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Nickname != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Nickname = e[0].ToString(); break; case "file": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (file != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } file = e[0].ToString(); break; default: throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name); } } if (VFS.FileExists(data.Freelancer.DataPath + file)) { foreach (Section s in ParseFile(data.Freelancer.DataPath + file)) { switch (s.Name.ToLowerInvariant()) { case "room_info": foreach (Entry e in s) { if (e.Name.ToLowerInvariant() == "set_script") { SceneScripts.Add(e[0].ToString()); } if (e.Name.ToLowerInvariant() == "goodscart_script") { GoodscartScript = e[0].ToString(); } if (e.Name.ToLowerInvariant() == "scene") { if (e.Count == 3 || e.Count == 4) { SceneScripts.Add(e[2].ToString()); } else { SceneScripts.Add(e[1].ToString()); } } } break; case "room_sound": foreach (Entry e in s) { if (e.Name.ToLowerInvariant() == "music") { Music = e[0].ToString(); } } break; case "camera": // TODO Room camera foreach (Entry e in s) { if (e.Name.ToLowerInvariant() == "name") { Camera = e[0].ToString(); } } break; case "spiels": // TODO Room spiels break; case "playershipplacement": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "name": PlayerShipPlacement = e[0].ToString(); break; case "launching_script": LaunchingScript = e[0].ToString(); break; case "landing_script": LandingScript = e[0].ToString(); break; } } break; case "characterplacement": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "start_script": StartScript = e[0].ToString(); break; } } break; case "forsaleshipplacement": // TODO Room forsaleshipplacement break; case "hotspot": // TODO Room hotspot var hotspot = new RoomHotspot(); foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "name": hotspot.Name = e[0].ToString(); break; case "behavior": hotspot.Behavior = e[0].ToString(); break; case "room_switch": hotspot.RoomSwitch = e[0].ToString(); break; case "set_virtual_room": hotspot.VirtualRoom = e[0].ToString(); break; } } Hotspots.Add(hotspot); break; case "flashlightset": // TODO Room flashlightset break; case "flashlightline": // TODO Room flashlightline break; default: throw new Exception("Invalid Section in " + file + ": " + s.Name); } } } else { FLLog.Error("Ini", "Room file not found " + file); } }
public void AddEquipmentIni(string path, FreelancerData data) { foreach (Section s in ParseFile(path)) { switch (s.Name.ToLowerInvariant()) { case "light": Equip.Add(new Light(s, data)); break; case "power": Equip.Add(new PowerCore(s)); break; case "scanner": break; case "tractor": break; case "lootcrate": break; case "repairkit": break; case "countermeasure": break; case "countermeasuredropper": break; case "shieldbattery": break; case "armor": break; case "cargopod": break; case "commodity": break; case "tradelane": break; case "internalfx": Equip.Add(new InternalFx(s, data)); break; case "attachedfx": Equip.Add(new AttachedFx(s, data)); break; case "shieldgenerator": break; case "shield": break; case "engine": break; case "thruster": Equip.Add(new Thruster(s)); break; case "cloakingdevice": break; case "motor": break; case "explosion": break; case "munition": break; case "gun": Equip.Add(new Gun(s)); break; case "mine": break; case "minedropper": break; case "lod": break; default: FLLog.Error("Equipment Ini", "Invalid Section in " + path + ": " + s.Name); break; } } }
public StarSystem(UniverseIni universe, Section section, FreelancerData data) : base(data) { if (universe == null) { throw new ArgumentNullException("universe"); } if (section == null) { throw new ArgumentNullException("section"); } string file = null; foreach (Entry e in section) { switch (e.Name.ToLowerInvariant()) { case "nickname": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Nickname != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Nickname = e[0].ToString(); break; case "file": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (file != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } file = e[0].ToString(); break; case "pos": if (e.Count != 2) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Pos != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Pos = new Vector2(e[0].ToSingle(), e[1].ToSingle()); break; case "msg_id_prefix": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (MsgIdPrefix != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } MsgIdPrefix = e[0].ToString(); break; case "visit": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (Visit != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } Visit = e[0].ToInt32(); break; case "strid_name": if (e.Count == 0) { break; } if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (IdsName != 0) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } IdsName = e[0].ToInt32(); break; case "ids_info": if (e.Count == 0) { break; } if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (IdsInfo != 0) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } IdsInfo = e[0].ToInt32(); break; case "navmapscale": if (e.Count != 1) { throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count); } if (NavMapScale != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name); } NavMapScale = e[0].ToSingle(); break; default: throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name); } } if (file == null) //TODO: MultiUniverse { FLLog.Warning("Ini", "Unimplemented: Possible MultiUniverse system " + Nickname); MultiUniverse = true; return; } foreach (Section s in ParseFile(GameData.Freelancer.DataPath + "universe\\" + file)) { switch (s.Name.ToLowerInvariant()) { case "systeminfo": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "name": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (Name != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } Name = e[0].ToString(); break; case "space_color": if (e.Count != 3) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (SpaceColor != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } SpaceColor = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, 1f); break; case "local_faction": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (LocalFaction != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } LocalFaction = e[0].ToString(); break; case "rpop_solar_detection": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (RpopSolarDetection != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } RpopSolarDetection = e[0].ToBoolean(); break; case "space_farclip": if (SpaceFarClip != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } SpaceFarClip = e[0].ToSingle(); break; default: throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name); } } break; case "music": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "space": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (MusicSpace != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } MusicSpace = e[0].ToString(); break; case "danger": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (MusicDanger != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } MusicDanger = e[0].ToString(); break; case "battle": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (MusicBattle != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } MusicBattle = e[0].ToString(); break; default: throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name); } } break; case "archetype": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "ship": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (ArchetypeShip == null) { ArchetypeShip = new List <string>(); } ArchetypeShip.Add(e[0].ToString()); break; case "simple": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (ArchetypeSimple == null) { ArchetypeSimple = new List <string>(); } ArchetypeSimple.Add(e[0].ToString()); break; case "solar": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (ArchetypeSolar == null) { ArchetypeSolar = new List <string>(); } ArchetypeSolar.Add(e[0].ToString()); break; case "equipment": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (ArchetypeEquipment == null) { ArchetypeEquipment = new List <string>(); } ArchetypeEquipment.Add(e[0].ToString()); break; case "snd": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (ArchetypeSnd == null) { ArchetypeSnd = new List <string>(); } ArchetypeSnd.Add(e[0].ToString()); break; case "voice": if (ArchetypeVoice == null) { ArchetypeVoice = new List <List <string> >(); } ArchetypeVoice.Add(new List <string>()); foreach (IValue i in e) { ArchetypeVoice[ArchetypeVoice.Count - 1].Add(i.ToString()); } break; default: throw new Exception("Invalid Entry in " + s.Name + ": " + e.Name); } } break; case "dust": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "spacedust": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (Spacedust != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } Spacedust = e[0].ToString(); break; default: throw new Exception("Invalid Entry in " + s.Name + ": " + e.Name); } } break; case "nebula": if (Nebulae == null) { Nebulae = new List <Nebula>(); } Nebulae.Add(new Nebula(this, s, GameData)); break; case "asteroids": if (Asteroids == null) { Asteroids = new List <AsteroidField>(); } Asteroids.Add(new AsteroidField(this, s, GameData)); break; case "ambient": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "color": if (e.Count != 3) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (AmbientColor != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } AmbientColor = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, 1f); break; default: throw new Exception("Invalid Entry in " + s.Name + ": " + e.Name); } } break; case "lightsource": if (LightSources == null) { LightSources = new List <LightSource>(); } LightSources.Add(new LightSource(s, GameData)); break; case "object": if (Objects == null) { Objects = new List <SystemObject>(); } Objects.Add(new SystemObject(universe, this, s, GameData)); break; case "encounterparameters": if (EncounterParameters == null) { EncounterParameters = new List <EncounterParameter>(); } EncounterParameters.Add(new EncounterParameter(s)); break; case "texturepanels": TexturePanels = new TexturePanelsRef(s, GameData); break; case "background": foreach (Entry e in s) { switch (e.Name.ToLowerInvariant()) { case "basic_stars": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (BackgroundBasicStarsPath != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } BackgroundBasicStarsPath = VFS.GetPath(GameData.Freelancer.DataPath + e [0].ToString()); break; case "complex_stars": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } if (BackgroundComplexStarsPath != null) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } BackgroundComplexStarsPath = VFS.GetPath(GameData.Freelancer.DataPath + e [0].ToString()); break; case "nebulae": if (e.Count != 1) { throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count); } string temp = VFS.GetPath(GameData.Freelancer.DataPath + e[0].ToString(), false); if (BackgroundNebulaePath != null && BackgroundNebulaePath != temp) { throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name); } BackgroundNebulaePath = temp; break; default: throw new Exception("Invalid Entry in " + s.Name + ": " + e.Name); } } break; case "zone": if (Zones == null) { Zones = new List <Zone>(); } Zones.Add(new Zone(s, GameData)); break; case "field": Field = new Field(s); break; case "asteroidbillboards": AsteroidBillboards = new AsteroidBillboards(s); break; default: throw new Exception("Invalid Section in " + file + ": " + s.Name); } } }
static void LogString(string s) { FLLog.Info("Lua", s); }
protected List <Section> ParseFile(string path, bool allowmaps = false) { if (path == null) { throw new ArgumentNullException("path"); } List <Section> sections = new List <Section>(); if (!path.ToLowerInvariant().EndsWith(".ini")) { path = path + ".ini"; } using (Stream stream = VFS.Open(path)) { byte[] buffer = new byte[4]; stream.Read(buffer, 0, 4); string fileType = Encoding.ASCII.GetString(buffer); if (fileType == FileType) // Binary Ini { BinaryReader reader = new BinaryReader(stream); int formatVersion = reader.ReadInt32(); if (formatVersion != FileVersion) { throw new FileVersionException(path, fileType, formatVersion, FileVersion); } int stringBlockOffset = reader.ReadInt32(); if (stringBlockOffset > reader.BaseStream.Length) { throw new FileContentException(path, fileType, "The string block offset was out of range: " + stringBlockOffset); } long sectionBlockOffset = reader.BaseStream.Position; reader.BaseStream.Seek(stringBlockOffset, SeekOrigin.Begin); Array.Resize <byte>(ref buffer, (int)(reader.BaseStream.Length - stringBlockOffset)); reader.Read(buffer, 0, buffer.Length); string stringBlock = Encoding.ASCII.GetString(buffer); reader.BaseStream.Seek(sectionBlockOffset, SeekOrigin.Begin); while (reader.BaseStream.Position < stringBlockOffset) { sections.Add(new Section(reader, stringBlock)); } } else // Text Ini { stream.Seek(0, SeekOrigin.Begin); StreamReader reader = new StreamReader(stream); int currentSection = -2; int currentLine = 0; bool inSection = false; while (!reader.EndOfStream) { string line = reader.ReadLine().Trim(); if (string.IsNullOrWhiteSpace(line) || line.StartsWith(";", StringComparison.OrdinalIgnoreCase) || line.StartsWith("@", StringComparison.OrdinalIgnoreCase)) { continue; } if (line.StartsWith("[", StringComparison.OrdinalIgnoreCase)) { if (line.Substring(1).Trim()[0] == ';') { inSection = false; currentSection = -1; continue; } if (!line.Contains("]")) { throw new FileContentException(path, IniFileType, "Invalid section header: " + line); } string name = line.Substring(1); sections.Add(new Section(name.Remove(name.IndexOf(']')).Trim())); currentSection = sections.Count - 1; inSection = true; continue; } else { if (!inSection) { continue; } if (line.Contains(";")) { line = line.Remove(line.IndexOf(";", StringComparison.OrdinalIgnoreCase)).TrimEnd(); } if (!char.IsLetterOrDigit(line [0]) && line [0] != '_') { FLLog.Warning("Ini", "Invalid line in file: " + path + " at line " + currentLine + '"' + line + '"'); } else if (line.Contains("=")) { string[] parts = line.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2) { string val = parts [1].TrimStart(); string[] valParts; if (val.Contains(",")) { valParts = val.Split(new char[] { ',' }); } else { valParts = new string[] { val } }; List <IValue> values = new List <IValue> (); foreach (string part in valParts) { string s = part.Trim(); bool tempBool; int tempInt; float tempFloat; if (bool.TryParse(s, out tempBool)) { values.Add(new BooleanValue(tempBool)); } else if (int.TryParse(s, out tempInt)) { values.Add(new Int32Value(tempInt)); } else if (float.TryParse(s, out tempFloat)) { long templong; bool a = long.TryParse(s, out templong); values.Add(new SingleValue(tempFloat, a ? (long?)templong : null)); } else { values.Add(new StringValue(s)); } } sections [currentSection].Add(new Entry(parts [0].TrimEnd(), values)); } else if (parts.Length == 3 && allowmaps) { string k = parts [1].Trim(); string v = parts [2].Trim(); sections[currentSection].Add(new Entry(parts[0].Trim(), new IValue[] { new StringKeyValue(k, v) })); } else if (parts.Length == 1) { sections [currentSection].Add(new Entry(parts [0].Trim(), new List <IValue> ())); } else { FLLog.Error("INI", "Invalid entry line: " + line + " in " + path); } } else { sections[currentSection].Add(new Entry(line, new List <IValue>(0))); } } currentLine++; } } } return(sections); }
public override void EnableScripting(UiContext context, string modalData) { try { DeleteLua(); lua = new Lua(); lua.State.Encoding = Encoding.UTF8; lua.LoadCLRPackage(); lua["LogString"] = (Action <string>)LogString; lua["LogError"] = (Action <string>)LogError; lua["ReadAllText"] = (Func <string, string>)context.ReadAllText; lua.DoString(LUA_SANDBOX); if (!string.IsNullOrEmpty(modalData)) { ((LuaFunction)lua["DeserializeToEnv"]).Call("ModalData", modalData); } Env = (LuaTable)lua["Env"]; Env["GetElement"] = (Func <string, UiWidget>)GetElement; Env["NewObject"] = (Func <string, object>)UiXmlReflection.Instantiate; Env["OpenModal"] = (Action <string, object, LuaFunction>)((xml, data, function) => { OpenModal(context, xml, data, function); }); Env["CloseModal"] = (Action <object>)((table) => { CloseModal(context, table); }); Env["Timer"] = (Action <float, LuaFunction>)((timer, func) => { timers.Add(new LuaTimer() { Time = TimeSpan.FromSeconds(timer), Function = func }); }); Env["ApplyStyles"] = (Action)ApplyStyles; Env["GetScene"] = (Func <Scene>)(() => this); Env["PlaySound"] = (Action <string>)context.PlaySound; Env["Game"] = context.GameApi; Env["Color"] = (Func <string, InterfaceColor>)context.GetColor; Env["GetNavbarIconPath"] = (Func <string, string>)context.GetNavbarIconPath; Env["SwitchTo"] = (Action <string>)(SwitchTo); RunSandboxed = (LuaFunction)lua["RunSandboxed"]; CallEvent = (LuaFunction)lua["CallEvent"]; RunSandboxed.Call(context.ReadAllText(ScriptFile), ScriptFile); lua.DoString("collectgarbage()"); } catch (LuaScriptException lse) { FLLog.Error("Lua", lse.ToString()); } catch (LuaException le) { FLLog.Error("Lua", le.ToString()); } catch (Exception e) { FLLog.Error("Lua", $"{e.GetType()}\n{e.Message}\n{e.StackTrace}"); lua?.Dispose(); lua = null; } }
static object GetFromSection(Section s, ReflectionInfo type) { var obj = Activator.CreateInstance(type.Type); ulong bitmask = 0; ulong requiredBits = type.RequiredFields; foreach (var e in s) { //Find entry int idx = -1; for (int i = 0; i < type.Fields.Count; i++) { if (type.Fields[i].Attr.Name.Equals(e.Name, StringComparison.InvariantCultureIgnoreCase)) { idx = i; break; } } //Special Handling if (idx == -1) { bool handled = false; if (type.HandleEntry != null) { handled = (bool)type.HandleEntry.Invoke(obj, new object[] { e }); } if (!handled) { FLLog.Warning("Ini", "Unknown entry " + e.Name + FormatLine(e.File, e.Line, s.Name)); } continue; } var field = type.Fields[idx]; //Warning for duplicates if (!field.Attr.Multiline) { if ((bitmask & (1ul << idx)) != 0) { FLLog.Warning("Ini", "Duplicate of " + field.Attr.Name + FormatLine(e.File, e.Line, s.Name)); } bitmask |= 1ul << idx; } requiredBits &= ~(1ul << idx); var ftype = field.Field.FieldType; Type nType; if ((nType = Nullable.GetUnderlyingType(ftype)) != null) { ftype = nType; } //Fill if (ftype == typeof(string)) { if (ComponentCheck(1, s, e)) { field.Field.SetValue(obj, e[0].ToString()); } } else if (ftype == typeof(float)) { if (ComponentCheck(1, s, e)) { field.Field.SetValue(obj, e[0].ToSingle()); } } else if (ftype == typeof(int)) { if (ComponentCheck(1, s, e)) { field.Field.SetValue(obj, e[0].ToInt32()); } } else if (ftype == typeof(long)) { if (ComponentCheck(1, s, e)) { field.Field.SetValue(obj, e[0].ToInt64()); } } else if (ftype == typeof(bool)) { if (field.Attr.Presence) { field.Field.SetValue(obj, true); } else if (ComponentCheck(1, s, e)) { field.Field.SetValue(obj, e[0].ToBoolean()); } } else if (ftype == typeof(Vector3)) { if (ComponentCheck(3, s, e)) { field.Field.SetValue(obj, new Vector3(e[0].ToSingle(), e[1].ToSingle(), e[2].ToSingle())); } } else if (ftype == typeof(Quaternion)) { if (ComponentCheck(4, s, e)) { field.Field.SetValue(obj, new Quaternion(e[1].ToSingle(), e[2].ToSingle(), e[3].ToSingle(), e[0].ToSingle())); } } else if (ftype == typeof(Vector2)) { if (e.Count == 1 && field.Attr.MinMax) { field.Field.SetValue(obj, new Vector2(-1, e[0].ToSingle())); } else if (ComponentCheck(2, s, e)) { field.Field.SetValue(obj, new Vector2(e[0].ToSingle(), e[1].ToSingle())); } } else if (ftype == typeof(Color4)) { if (ComponentCheck(4, s, e, 3)) { Color4 col; if (e.Count == 3) { col = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, 1f); } else { col = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, e[3].ToInt32() / 255f); } field.Field.SetValue(obj, col); } } else if (ftype == typeof(Color3f)) { if (ComponentCheck(3, s, e)) { field.Field.SetValue(obj, new Color3f(e[0].ToSingle(), e[1].ToSingle(), e[2].ToSingle())); } } else if (ftype == typeof(List <string>)) { if (field.Attr.Multiline) { bitmask &= ~(1ul << idx); //Avoid duplicate warnings if (ComponentCheck(1, s, e)) { var v = (List <string>)field.Field.GetValue(obj); v.Add(e[0].ToString()); } } else if (ComponentCheck(int.MaxValue, s, e, 1)) { field.Field.SetValue(obj, e.Select((x) => x.ToString()).ToList()); } } else if (ftype == typeof(float[])) { if (ComponentCheck(int.MaxValue, s, e, 1)) { var floats = new float[e.Count]; for (int i = 0; i < e.Count; i++) { floats[i] = e[i].ToSingle(); } field.Field.SetValue(obj, floats); } } else if (ftype == typeof(string[])) { if (ComponentCheck(int.MaxValue, s, e, 1)) { var strings = new string[e.Count]; for (int i = 0; i < e.Count; i++) { strings[i] = e[i].ToString(); } field.Field.SetValue(obj, strings); } } else if (ftype.IsEnum) { if (ComponentCheck(1, s, e)) { //TryParse requires generics, wrap in exception handler try { field.Field.SetValue(obj, Enum.Parse(field.Field.FieldType, e[0].ToString(), true)); } catch (Exception) { FLLog.Error("Ini", "Invalid value for enum " + e[0].ToString() + FormatLine(e.File, e.Line, s.Name)); } } } } if (requiredBits != 0) { //These sections crash the game if they don't have required fields //So don't let them be added to lists for (int i = 0; i < 64; i++) { if ((requiredBits & (1ul << i)) != 0) { FLLog.Error("Ini", string.Format("Missing required field {0}{1}", type.Fields[i].Attr.Name, FormatLine(s.File, s.Line, s.Name))); } } return(null); } else { return(obj); } }