memnoch3434 Posted October 23, 2017 Share Posted October 23, 2017 I've been working on a mod to get some data from the game (like in game distances and such). I'd like to make a text file with the data each time I take data. However I must be doing something wrong, as the mod breaks whenever I try to make a file. Here is the onTick portion of the code: private void onTick(object sender, EventArgs e) { if (Activate) { ticks = ticks + 1; if (IncreaseSpeed > -1) { SendKeys.SendWait("{RIGHT}"); IncreaseSpeed += 1; if (IncreaseSpeed == 3) { IncreaseSpeed = -1; } } if (Game.Player.Character.IsInVehicle()) { if (ticks % 50 == 0) { Vehicle[] VehiclesNearby = World.GetNearbyVehicles(Game.Player.Character, 300f); DateTime NowRaw = new DateTime(); string Now = NowRaw.ToString(); FileLoc = (@"C:\Users\amixter\Documents" + "p.txt"); VehicleNumber = 0; SendKeys.SendWait("{PRTSC}"); pPos = Game.Player.Character.Position; pHeading = Game.Player.Character.Heading; foreach (Vehicle thisVehicle in VehiclesNearby) { if (thisVehicle.IsOnScreen) { vehPos.Add(thisVehicle.Position); vehHeading.Add(thisVehicle.Heading); VehicleNumber += 1; vehName.Add(thisVehicle.Model.ToString()); } } } if (ticks- 10 % 50 == 0) { foreach(Vector3 Vector in vehPos) { Dist.Add(Vector.DistanceTo(pPos)); X.Add(Vector.X - pPos.X); Y.Add(Vector.Y - pPos.Y); Z.Add(Vector.Z - pPos.Z); } foreach(float heading in vehHeading) { vHeadingRel.Add( heading - pHeading); } int i = 0; fileInfo = fileInfo + "Number of Vehicles in this Image: " + VehicleNumber.ToString() + "\r\n"; fileInfo = fileInfo + "\r\n"; for (i = 0; i < VehicleNumber; i++) { fileInfo = fileInfo +"Vehicle Number: " + i.ToString() + "\r\n"; fileInfo = fileInfo + "Model = " + vehName[i] + "\r\n"; fileInfo = fileInfo + "Distance = " + Dist[i].ToString() + "\r\n"; fileInfo = fileInfo + "X = " + X[i].ToString() + "\r\n"; fileInfo = fileInfo + "Y = " + Y[i].ToString() + "\r\n"; fileInfo = fileInfo + "Z = " + Z[i].ToString() + "\r\n"; fileInfo = fileInfo + "Relative Heading = " + vHeadingRel[i].ToString() + "\r\n"; fileInfo = fileInfo + "\r\n"; } } if (ticks -20 % 50 == 0) { Dist = new List<float>(); X = new List<float>(); Y = new List<float>(); Z = new List<float>(); vehHeading = new List<float>(); vHeadingRel = new List<float>(); vehPos = new List<Vector3>(); vehName = new List<string>(); } if (ticks - 30% 50 == 0) { if (!File.Exists(FileLoc)) { using(TextWriter tw = new StreamWriter(FileLoc, false, Encoding.UTF8, 4000)) { tw.WriteLine(fileInfo); } } } if (!Function.Call<bool>(Hash.IS_WAYPOINT_ACTIVE)) { switch (p) { case 0: Function.Call(Hash.SET_NEW_WAYPOINT, -139.682, 6439.920); p = p + 1; break; case 1: Function.Call(Hash.SET_NEW_WAYPOINT, -3045.002, 231.303); p = p + 1; break; case 2: Function.Call(Hash.SET_NEW_WAYPOINT, 769.490, -2963.950); p = p + 1; break; case 3: Function.Call(Hash.SET_NEW_WAYPOINT, 3315.331, 5150.924); p = 0; break; } } } if (!Game.Player.Character.IsInVehicle()) { Activate = !Activate; Vehicle vehicle = World.CreateVehicle(VehicleHash.Adder, Game.Player.Character.Position + Game.Player.Character.ForwardVector * 3.0f, Game.Player.Character.Heading + 90); vehicle.IsInvincible = true; vehicle.PlaceOnGround(); vehicle.NumberPlate = "GCAPS"; if (Function.Call<bool>(Hash.IS_VEHICLE_SEAT_FREE, vehicle, -1)) { Function.Call<bool>(Hash.SET_PED_INTO_VEHICLE, Function.Call<Ped>(Hash.PLAYER_PED_ID), vehicle, -1); } SendKeys.SendWait("{J}"); IncreaseSpeed = 0; Activate = !Activate; } } } Everything Runs just fine except for this portion: if (!File.Exists(FileLoc)) { using(TextWriter tw = new StreamWriter(FileLoc, false, Encoding.UTF8, 4000)) { tw.WriteLine(fileInfo); } } What am I missing? Is it just too slow to print a text file as a tick operation? Link to comment Share on other sites More sharing options...
Guest Posted October 24, 2017 Share Posted October 24, 2017 (edited) The most immediate thing I can see is this FileLoc = (@"C:\Users\amixter\Documents" + "p.txt"); You have no backslash after Documents, so it will be trying to create a file called Documentsp.txt in the C:\Users\amixter folder. I don't know if that is the whole problem but it's something that could be a problem at some level... I am not sure what the permissions situation is with that level of the Users folder. You also seem to be creating your file with the append flag set to False, so it will probably be creating a new file every time. But I only ever use the StreamWriter class, not the TextWriter class, so I could be wrong about that. In my debug logging class, I declare a StreamWriter variable. private StreamWriter SW; I create the file when the log is initialised with using (SW = File.CreateText(LogName)){ SW.WriteLine(initString);} Where initString is just a header string built from the time and date... and then when I want to write to that file, I use this using (SW = File.AppendText(LogName)){ SW.WriteLine(prefix + " --->> " + logentry);} But if I was collecting a lot of entries, I would write them to a List<string> first and then write the whole collection out on a keypress when I had finished collecting the data. Edited October 24, 2017 by Guest Link to comment Share on other sites More sharing options...
memnoch3434 Posted October 24, 2017 Author Share Posted October 24, 2017 Thanks for the reply! The most immediate thing I can see is this FileLoc = (@"C:\Users\amixter\Documents" + "p.txt");You have no backslash after Documents, so it will be trying to create a file called Documentsp.txt in the C:\Users\amixter folder. I don't know if that is the whole problem but it's something that could be a problem at some level... I am not sure what the permissions situation is with that level of the Users folder. Good catch on the file name! I fixed this issue accidentally last night, I do have a directory that is writing for sure now. You also seem to be creating your file with the append flag set to False, so it will probably be creating a new file every time. But I only ever use the StreamWriter class, not the TextWriter class, so I could be wrong about that. Believe it or not, that was intentional at the time. In my debug logging class, I declare a StreamWriter variable. private StreamWriter SW;I create the file when the log is initialised withusing (SW = File.CreateText(LogName)){ SW.WriteLine(initString);}Where initString is just a header string built from the time and date... and then when I want to write to that file, I use thisusing (SW = File.AppendText(LogName)){ SW.WriteLine(prefix + " --->> " + logentry);}But if I was collecting a lot of entries, I would write them to a List first and then write the whole collection out on a keypress when I had finished collecting the data. i attempted to do what you suggested: Collect the data in a List and then write all lines to a file on key up. When I first changed to a key press instead of a new file every so often, I made a mistake and printed just the List object. That actually created a text file, but just had information about the object. Still not having luck with writing all the data. How much data do you typically write to your log file? Link to comment Share on other sites More sharing options...
Guest Posted October 24, 2017 Share Posted October 24, 2017 (edited) The amount of data I write changes as I progress through the mod. As parts of the mod are proven to be working fine, I remove those from the debugging process, just to remove clutter from the log file. But it could be anything from writing out the details of a new vehicle when I find one, to constantly writing out coordinates and hash values of multiple objects. I have had cases where I have generated 100KB+ log files in a matter of seconds. I have never had a problem other than a slight stutter with the bigger log files but I much prefer to cache those values and then write them out in one go later. This is the output section of a mod I had that scanned the whole map for CCTV cameras. This also includes a section that increments a file number so that if a file is already existing, it will create one with a new number on the end. So if cctv-cameras1.txt is present, it would create cctv-cameras2.txt for example. string path_pre = "scripts\\cctv-cameras";string path_ext = ".txt";int counter = 0;int filecounter = 1;string fullpath = path_pre + filecounter.ToString() + path_ext;while (File.Exists(fullpath)){ filecounter++; fullpath = path_pre + filecounter.ToString() + path_ext;}using (StreamWriter sw = File.CreateText(fullpath)){ foreach (sCCTVStruct _cctv in CCTVCameras.Values) { string _header = string.Format("[{0:000}]\t", counter); string _model = "[" + _cctv.sPropHash + "]\t\t-\t"; string _vector3 = "Position (" + _cctv.xPos.ToString() + ", " + _cctv.yPos.ToString() + ", " + _cctv.zPos.ToString() + ")\t\t"; string _rotVector3 = "Rotation (" + _cctv.xRot.ToString() + ", " + _cctv.yRot.ToString() + ", " + _cctv.zRot.ToString() + ")\t\t"; string _streetName = _cctv.street; string bstring = _header + _model + _vector3 + _rotVector3 + _streetName; sw.WriteLine(bstring); counter++; }}UI.ShowSubtitle("Writing File: " + fullpath + " and stopping scanning."); Edited October 24, 2017 by Guest Link to comment Share on other sites More sharing options...
memnoch3434 Posted October 24, 2017 Author Share Posted October 24, 2017 So I think I figured out the problem. I had originally had an issue with naming the file using a dateTimeStamp as a string (still not sure what is going on there) but I assumed it was the time it took to write a file (reinforced by the fact that when the file write operation was removed the code kept working). I then implemented a strategy to process less information on each "tick" to attempt to fix the problem. This caused a second problem, by forcing too many operations too soon. The code is now working! Link to comment Share on other sites More sharing options...