The online racing simulator
Searching in All forums
(921 results)
DarkTimes
S2 licensed
I found out recently that Microsoft are only releasing Visual Studio 2012 Express versions for Metro and Web. That means you won't be able to create desktop or even console applications for .NET 4.5 without buying a full version of Visual Studio. You won't be able to create standalone DLLs like InSim.NET either. This is very bad news for hobbyist programmers in general, such as the ones on this forum who write InSim programs. Because of this there is pretty much no point in continuing to create a .NET 4.5 version of InSim.NET, as the hobbyist programmers it's aimed at won't be able to use it.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
You can store a callback using the .NET Action delegate type.

void SomeMethod() { }

// Create an action that points to the method.
Action methodToCall = new Action(SomeMethod);

.NET is smart enough to figure out what to do if you leave out the object instantiation.

// Does the same thing as above.
Action methodToCall = SomeMethod;

Then you can just call the action delegate like you would a normal method.

methodToCall();

If you want to pass a parameter it would look like this:

void SomeOtherMethod(string param1, int param2) { }

Action<string, int> otherMethod = SomeOtherMethod;

otherMethod("Hello", 1234);

If you want the method to return a value, you can use the builtin Func delegate type.

bool MethodWithReturn(string param1) { return true; }

// Use a func if there is a return value.
Func<string, bool> returnMethod = MethodWithReturn;

bool result = returnMethod("Hello");

There's a lot more to delegates, but that's enough to get you through most problems.
DarkTimes
S2 licensed
There is a repo on SourceForge (http://lfslapper.svn.sourceforge.net/viewvc/lfslapper/) but it doesn't seem to have been updated recently. I'm not sure where the latest revisions are.
DarkTimes
S2 licensed
I've made a few big changes in the last few days.

Firstly I pushed the development version of pyinsim 3.0.0 to codePlex, overwriting the old repository. I wasn't sure if I was going to do this at first, but I figured that all the old code and old versions will still be there, so people can still find them if they need them.

The second change was to add support for both Python 2.7 and Python 3.0 in a single package. The latest version of pyinsim has support for both versions of Python without any changes. It does this by conditionally declaring and importing several functions depending on which Python version is installed. This wasn't as much effort as I thought it was going to be actually, Python 2.7 and 3.0 are more compatible than you think. That being said, support for two Python versions means twice as many bugs and twice as much testing needed!

Lastly I'm still making some changes to the API. I realised after some thought that what I really needed to do was to eliminate any situation where there was more than one way of doing something. This means that I've finally deprecated the old way of sending packets in favour of the simpler newer version. That means that to send a packet you now always do it like this:

insim.send_packet(IS_MST(Msg='Hello, InSim!'))

In addition to this change I also renamed the pyinsim 'run' function to the new name of 'main_loop', which I think better describes what it actually is. There was always a lot of confusion as to what the run function did and why it was needed. Now it should be more explicit.

from pyinsim import insim_init, main_loop, IS_MST

insim = insim_init('127.0.0.1', 29999, Admin='')

insim.send_packet(IS_MST(Msg='Hello, InSim!'))

main_loop()

Um, I think that's it for the moment. As mentioned the library still needs a bunch more testing, and I also still need to rewrite the documentation to reflect all the API changes. That being said, it is coming along.

You can find the latest version of pyinsim 3.0.0 in the CodePlex repository.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Well, you did ask for feedback.

1. For some reason the solution won't open in VS2010. That's weird cause VS11 projects are supposed to be backwards compatible now. Anyway, I had to create a new VS10 project and copy all the files and references into it.

2. I'd suggest spending some time reading the .NET Framework Design Guidelines, which contains everything you would ever want to know about naming variables, methods, classes and more. They are just guidelines, so you don't need to follow them to the letter, but I'd recommend following them as much as you can. I find it really easy to tell from looking at code whether someone has read those guidelines or not. There's also this blog post about Microsoft Internal Coding Guidelines, but that's much more down to taste.

The main naming guidelines can be summed up as follows:
  • All private fields and local variables should be lower camelCase
  • Classes, properties and methods should be PascalCase
3. You have named a bunch of your classes with weird names, such as 'Globals', 'Processor', 'Vitals'. Aside from 'globals' (more on that in a minute) I've no idea what any of them mean. I'd highly suggest using more descriptive names for your classes.

4. Having a global settings class is a bad idea for a bunch of reasons. What I'd suggest is moving this 'data' out of your program into a configuration file. .NET has built-in support for creating Settings files for you automatically (you can create application wide settings, or per-user settings) and also lets you edit them using a pretty(ish) designer UI. Right-click on your project go to Properties > Settings and follow the instructions.

5. You're using a MySQL database which is fair enough I guess. I'd suggest using an embedded database such as SQL Compact or SQLite instead, as they require no setup or configuration and can be easily bundled with your program. MySQL requires you to download, install, configure and run the MySQL Windows Service, which is a total pain and way more hassle than it's worth. In terms of SQL Compact vs SQLite, I'd go with SQL Compact just because it has first class support inside Visual Studio (so you can use the database explorer and designer etc..) and can be easily installed and updated using NuGet.

6. You are executing raw SQL statements in your code, make sure you know about SQL Injection and always parametrise your SQL queries. Instead of executing raw SQL strings you should learn about LINQ, as it's probably the single best feature of the C# programming language.

7. A good tip is to turn on Warning as Errors, which will cause any code warnings to prevent compilation, therefore forcing you to fix them. Go to Properties > Build and set Treat Warnings as Errors to All.

8. Finally I'd advise running a static code analyser over your code. If you are using VS11 Ultimate beta then it has one built in. Right click on your project and select Run Code Analysis. You can configure it by going to Properties > Code Analysis and selecting a rule set. I'd suggest starting off with a basic rule set and gradually enabling more and more rules. Eventually you'll get to a point where either all the problems are fixed, or the things it's suggesting are completely pointless. If you are not using a retail version of Visual Studio then you can download FxCop, which is pretty-much a standalone version of the same thing.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Edit: I removed this feature.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I had looked at how prism handles its timers previously, back when I was implementing something similar for pyinsim. Looking at the code in the PHPInSimMod.php updateSelectTimeout method I think I see what might be the cause of the bug:


<?php 
$sleep 
1;
$uSleep NULL;

$sleepTime NULL;
foreach (
$this->plugins->getPlugins() as $plugin => $object)
{
    
$timeout $object->executeTimers();

    if (
$timeout $sleepTime)
        
$sleepTime $timeout;
}
?>

It seems that the expression $timeout < $sleepTime is comparing an int with a null, which will always evaluate false in PHP. I wasn't sure so I checked it on CodePad and my thinking appears to be correct.

Next in the same method there is this code:


<?php 
# If there are no timers set or the next timeout is more then a second away, set the Sleep to 1 & uSleep to NULL.
if ($sleepTime == NULL OR $sleepTime >= 1)
{    
# Must have a max delay of a second, otherwise there is no connection maintenance done.
    
$sleep 1;
    
$uSleep NULL;
}
?>

It checks if the sleepTime is NULL, which it always is, then assigns the sleep variable a value of one second, which is what accounts for the constant one second stream_select timeout interval.

I think to fix the bug you would need to change the first problematic expression to something like the following:


<?php 
if ($sleepTime == NULL || $timeout $sleepTime)
    
$sleepTime $timeout;
?>

Which would/should/might fix the issue. Of course I might be completely wrong.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Pushed version 1.3.1 onto CodePlex.

Changes in 1.3.1
  • Added ability to combine filter terms by seperating them with spaces (e.g. 'mso sta lap' will show you all IS_MSO, IS_STA, and IS_LAP packets).
  • Fixed bug in IS_PFL where Size, Type and ReqI weren't being set.
DarkTimes
S2 licensed
Quote from Mountaindewzilla :Pic related.

Thanks for the tip, guys.

Ah, that's a bug. If you look carefully you'll notice that the Size is listed a zero as well. The Size, Type and ReqI of the IS_PFL packet was not being set, so it was displaying the default values. The default value for Type is ISP_NONE.

I've fixed the error and pushed InSimSniffer 1.3.1 onto CodePlex.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from Dygear :What he is looking for is the ISP_PFL packet, for player flags.

Ah, OK. Obviously pyinsim supports IS_PFL.

def player_flags(insim, packet):
pass

insim.bind(ISP_PFL, player_flags)

DarkTimes
S2 licensed
Quote from Mountaindewzilla :Is it just me, or is there no IS_NONE class in insim.py?

It'd be nifty as LFS sends a NONE packet when users update their controls. Actually, only when a player is in the player list and updates their controls.

Do you guys think it'd be a good idea to suggest a 'player changed controls' packet in the improvement suggestions forum?

InSim does not have an IS_NONE packet. In fact, I'm struggling to even conceive of how such a packet would look. What is it exactly that LFS sends when the user updates their controls?
DarkTimes
S2 licensed
Quote from PoVo :I'd personally recommend PRISM, since it's very easy to use and the single instance can connect to multiple LFS hosts.

pyinsim will do this as well, it's very simple. Just create as many InSim connections that you want before you call run. This example sends a hello message to anyone that's connected to any of the specified hosts.

import pyinsim

def new_connection(host, ncn):
host.sendm('Hello, %s' % ncn.PName, ncn.UCID)

hosts = [pyinsim.insim('127.0.0.1', 29999, Admin=''),
pyinsim.insim('127.0.0.1', 29999, Admin=''),
pyinsim.insim('127.0.0.1', 29999, Admin='')]

for host in hosts:
host.bind(pyinsim.ISP_NCN, new_connection)
host.send(pyinsim.ISP_TINY, ReqI=1, SubT=pyinsim.TINY_NCN)

pyinsim.run()

Last edited by DarkTimes, .
DarkTimes
S2 licensed
If your computer is getting blue screens it normally means some kind of hardware or driver issue. It sounds like your computer is creating kernel dump files when it crashes, it's possible to analyse these files to find out what the issue is. Check out this blog for information on how to analyse dump files and figure out what the true problem is.

http://mikemstech.blogspot.co. ... -crash-dump-analysis.html

The issue could also be caused by a virus or spyware, so make sure you run full virus and spyware scans, which you can do using free programs like AVG Virus Scan and Malware Bytes. Recently I was getting random blue screens and other issues, and eventually I tracked the problem to a virus that had infected my computer (the first virus I've had in about seven years).

By analysing dump files and using virus/spyware scanners it's almost always possible to figure out exactly what's going wrong.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Nope, sorry. SPR relays only contain hotlap data for the current player, so it's not possible to create a championship from the available info.

Also, I've kinda given up working on this app for the time being. If I were to revive LFSPoints I would do so as a web site, instead of a desktop app. A online league management web site sounds like a fun idea, but I would need to determine if there was an audience for it. There's not much point in launching anything like that at the moment though, as LFS itself is pretty much dormant until the next release appears. With the current LFS situation the number of interested users is only ever going to decrease, which means the site would become less and less useful over time, which gives me less and less enthusiasm for building it.
DarkTimes
S2 licensed
Has anyone had a chance to checkout the InSim.NET 3.0 stuff I posted a week or so ago? It features a quite radical (for the most part) redesign of the core API, so I'd appreciate any feedback, especially bad feedback, from people who've tried it.

You can find the development repository on my BitBucket account (it's like GitHub except for Mercurial source control). You can either download the source as a .zip file, or clone the repository with the command:

hg clone https://bitbucket.org/alexmcbride/insimdotnet

You can find an excellent tutorial on using Mercurial at hginit.com. Mercurial is like Git, except simpler to use and much more Windows friendly. You don't have to use the source control though, just download the zip by clicking the 'get source' link on the far-right.

If you don't understand the new InSim.NET API, let me know, and I'll post some more example code. I am hopeful, however, that you should be able to figure out how it works purely by looking at the intellisense data inside Visual Studio, as that's how I tried to design it.

Anyway, let me know what you think!

Edit: For extra credit I've also made public my InSimSniffer WPF port on BitBucket. It's a version of InSimSniffer I wrote a few weeks ago, that ports the UI to WPF using the MVVM design pattern. I wrote it in a day and a bit, so the code isn't super-awesome. I didn't see the point in releasing it as it doesn't add any extra functionality over the original app, although I might in the future. Still, the presence of such code might interest a few other .NET developers on here.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I have created a NuGet package for InSimDotNet, which makes it very easy to download and install the library in your Visual Studio project. Here are the steps to use it.
  • Create a new Visual Studio project
  • Go to View > Other Windows > Package Manager Console
  • In the console type 'Install-Package InSimDotNet' then hit enter
  • That's it!
Visual Studio will now download and install the library automatically!

If you are using Visual Studio 11 Beta you can also use the option Project > Manage NuGet Packages, which will allow you to use the new Package Manager UI. Once the manager has opened, just click Online tab and search for 'InSimDotNet', finally click install.

This is the first NuGet package I've created, so let me know if you have any problems.

I created a screenshot with the Package Manager Console at the bottom and the Package Manager UI in the centre, to help people show what I'm talking about.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from hyntty :Sorry to derail the thread but could someone care to explain that line?

It's called method chaining. Each method returns an instance of the object the method was called on, which allows you to chain the method calls together in this way. The code snippet just instantiates a new BTN object, then sets its various properties.
DarkTimes
S2 licensed
I've been messing around with Entity Framework Code First for .NET and it's really useful for making little databases, such as you would use in a InSim program. I figured I'd do a quick tutorial on using it, as it's really very simple.

First of all boot up Visual Studio 2010 and create a new C# Console Application project, call it what you like. Before we can use the EntityFramework we'll need to include the assemblies in our project, but this is easy using the .NET package manager, called NuGet. In Visual Studio go to View > Other Windows > Package Manager Console and in the console window type the following command then hit enter.

Install-Package EntityFramework

This should download and install the EntityFramework for you automatically. Now we need to create a simple model to store in the database, which for the purposes of this example will represent a simple cruise server. Here is the code for the model


<?php 
public class User {
    public 
int ID getset; }
    public 
string UserName getset; }
    public 
string PlayerName getset; }
    public 
int Cash getset; }
    public 
virtual List<CarCars getset; }
}

public class 
Car {
    public 
int ID getset; }
    public 
int UserID getset; }
    public 
string CarName getset; }
    public 
User User getset; }
}
?>

We create a User object and a Car object, that will have a one-to-many relationship. One user will have many cars, one car will have one user. As the EntityFramework follows a convention over configuration coding style, the relationships between the keys will be setup for us automatically. We will be able to access a user's cars through the User.Cars property, and access a car's user through its Car.User property.

Next we need to create a DbContext for our model, which will represent our connection with the database, and also tell the EntityFramework which model classes to use. This is extremely simple code.


<?php 
public class CruiseContext DbContext {
    public 
DbSet<UserUsers getset; }
    public 
DbSet<CarCars getset; }
}
?>

Finally we need to tell the EntityFramework which database we want to use to store our data. By default it uses a SQLServer Express instance to store it, but I'd rather use SQLServer Compact instead, as it's simpler. SQLServer Compact is a simple file-based database, similar in nature to SQLite, that requires no installation or configuration. It can store up to 4GB of data if I remember correctly, so it's very useful for this kind of thing. Anyway, open you projects app.config file and change to contents to look like this:


<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<connectionStrings>
<add name="CruiseContext"
providerName="System.Data.SqlServerCe.4.0"
connectionString="Data Source=CruiseDB.sdf"/>
</connectionStrings>
</configuration>

The important bit is the connectionStrings element, which we use to define which database our 'CruiseContext' is to use. The 'System.Data.SqlServerCe.4.0' bit tells it to use a SQLServer Compact 4.0 database, and 'CruiseDB.sdf' is used to specify the actual name of the database file where we want to store our data. If this file does not exist then the EntityFramework will create it for us. If we delete it, it will recreate it.

Now all that's left is to write some code that actually access our database and saves and retrieves some data in order to test (prove) that it's working.


<?php 
class Program {
    static 
void Main() {
        
// Save some data to the database.
        
SaveUserToDatabase();

        
// Read the data back out of the database.
        
RetrieveUserFromDatabase();

        
Console.ReadLine();
    }

    private static 
void SaveUserToDatabase() {
        
// Create database connection.
        
CruiseContext db = new CruiseContext();

        
// Create a new user.
        
User user = new User {
            
UserName "DarkTimes",
            
PlayerName "Alex",
            
Cash 1000,
            
Cars = new List<Car>(), // empty car list
        
};

        
// Add some cars.
        
user.Cars.Add(new Car CarName "UF1" });
        
user.Cars.Add(new Car CarName "XFG" });
        
user.Cars.Add(new Car CarName "XRG" });

        
// Add the user to the database.
        
db.Users.Add(user);

        
// Save the changes to the database.
        
db.SaveChanges();
    }

    private static 
void RetrieveUserFromDatabase() {
        
// Create new database connection.
        
CruiseContext db = new CruiseContext();

        
// Query the database for the user.
        
User user = (from u in db.Users
                     where u
.UserName == "DarkTimes"
                     
select u).Single();

        
// Write the user info to the console.
        
Console.WriteLine("UserName: {0}"user.UserName);
        
Console.WriteLine("PlayerName: {0}"user.PlayerName);
        
Console.WriteLine("Cash: {0}"user.Cash);
        
Console.WriteLine("Cars:");

        foreach (
Car car in user.Cars) {
            
Console.WriteLine(car.CarName);
        }
    }
}
?>

It might take a few moments for the program to run the first time you start it, as it needs to create the database and all the tables etc.. but after that the performance should be fine.

Well, it looks like more work than it really is the first time you see it, once you've tried it, however, you'll see that it makes it very simple and easy to create a database for your InSim app. I've found it very useful.

Here is the complete project to download.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I have pushed the development version of InSim.NET 3.0 onto BitBucket, as after stalling for a while, the development is coming along quite nicely now. Still lots of work to do, things to fix and code to refactor, but I'm reasonably happy with it.

https://bitbucket.org/alexmcbride/insimdotnet

I'll do a write up of the changes soon, but here's a basic code example to show how the new API changes are working. It's important to note that this version of InSim.NET is not backwards compatible, it has lots of big breaking changes and won't work with code written for older versions of the library. Currently the library supports .NET 4.0 and .NET 4.5, but because of changes to the way packets are created it no longer supports .NET 3.5.


<?php 
// InSim.NET 3.0 Example Code

using System;
using System.Text;
using System.Threading;
using InSimDotNet;
using InSimDotNet.Packets;

namespace 
InSimTest {
    class 
Program {
        static 
void Main() {
            new 
Program().Run();
        }

        
void Run() {
            
// Set console to unicode encoding (you also need to set 
            // the console to use a unicode font in Windows).
            
Console.OutputEncoding = new UTF8Encoding();

            
// Create new InSim object.
            
InSimClient client = new InSimClient();

            
// Hook up packet events.
            
client.Version += client_Version;
            
client.MessageOut += client_MessageOut;

            
// Initialize InSim.
            
client.Initialize(new InSimSettings {
                
Host "127.0.0.1",
                
Port 29999,
                
Admin String.Empty,
            });

            
// Send message packet to LFS.
            
client.Send(new MessageTypePacket {
                
Message "Hello, InSim!"
            
});

            
// Stop program from exiting while LFS is connected.
            
while (client.IsConnected) {
                
Thread.Sleep(100);
            }
        }

        
void client_Version(object senderPacketEventArgs<VersionPackete) {
            
// Write version info to the console.
            
Console.WriteLine(
                
"Version: {0}{1} InSim: {2}",
                
e.Packet.Product,
                
e.Packet.Version,
                
e.Packet.InSimVersion);
        }

        
void client_MessageOut(object senderPacketEventArgs<MessageOutPackete) {
            
// Write any messages typed by users to the console.
            
if (e.Packet.UserType == UserType.User) {
                
Console.WriteLine("Message: {0}"e.Packet.Message);
            }
        }
    }
}
?>

I'd urge anyone trying it to pay attention to the API and intellisense in Visual Studio, as it's been designed to help you adapt from the old version as seamlessly as possible.

As it's not even a beta version yet, it will have one or three bugs, also the API may still change wildly before it's finished.
DarkTimes
S2 licensed
Quote from broken :I have this very basic question. When you go to the Visual Studio 11 download page, which download should I pick? (I told you it was very basic)

There is a simple download page here: http://www.microsoft.com/download/en/details.aspx?id=28975

I downloaded Visual Studio 11 Ultimate beta as an ISO. That way you can either burn it to disk or use a disk mounter like VirtualCloneDrive to install it. Alternatively you can download the web installer, which will download and install it automatically. Personally I prefer having an ISO as that way if there are problems with the install it's easy to reinstall it. I've not tried the Express versions.
DarkTimes
S2 licensed
In order to access the Windows user32.dll with Java you can use Java Native Access library. You would then need to read the documentation to figure out how to call the Win32 keybd_event function.

As MadCatX says it's a bit easier using C# as the .NET Framework has builtin support for calling native libraries on Windows. You can find out more about invoking the Win32 API using C# at pinvoke.net.
DarkTimes
S2 licensed
You just set the flag to ISS_SHIFTU and LFS will switch to SHIFT+U mode.

From InSim.txt:

// The ISS state flags that can be set are :

// ISS_SHIFTU - in SHIFT+U mode
// ISS_SHIFTU_FOLLOW - FOLLOW view
// ISS_VIEW_OVERRIDE - override user view

// On receiving this packet, LFS will set up the camera to match the values in the packet,
// including switching into or out of SHIFT+U mode depending on the ISS_SHIFTU flag.

You can also set SHIFT+U mode by sending a key-press:

insim.Send(new IS_SCH {
CharB = 'U',
Flags = CharacterModifiers.SHIFT,
});

Edit: I realised now that you might be trying to use this on a dedi-server, which won't work. Switching to SHIFT+U mode only works if you're connected to a local copy of LFS.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
There is a tutorial on using OutSim and OutGauge on the InSim.NET web site.
DarkTimes
S2 licensed
Nope, I have no format education in Python or any other programming topic.
DarkTimes
S2 licensed
Quote from CheerioDM :If any of you know Python, how did you learn?

I used Dive Into Python to learn Python.
FGED GREDG RDFGDR GSFDG