The online racing simulator
Searching in All forums
(921 results)
DarkTimes
S2 licensed
What is it you are actually trying to do? I don't understand what the problem is. CompCar doesn't have a public constructor because there is no reason for you to ever construct it, that's handled internally by the library. You will need to give more details about what you are trying to do and what problem you're having. Almost certainly it sounds like you are trying to do something in a strange way.

Edit: If you are getting a NullReferenceException then you need to check that a reference is not null before you use it

if (car != null)
{
// Do something with CompCar.
}

Last edited by DarkTimes, .
Make LFS play nicer with Windows 7 UAC
DarkTimes
S2 licensed
I've been running Windows 7 for a month or so now, and LFS runs great on it, but it's quite annoying that LFS does not obey the UAC (User Account Control). You have to run LFS in administrator mode, otherwise it uses UAC virtulization, meaning that all the settings and files are written to hidden directories you need to unlock to see.

Really, in this modern age, LFS should respect the user and system security modes of modern operating systems, and store program files and personal files in the right places. This would also have the secondary benefit that LFS would give each user of the PC their own profile.

I seem to remember this idea being shot down back when the installer was added, but the fact is that the UAC exists for a reason, to improve security, and it seems only right that LFS should respect the security settings that a computer may have. There is no reason for LFS to require extra clearance, while other programs do not. It is not hard, speaking as a programmer, to write code that obeys Windows 7's security modes, it just takes a bit of forethought.

I know some people will say that they don't use UAC, and that's cool, but there are others who do use it, and should be encouraged to use it, and LFS should respect that.

Here is a short technical article on how to make a game that works on least privileged user accounts. This is not for LFS devs (obviously) just for interested parties.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
You should use a revision control system, such as Mercurial. That way you can just merge my update with your own script and it will apply the new changes automatically. I can convert my update to a source patch if you need.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Heya I updated my little cruise script example. I fixed the UDP bug in pyinsim a long time ago, so I re-enabled UDP updates for MCI packets. I also added welcome message that's displayed to each player when they connect. You might want to update this to change the web site URL and remove the swearing.
DarkTimes
S2 licensed
Quote from learjet45 :Oh, and yet another thing. I can't seem to find anything to distinguish AI from regular players with InsimSniffer, and I'm trying to code in AI detection so people can't use AI.

Sorry didn't see your post before. You can use the PType property of the NPL packet, it contains various bit flags about the player type. You're correct this information is not easily accessible using InSimSniffer, I'll put it on the todo list.

# byte PType; // bit 0 : female / bit 1 : AI / bit 2 : remote

def npl(insim, npl):
if npl.PType & 2:
print '%s is an AI!' % npl.PName

Last edited by DarkTimes, .
DarkTimes
S2 licensed
OK - here is an example of making a !location command.

import pyinsim

players = {}

def npl(insim, npl):
# Create class variable on NPL packet to store current XYZ.
npl.xyz = [0,0,0]
players[npl.PLID] = npl

def pll(insim, pll):
del players[pll.PLID]

def ism(insim, ism):
#Request player list.
insim.send(pyinsim.ISP_TINY, ReqI=1, SubT=pyinsim.TINY_NPL)

def mso(insim, mso):
# Parse command.
if mso.UserType == pyinsim.MSO_PREFIX:
msg = mso.Msg[mso.TextStart:]
if msg == '!location':
# Send player's XYZ.
npl = players[mso.PLID]
insim.sendm('X: %d Y: %d Z: %d' % (npl.xyz[0], npl.xyz[1], npl.xyz[2]), ucid=mso.UCID)

def mci(insim, mci):
for car in mci.Info:
npl = players.get(car.PLID)
if npl:
# Set XYZ (convert LFS coords to meters)
npl.xyz = [pyinsim.length(car.X), pyinsim.length(car.Y), pyinsim.length(car.Z)]

insim = pyinsim.insim('127.0.0.1', 29999, Prefix='!', Flags=pyinsim.ISF_MCI, Interval=500)
insim.bind(pyinsim.ISP_NPL, npl)
insim.bind(pyinsim.ISP_PLL, pll)
insim.bind(pyinsim.ISP_ISM, ism)
insim.bind(pyinsim.ISP_MSO, mso)
insim.bind(pyinsim.ISP_MCI, mci)
insim.send(pyinsim.ISP_TINY, ReqI=1, SubT=pyinsim.TINY_ISM)
pyinsim.run()

We store a list of each NPL packet and create a new property called 'xyz', then whenever an MCI packet is received we update the 'xyz'. After that all we need to do is output the coords whenever someone types the command !location.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from juliao :insim not initialised

error ->l insim password does not match your multiplayer admin password

help

http://www.4shared.com/photo/gQ-Pias7/erro.html

You need to set the InSim password, which can be found in Project > Project Settings > InSim. If you don't know your InSim password, you can find it by opening the file LFS\cfg.txt and looking for the line Game Admin. It's the same admin password you use when logging onto a multiplayer host.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from Litro :Hm,I don't know how to make realtime video of pictures. I can't find out it. Anyone help ?

Practically any video editing program can do this. A popular choice is the free VirtualDub.
DarkTimes
S2 licensed
Ah, this is a small bug, but also it sounds like you are sending a command that is too long. The maximum length a command can be is 64 characters, as your command is longer than that the sendm method is sending a MSX instead, which doesn't support commands.
DarkTimes
S2 licensed
What is !location supposed to do?

You're just lucky I don't believe in Christmas.
DarkTimes
S2 licensed
Haha, I didn't even think of this one...

Christmas Steps

Quite apt.
DarkTimes
S2 licensed
Have a happy Gabber christmas? I know a few DJs you'd get on great with! I've heard these people play Gabber at weddings...

Just to finish on the Mogwai vibe, Yes, I am a long way from home.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Mogwai Fear Satan

The only song YouTube needs to split into two parts. I grew up a few miles from the place where these guys formed.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I realise I'd haven't mentioned the new OutSim and OutGauge support in the next version of Spark/InSim.NET (source available on CodePlex), it's now only a few lines of code to add OutGauge or OutSim support to your application.

Here is a full OutGauge program that prints your current RPM to the console.

void InitializeOutGauge()
{
// Create OutGauge listener.
using (OutGauge outgauge = new OutGauge())
{
// Hook OutGauge packet event.
outgauge.PacketReceived += new EventHandler<OutGaugeEventArgs>(outgauge_PacketReceived);

// Start listening.
outgauge.Connect("127.0.0.1", 30000);
}
}

void outgauge_PacketReceived(object sender, OutGaugeEventArgs e)
{
// Handle OutGauge packet.
Console.WriteLine("RPM: {0}", e.Packet.RPM);
}

Simples!

You can download InSim.NET from CodePlex now and compile it yourself, or wait until just after Christmas for the official release.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from JayEyeBee :Nifty. That isn't exactly the problem I was trying to describe (the replay I was using is well over an hour long, but I think there must be a problem with that replay file). Oh well, a more useful report than I thought.

Yeah I know the steps to reproduce it are different, but I believe it's the same actual bug. Those steps I posted are an easily repeatable way to reproduce the error, regardless of the scenario you find yourself in . Still you're right I can never be 100% sure that your bug is not (subtly) different, so we could investigate the matter further.

If you like you can send me your LFSRecord project and the edited replay that causes the issue, that way I can watch the code executing while the error occurs and will be able to confirm that this is indeed the same bug (or not).

If you don't want to upload it here, send me a PM and I'll give you my email address.

Edit: I should just point out that I'm not just a random forum poster, I'm working on this project with Victor.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from JayEyeBee :I'm having an odd problem. I'm using a replay that came from a larger one that had been edited using mpredit into more manageable chunks. (It's pretty time consuming to develop a camera sequence from an incident late in a large replay).
When I play the replay through LfsRecord, it will progress so far then give me an error: "Replay Error: the position you want to play from is beyond the length of the replay." This is less than a minute into a replay of well over an hour. It also will not let me generate a time offset keyframe from farther into the replay.


Edit: This doesn't happen with the original 6 hour long replay, nor a replay of the start of the race generated from mpredit.

Also, when I closed LFS when LFSRecord was displaying this error, LFSRecord crashed.

I like breaking things.


From the crash

OK, thanks for the report. I can indeed reproduce this (both parts) and I'm looking into it.

Edit: It appears that LFSRecord will let you set a replay offset that is longer than the length of the replay. The error message is being sent by LFS to LFSRecord, as LFSRecord is trying to move the replay to a place that doesn't exist.

To easily reproduce this error, load a relatively short replay (say 10 seconds) and set the replay offset to a value that's greater than that (say 20 seconds). Now start playback from the start of the replay. After 10 seconds (when the replay finishes) this error will occur. The reason is that as the replay has ended LFSRecord is trying to set the replay position back to the start, but the start offset is longer than the replay length.

Um... I think I'll leave this one to Victor to fix.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from learjet45 :Not exactly :P
Here is what I've used for quite a bit of the stuff I've done :P

def get_ncn_by_uname(uname):
ncn = filter(lambda n: n.UName == uname, connections.values())
if ncn:
return ncn[0]
return None


That function basically does the same thing in a different way, even then modifying it to be case-insensitive uses the same principle.


def get_ncn_by_uname(uname):
[b]uname = uname.lower()[/b]
ncn = filter(lambda n: [b]n.UName.lower() == uname[/b], connections.values())
if ncn:
return ncn[0]
return None

Quote :Edit: and one more thing. I'm working on my issue with pitting and what not. However, I cannot seem to figure out how to get the connection info for the player who pitted. I need to define ncn so I can change the ncn.vars.pitting value, but I'm not sure how to go about doing that with the PLP packet.

You need to get the NPL for that packet, then use the UCID in the NPL to get the NCN.

def player_left_pits(insim, plp):
npl = players[plp.PLID]
ncn = connections[npl.UCID]

# Do something with ncn...

DarkTimes
S2 licensed
Yes, you need Windows XP SP3 or better, but make sure that you have also got the latest version of the .NET Framework, as LFSRecord uses the .NET Framework 4.0.

You can get it from the Microsoft downloads site, or from Windows update.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I don't remember that function I wrote, but imagine it would be something like this...

def get_ncn_by_uname(uname):
uname = uname.lower()
for ncn in connections.values:
if ncn.UName.lower() == uname:
return ncn
return None

DarkTimes
S2 licensed
Can I ask what video output format people prefer to use? Such as do you like WMV or AVI etc..
DarkTimes
S2 licensed
OK, I've written a small example to show how to handle laps, splits and positions. Laps are contained in the IS_LAP packet, splits in the IS_SPX packet, and positions are included in the IS_NLP packet.

This example is fairly simple - it tracks each player and prints out the name, position, lap time and split times whenever they complete a lap. I've tried to comment each line to explain what it does.

Just to enter a shameless plug you can also use my other program InSimSniffer to watch the packets as they arrive, which can help a lot in understanding how it all fits together.

import pyinsim

# Dict to store players.
players = {}


def insim_multiplayer(insim, ism):
# Whenever we join a host we request the player list to be sent.
insim.send(pyinsim.ISP_TINY, ReqI=1, SubT=pyinsim.TINY_NPL)


def new_player(insim, npl):
# Create class variables on NPL packet to store current
# position and current splits.
npl.position = 0
npl.splits = []

# Add NPL packet to players dict.
players[npl.PLID] = npl


def player_left(insim, pll):
# Delete player from dict.
del players[pll.PLID]


def split_completed(insim, spx):
# get player from dict.
npl = players[spx.PLID]

# add new split.
npl.splits.append(spx.STime)


def node_lap(insim, nlp):
# Loop through each car in the packet.
for car in nlp.Info:
# Get player for this car.
npl = players.get(car.PLID)

# Sometimes, at the start of a race, you can get NLP
# packets before the player list has been received.
if npl:
# Store current race position.
npl.position = car.Position


def lap_completed(insim, lap):
# Get player from dict.
npl = players[lap.PLID]

print 'Player: %s' % pyinsim.stripcols(npl.PName)
print 'Lap: %s' % lap.LapsDone
print 'Position: %d' % npl.position
print 'Time: %s' % pyinsim.timestr(lap.LTime)

# Google list comprehension if you don't understand this line :p
print 'Splits: %s' % ', '.join([pyinsim.timestr(s) for s in npl.splits])

# Blank line.
print ''

# Reset splits so they're ready for next lap.
npl.splits = []


if __name__ == '__main__':
# Create new InSim connection object.
insim = pyinsim.insim('127.0.0.1', 29999, Admin='', Flags=pyinsim.ISF_NLP, Interval=500)

# Bind events.
insim.bind(pyinsim.ISP_ISM, insim_multiplayer)
insim.bind(pyinsim.ISP_NPL, new_player)
insim.bind(pyinsim.ISP_PLL, player_left)
insim.bind(pyinsim.ISP_LAP, lap_completed)
insim.bind(pyinsim.ISP_SPX, split_completed)
insim.bind(pyinsim.ISP_NLP, node_lap)

# Request host packet on connecting.
insim.send(pyinsim.ISP_TINY, ReqI=1, SubT=pyinsim.TINY_ISM)

# 3, 2, 1 GO!
pyinsim.run()

Last edited by DarkTimes, .
DarkTimes
S2 licensed
You would need to suspend then resume the distance update while you are sending them to the pits. Add a flag to the user vars, something like is_pitting, then before you send the pit command set that to true. Then when updating the distance check to see if that flag is set, if it is then don't add any distance for them. Once they leave the pits you can set the flag back to false.
DarkTimes
S2 licensed
The command parsing code splits the command into a list of words, so for instance the command:

!give DarkTimes 2000

Would become a list like:

args = ['!give', 'DarkTimes', 2000]

To turn the list back into a string you can use str.join().

reason = ' '.join(args[1:])

Last edited by DarkTimes, .
DarkTimes
S2 licensed
OK thanks, I had already fixed that error in my version, I just hadn't pushed the changes out to release.

I've uploaded a new version to CodePlex.

This update, with the major-refactorings, does seem to have caused a lot of bugs, sorry.
DarkTimes
S2 licensed
OK cool.
FGED GREDG RDFGDR GSFDG