Koenvh1 / ets2-local-radio

Radio from wherever you are in ETS2/ATS
https://koenvh.nl/projects/ets2-local-radio
Mozilla Public License 2.0
232 stars 40 forks source link

Overlay works on 32-bit but not on 64-bit #137

Open Emiroe opened 3 years ago

Emiroe commented 3 years ago

Hi,

I am trying to get this to work for me. Until now I always had crashes whenever the game tried to show the overlay for the first time. The steps I take:

I have searched a bit and found this thread from yesterday where a fix was given: https://github.com/Koenvh1/ets2-local-radio/issues/136#issuecomment-810560932

I have tried to implement this fix and it has improved the situation a little. It now seems that it doesn't crash anymore, but there is also still no overlay. Something else I have noticed now is that it does work when using 32-bit Direct X 11 but not when using 64-bit Direct-X 11.

I have updated my NVIDIA card to the latest version. Any suggestion what it could be?

Koenvh1 commented 3 years ago

Try uninstalling Local Radio, removing the folder, and installing it again. Some people had some temp files becoming uneditable, which might cause it to crash. Additionally #136 notes that it happens using the latest nVidia drivers, so you may want to try it with the version before that.

Emiroe commented 3 years ago

Hi! Thanks for the quick response. I have removed the plugin and uninstalled the program completely - then freshly downloaded a new installer from GitHub. I tested it aain with this fresh install:

I have rolled back my nvidia update but it did not have any effect. Regarding the other thread: maybe I forgot to say but it never worked in 64-bit for me. It did not stop working suddenly.

The "fix" in the other thread does prevent the game from crashing, but it still does not show the overlay. The error log also does not tell much:

23:46:41: Device found: G923 Racing Wheel for PlayStation 4 and PC 23:46:41: Device found: G923 Racing Wheel for PlayStation 4 and PC 23:46:50: Not found: C:\Program Files (x86)\ETS2 Local Radio\web\custom.js 23:47:00: Not found: C:\Program Files (x86)\ETS2 Local Radio\web\custom.js 23:47:48: Process attached: eurotrucks2 (Width: 0; Height: 0) 23:47:48: No capture process bound

gatenosix commented 3 years ago

Hi,

Just wanted to chime in and say I'm getting the same issue. For whatever reason, the fix from the other thread doesn't seem to help me in 64-bit but like Emiroe, all seems to be fine when running the game in 32-bit mode.

My error log is very similar, with the only real difference being the wheel I'm using:

13:15:36: Device found: Logitech G29 Driving Force Racing Wheel USB 13:15:36: Device found: Logitech G29 Driving Force Racing Wheel USB 13:16:10: Not found: D:\Programs and Apps\ETS2 Local Radio\web\custom.js 13:16:19: Not found: D:\Programs and Apps\ETS2 Local Radio\web\custom.js 13:17:10: Process attached: eurotrucks2 (Width: 0; Height: 0) 13:17:10: No capture process bound

Emiroe commented 3 years ago

Hey @gatenosix,

I actually solved the issue for myself by completely removing ETS2 Local Radio. Then I reinstalled the latest version version and "installed the plugin".

What I then did is I actually downloaded an older version of the ets2-telemetry.dll and replaced the one ETS2 Local Radio installed with the older version. I used release 1.3.0 instead of 1.4.0.

https://github.com/nlhans/ets2-sdk-plugin/releases/download/revision_4_rel_1_3_0/release_v1_3_0.zip

Then just replace the ets2-telemetry.dll in the Win64 folder in your trucksim installation folder with the one from the win64 folder in the above zip. It solved the issue for me.

Sadly I am using VR and the overlay does not show up in VR. Only on Monitor, but it did fix the issue for me in non-VR.

hadeseol commented 3 years ago

@Emiroe I will have to try this, I did the previous thread and the issue seemed solved but after a couple of times starting the games both started crashing again. In the game.log file there were some telemetry errors so I will check on this.

Edit: Tried this but the games still crash for me.

hadeseol commented 3 years ago

@jacrify unfortunately I don't use that plugin or a wheel.

Koenvh1 commented 3 years ago

@Emiroe @gatenosix @hadeseol @jacrify

Here is a version that should log exactly where it crashes. I added 34 print logs, which should show up in your Error log.txt file. Depending on which is the last entry, I might be able to find out what causes the crash. Do you think you could test it, and send me the result of the log? Apart from the logging, it is identical to v3.2.0.

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using Capture;
using Capture.Hook;
using Capture.Interface;
using ETS2_Local_Radio_server.Properties;
using Svg;

namespace ETS2_Local_Radio_server
{
    static class Station
    {
        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle);

        public struct Rect
        {
            public int Left { get; set; }
            public int Top { get; set; }
            public int Right { get; set; }
            public int Bottom { get; set; }
        }

        public static string NowPlaying = "Now playing:";
        public static bool RTL = false;

        public static int Width = 0;
        public static int Height = 0;

        public static CaptureProcess CaptureProcess = null;

        public static System.Timers.Timer Timer = new System.Timers.Timer();

        public static void SetStation(string name, string signal, string logoPath = null)
        {
            try
            {
                if (Settings.Overlay)
                {
                    if (CaptureProcess == null || CaptureProcess.Process.HasExited)
                    {
                        AttachProcess(Main.currentGame == "ets2" ? "eurotrucks2" : "amtrucks");
                        Log.Write("No capture process bound");
                        if (CaptureProcess == null)
                        {
                            return;
                        }
                    }

                    Log.Write("Station 1");
                    Rect rectangle = new Rect();
                    Log.Write("Station 2");
                    GetWindowRect(CaptureProcess.Process.MainWindowHandle, ref rectangle);
                    Log.Write("Station 3");
                    Width = rectangle.Right - rectangle.Left;
                    Height = rectangle.Bottom - rectangle.Top;

                    Log.Write("Station 4");
                    Image bmp = new Bitmap(Resources.overlay_double);

                    Log.Write("Station 5");
                    RectangleF rectf = new RectangleF(0, 0, bmp.Width, bmp.Height);

                    Log.Write("Station 6");
                    Graphics g = Graphics.FromImage(bmp);

                    if (Settings.VR)
                    {
                        g.TranslateTransform(0, bmp.Height);
                        g.ScaleTransform(1, -1);
                    }
                    Log.Write("Station 7");

                    //g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

                    StringFormat format = new StringFormat()
                    {
                        Alignment = StringAlignment.Center,
                        LineAlignment = StringAlignment.Center
                    };
                    Log.Write("Station 8");
                    var font = new Font("Microsoft Sans Serif", 15, FontStyle.Bold);
                    Log.Write("Station 9");

                    var stringSize = g.MeasureString(NowPlaying + " " + name, font);
                    var nowPlayingSize = g.MeasureString(NowPlaying + " ", font);
                    var nameSize = g.MeasureString(name, font);
                    Log.Write("Station 10");
                    var topLeft = new PointF((512 / 2) - (stringSize.Width / 2) + 123,
                        (bmp.Height / 2) - (stringSize.Height / 2));
                    //var rectangle = new Rectangle(0, 0, (int)stringSize.Width, (int)stringSize.Height);
                    var brush = new SolidBrush(Color.FromArgb(255, 174, 0));
                    Log.Write("Station 11");
                    //var brush = new LinearGradientBrush(rectangle, Color.White, Color.FromArgb(255, 174, 0), 0.0f, false);
                    if (RTL)
                    {
                        g.DrawString(name, font, brush, topLeft);
                        g.DrawString(NowPlaying, font, Brushes.White, new PointF(topLeft.X + nameSize.Width + nowPlayingSize.Width, topLeft.Y), new StringFormat { FormatFlags = StringFormatFlags.DirectionRightToLeft });
                    }
                    else
                    {
                        g.DrawString(name, font, brush, new PointF(topLeft.X + nowPlayingSize.Width, topLeft.Y));
                        g.DrawString(NowPlaying, font, Brushes.White, topLeft);
                    }
                    Log.Write("Station 12");

                    switch (signal)
                    {
                        case "0":
                            g.DrawImage(Resources.signal_0, 593, bmp.Height - 36, 32, 32);
                            break;
                        case "1":
                            g.DrawImage(Resources.signal_1, 593, bmp.Height - 36, 32, 32);
                            break;
                        case "2":
                            g.DrawImage(Resources.signal_2, 593, bmp.Height - 36, 32, 32);
                            break;
                        case "3":
                            g.DrawImage(Resources.signal_3, 593, bmp.Height - 36, 32, 32);
                            break;
                        case "4":
                            g.DrawImage(Resources.signal_4, 593, bmp.Height - 36, 32, 32);
                            break;
                        case "5":
                            g.DrawImage(Resources.signal_5, 593, bmp.Height - 36, 32, 32);
                            break;
                    }
                    Log.Write("Station 13");

                    if (logoPath != null)
                    {
                        Log.Write("Station 14");
                        if (logoPath.StartsWith("http"))
                        {
                            Log.Write("Station 15");
                            using (var client = new WebClient())
                            {
                                var newPath = Directory.GetCurrentDirectory() + "\\tmp" + Path.GetExtension(logoPath);
                                client.DownloadFile(logoPath, newPath);
                                logoPath = newPath;
                            }
                            Log.Write("Station 16");
                        }
                        else
                        {
                            Log.Write("Station 17");
                            logoPath = Directory.GetCurrentDirectory() +
                                       @"\web\" + logoPath.Replace("/", "\\");
                        }
                        //var logo = Image.FromFile(Directory.GetCurrentDirectory() + @"\web\stations\images-america\tucson\La Caliente.png");
                        //MessageBox.Show(Directory.GetCurrentDirectory() +
                        //                @"\web\" + logoPath.Replace("/", "\\"));
                        try
                        {
                            Log.Write("Station 18");
                            if (logoPath.EndsWith("svg"))
                            {
                                try
                                {
                                    var img = SvgDocument.Open(logoPath);
                                    logoPath = logoPath.Replace(".svg", ".png");
                                    using (Bitmap tempImage = new Bitmap(img.Draw()))
                                    {
                                        tempImage.Save(logoPath);
                                    }
                                    Log.Write("Station 19");
                                    //img.Save(logoPath, ImageFormat.Png);
                                }
                                catch (Exception)
                                {
                                    logoPath = logoPath.Replace(".svg", ".png");
                                }
                            }
                            Log.Write("Station 20");
                            var logo = new Bitmap(logoPath);

                            var logoHeight = (float)logo.Height;
                            var logoWidth = (float)logo.Width;
                            Log.Write("Station 21");
                            if (logoHeight > 0.41f * logoWidth)
                            {
                                logoWidth = (float)((90f / logoHeight) * logoWidth);
                                logoHeight = 90;
                            }
                            else if (logoHeight <= 0.41f * logoWidth)
                            {
                                logoHeight = (float)((220f / logoWidth) * logoHeight);
                                logoWidth = 220;
                            }
                            Log.Write("Station 22");

                            //MessageBox.Show("bmpw: " + bmp.Width + "; bmph: " + bmp.Height + "; logow: " + logoWidth.ToString() + "; logoh: " + logoHeight.ToString());

                            g.DrawImage(logo, (256 / 2) - (logoWidth / 2) + 645, (bmp.Height / 2) - (logoHeight / 2), logoWidth,
                                logoHeight);
                            Log.Write("Station 23");
                            logo.Dispose();
                            Log.Write("Station 24");
                        }
                        catch (Exception ex)
                        {
                            Log.Write(logoPath);
                            Log.Write(ex.ToString());
                        }
                    }
                    Log.Write("Station 25");
                    g.Flush();

                    //TODO: Get memory picture to work.
                    //MemoryStream ms = new MemoryStream();
                    //bmp.Save(ms, ImageFormat.Png);

                    //GPPICI_LoadNewInternalPicture(ms.ToArray(), (int) ms.Length);
                    //GPPICI_ShowInternalPicturePos(true, (width/2) - (Resources.overlay.Width/2), (height/4));

                    //bmp.Save(Directory.GetCurrentDirectory() + @"\overlay.png");

                    //ImageConverter converter = new ImageConverter();
                    //byte[] overlayImg = (byte[])converter.ConvertTo(Image.FromFile(Directory.GetCurrentDirectory() + @"\overlay.png"), typeof(byte[]));
                    var overlay = new Capture.Hook.Common.Overlay
                    {
                        Elements = new List<Capture.Hook.Common.IOverlayElement>
                        {
                            new Capture.Hook.Common.ImageElement()
                            {
                                Location = new Point((Width / 2) - (bmp.Width / 2), (Height / 4)),
                                Image = bmp.ToByteArray(System.Drawing.Imaging.ImageFormat.Png)
                            }
                        },
                        Hidden = false
                    };
                    Log.Write("Station 26");
                    CaptureProcess.CaptureInterface.DrawOverlayInGame(overlay);
                    bmp.Dispose();
                    Log.Write("Station 27");
                    //GPPIC_LoadNewPicture(Directory.GetCurrentDirectory() + @"\overlay.png");
                    //GPPIC_ShowPicturePos(true, (width / 2) - (bmp.Width / 2), (height / 4));

                    Timer.Interval = 4000;
                    Timer.Elapsed += (sender, args) =>
                    {
                        Log.Write("Station 28");
                        Timer.Enabled = false;
                        Timer.Stop();
                        overlay.Hidden = true;
                        CaptureProcess?.CaptureInterface.DrawOverlayInGame(
                            new Capture.Hook.Common.Overlay
                            {
                                Elements = new List<Capture.Hook.Common.IOverlayElement>()
                            }
                        );
                        Log.Write("Station 29");
                        //GPPIC_ShowPicturePos(false, (width / 2) - (Resources.overlay.Width / 2), (height / 4));
                        //GPPICI_ShowInternalPicturePos(false, (width/2) - (Resources.overlay.Width/2), (height/4));
                        //Log.Write("Hide overlay");
                    };
                    Timer.Enabled = true;
                    Timer.Start();
                    Log.Write("Station 30");
                }
            }
            catch (Exception ex)
            {
                Log.Write(ex.ToString());
            }
        }

        public static void AttachProcess(string name)
        {
            if (CaptureProcess != null)
            {
                Log.Write("Station 31");
                HookManager.RemoveHookedProcess(CaptureProcess.Process.Id);
                CaptureProcess.CaptureInterface.Disconnect();
                CaptureProcess = null;
            }
            Log.Write("Station 32");
            try
            {
                Log.Write("Station 33");
                Process[] processes = Process.GetProcessesByName(name);
                foreach (Process p in processes)
                {
                    if (p.MainWindowHandle == IntPtr.Zero)
                    {
                        continue;
                    }

                    if (HookManager.IsHooked(p.Id))
                    {
                        continue;
                    }

                    CaptureConfig cc = new CaptureConfig()
                    {
                        Direct3DVersion = Direct3DVersion.AutoDetect,
                        ShowOverlay = true
                    };

                    var captureInterface = new CaptureInterface();
                    CaptureProcess = new CaptureProcess(p, cc, captureInterface);
                    Log.Write("Station 34");
                }

                Log.Write("Process attached: " + name + " (Width: " + Width + "; Height: " + Height + ")");
            }
            catch (Exception e)
            {
                Log.Write(e.Message);
            }
        }
    }
}

ETS2 Local Radio server.zip

gatenosix commented 3 years ago

@Koenvh1

Thanks - Just gave it a try, and have attached a copy of the error log.

Error log.txt

hadeseol commented 3 years ago

@Koenvh1 I managed to find my particular issue and posted it on #136 but I ran this version and here is the log. Error log.txt

gatenosix commented 3 years ago

@Koenvh1 I managed to find my particular issue and posted it on #136 but I ran this version and here is the log. Error log.txt

This seems to have sorted the issue for me too.

I created a new profile for ETS2 in RivaTuner to disable the overlay and it no longer crashes, so it seems like the overlays were conflicting with each other.