The online racing simulator
Quote from davidmd :Hi,
I'm trying to send to spectator a player, now I have the playerId, but I have could figured out how to send a packet forcing a player to spectate. Any help would be really appreciated.
Thanks.

If you want to force a player to spectate you need to find out their license name. This is the the value returned by the "getUsername()" method in the NewConnectionResponse class associated with the player's connection. To find out which connection is associated with the player you need to use the value returned by the "getConnectionID()" method in the NewPlayerResponse. When have the player's connectionID you can get the username of the player's connection by using the "getUsername()" as I said above. When you know the player's license name you have to send the following command to LFS:

/spec amp88

Where you replace the "amp88" with the player's license name. To send the command to LFS you need to create a new MessageRequest containing the above String then send it to the client. Let me know if that's enough information for you or if you're still struggling.
Got it, thank you very much.

client.send(new MessageRequest("/spec " + lfsid));

Hi,
Now I'm working on an application to check the tyre compound at the beginning of the race and when does the player make a pit stop and change it. And I have found a problem, in the replay (at the end of the post) at about 3:45 minutes of the replay time, the player named 24[GRP]Ivan, made a pit stop, he came with the following tyre compound "Tyres [rearLeft=0, rearRight=0, frontLeft=0, frontRight=0]" (R1 type) and when the PitStopResponse event is generated, the tyres report "Tyres [rearLeft=-1, rearRight=-1, frontLeft=1, frontRight=1]" (should be R2(1) in front and R1(0) in rear). The problem is that there is no tyre type -1, it should be 0 (unless I don't understand something ).

am I correct??

REPLAY:
http://rapidshare.com/files/287554441/testing.mpr.html
At the start of the race 24[GRP]Ivan has R1 tyres back and front (all of his tyres are equal to the value 0). When he pits he changes his front tyres to R2 compound but leaves his rears at R1 compound. Now his front tyres are equal to the value 1 (which corresponds to R2) and his rears have the value -1. Now, the -1 value doesn't correspond to any tyre type (like R1, R2, R3) but what it means is that those tyres haven't been changed. If you take a look at the source code of the Tyres.java class you'll see more:

public static final byte TYRE_R1 = 0;

public static final byte TYRE_R2 = 1;

public static final byte TYRE_R3 = 2;

public static final byte TYRE_R4 = 3;

public static final byte TYRE_ROAD_SUPER = 4;

public static final byte TYRE_ROAD_NORMAL = 5;

public static final byte TYRE_HYBRID = 6;

public static final byte TYRE_KNOBBLY = 7;

public static final byte NOT_CHANGED = (byte)0xff;

The value (byte) 0xff which represents the NOT_CHANGED value is equal to -1 (you can find this out by doing a System.out.println((byte) 0xff).
OK, once again thank you very very much for your help. Now I see what I was doing wrong. I'll take a look at the source code before.
No problem, glad to help
Something that's been bugging me for a while. If your own LFS project uses Log4J and you are logging at the debug level you also get debugging information that's being generated by JInSim. Is there any way to stop this debugging information being generated by JInSim (like a static global flag?) other than changing my own debugging level?
Log4j comes with all you need. Here is an example configuration that sets the global log level to info and the log level for all classes under com.mypackage to debug.


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>

<logger name="com.mypackage">
<level value="debug"/>
</logger>

<root>
<priority value ="info"/>
<appender-ref ref="STDOUT"/>
</root>

</log4j:configuration>

Quote from Brilwing :Log4j comes with all you need. Here is an example configuration that sets the global log level to info and the log level for all classes under com.mypackage to debug.

Thanks, I'd forgotten about setting specific log levels for different packages
#161 - apm
Could you guys guide me, I cant even get these examples to work. What I am doing wrong?
C:\Users\user\Desktop\prkl\jinsim-0.3>java -cp dist/jinsim-0.5.rc5.jar net.sf.ji
nsim.examples.helloworld.Main localhost 10000
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lo
gging/LogFactory
at net.sf.jinsim.AbstractChannel.<clinit>(AbstractChannel.java:17)
at net.sf.jinsim.examples.helloworld.Main.run(Main.java:93)
at net.sf.jinsim.examples.helloworld.Main.main(Main.java:150)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFacto
ry
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
... 3 more

Running on LFS Z25 with launch paremeter /insim=10000.
Quote from apm :Could you guys guide me, I cant even get these examples to work. What I am doing wrong?

C:\Users\user\Desktop\prkl\jinsim-0.3>java -cp dist/jinsim-0.5.rc5.jar net.sf.jinsim.examples.helloworld.Main localhost 10000
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at net.sf.jinsim.AbstractChannel.<clinit>


The JInSim library uses a logging library that you need to specify on the class path to run any of the examples. A version of the required library is located in the lib directory. Try the following command to run the example instead:

java -cp dist\*;lib\*; net.sf.jinsim.examples.helloworld.Main 127.0.0.1 10000

What this does (by specifying the dist\* and lib\* classpath entries) is to put the logging library on the classpath. Also it's worth noting that I've replaced the "localhost" for the host parameter with "127.0.0.1". I've found that Vista and Java don't get on well together with "localhost" (I don't know if you're using Vista, but it's just something to put in the mind of anyone who does run Vista and looks at this thread). Good luck and happy coding
#163 - apm
Quote from amp88 :The JInSim library uses a logging library that you need to specify on the class path to run any of the examples. A version of the required library is located in the lib directory. Try the following command to run the example instead:

java -cp dist\*;lib\*; net.sf.jinsim.examples.helloworld.Main 127.0.0.1 10000

What this does (by specifying the dist\* and lib\* classpath entries) is to put the logging library on the classpath. Also it's worth noting that I've replaced the "localhost" for the host parameter with "127.0.0.1". I've found that Vista and Java don't get on well together with "localhost" (I don't know if you're using Vista, but it's just something to put in the mind of anyone who does run Vista and looks at this thread). Good luck and happy coding

Thanks for quick reply and solving my problem . You were correct about localhost , as I'm running on Windows 7. Looking forward to spend some time with java on vacation .
Hello guys,

please I have problem. How I send a keypress from my program with jinsim ? I try write software for blinking headlight. Thank you.
Just use the MessageRequest class.

e.g.

MessageRequest msgRequest = new MessageRequest();
msgRequest.setMessage("/press 3"); // turns on and off the headlights
client.send(msgRequest);

You can use the helloworld/Main.java example that is included in jinsim so see a full example how a message request is send.
thank you a lot man ! lights,blinkers works, but now I have problem with ignition. the script command /press I not works, Its posible to cut the ignition from jinsim ? i found the program in c# where the ignition cut works. sorry for wasting your time man.
I receive OutSim and OutGauge packets , based on the Speedometer example.

I can receive OutGauge packets _or_ OutSim packets very well, everything works. But not at the same time.

If I set...
client.enableOutGauge(1);
client.enableOutOutsim(1);

Monitoring the response I see no OutGauge packets only OutSim recieved. (response.toString)

(If I turn off OutSim, OutGauge packtes come.)

Any ideas what do I do wrong? I tried everything and googled for a day, but nothing moved me further.

Thanks in advance, and respect for the effort, jinsim seems to be a bliss form my motionsim project.
Well maybe my above post was not clear enough. Lets say, it's becouse I'm not a native speaker, and I was tried.

Nevertheless, I found the solution. I think it's a bug in OutChannel.java.

So the problem is, if both OutSim and OutGauge packages are sent by LFS, jinsim will interpret both as OutSim packages. From the user perspective it makes virtually no OutGauge packages received, and every second OutSim packages contains incorrect values. (This second packages are the OutGauge packages, only jinsim process them as they were OutSim packages.)

My solution was to change the run method of OutChannel.java.
I deleted every buffer.slip(); lines, and inserted buffer.position(0); at the end of the two if section.

I think the problem with the original, that the buffer.flip of the if else section sets the buffer limit to 68 (the last package's size). So after this every buffer.position(); reading will give 68 and will never go into the first if.

I run LFS on a PC, and jinsim on a laptop, that runs Ubuntu and connected via wireless to the PC. Just for the record, but I don't think this is an issue.
In which version of JInSim does this happen? I have 0.5-rc5 here and the code looks like it should work.

Perhaps calling buffer.clear() instead of the second buffer.flip() in each if-block would be a good idea, but other than that I think the code is OK in 0.5-rc5.
0.5RC5
Looking at the code, I don't think it could work otherwise, than buggy. But I'm not a veteran programmer, so I might miss something.
The code in question is as follows:


public void run() {
running = true;

ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
buffer.order(ByteOrder.LITTLE_ENDIAN);

while (running) {
try {

datagramChannel.receive(buffer);

if (buffer.position() == OUT_GAUGE_SIZE) {
buffer.flip();

OutGaugeResponse reponse = new OutGaugeResponse();
reponse.construct(buffer);
client.notifyListeners(reponse);
buffer.flip();


} else if (buffer.position() == OUT_SIM_SIZE || buffer.position() == OUT_SIM_SIZE - 4) {
buffer.flip();

OutSimResponse response = new OutSimResponse();
response.construct(buffer);
client.notifyListeners(response);
buffer.flip();
}
Thread.sleep(10);
} catch (Exception e) {
log.error("Something went wrong!", e);
}
}
}


I can't fool around with it right now, but shouldn't this work?

try {
datagramChannel.receive(buffer);

if (buffer.position() == OUT_GAUGE_SIZE || buffer.position() == 92 //OutGauge size without ID) {
buffer.flip();
OutGaugeResponse reponse = new OutGaugeResponse();
reponse.construct(buffer);
client.notifyListeners(reponse);
buffer.clear(); //CHANGED
} else if (buffer.position() == OUT_SIM_SIZE || buffer.position() == OUT_SIM_SIZE - 4) {
buffer.flip();
OutSimResponse response = new OutSimResponse();
response.construct(buffer);
client.notifyListeners(response);
buffer.clear(); //CHANGED
}
Thread.sleep(10);
}

Maybe you misunderstand me.
The solution that i was posted works for me.
I think yours works too.
Maybe instead buffer.position(0) is better buffer.clear.

But the problem is buffer.flip I think. I dont really see the point of buffer.flip in the original code. As far I know it sets the new limit to the current position, and then sets position to zero.

The problem is with the original, that buffer.flips sets buffer limit to 68 (since OutSim package comes first) thats why the new buffer size becomes 68 bytes.

So, there will be never again 96 bytes buffer, because it is capped to 68 bytes to the rest of eternity. The next flips just "changes" form 68 to 68 again.

So the next OutGauge package fills the newly set 68 bytes buffer (the remaining bytes are ignored) and continues its life as an OutSim package (with completly meaningless data of course).

In other words we cant differ packages by size, if the buffer is set to the size of the smaller package. And that is what OutSim's buffer.flip does.

Am I thinking right?
Quote :
I deleted every buffer.slip(); lines, and inserted buffer.position(0); at the end of the two if section.

It was the word "every" in this sentence that got me confused, I thought you somehow got rid of flipping the buffer altogether.

Does this code work in every case? The way I see it the current core ignores the possibility of an OutGauge packet with no ID which is only 92 bytes long.
Yes, I deleted all the buffer.flip lines.
I tried yours, it works too.

Quote : The way I see it the current core ignores the possibility of an OutGauge packet with no ID which is only 92 bytes long.

Yes, you are right I think.

It misses the OR relation, that OutSim's IF ELSE has.

else if (buffer.position() == OUT_SIM_SIZE || buffer.position() == OUT_SIM_SIZE - 4)

Just looking through outguage, I understand what most of the flags are, except OG_1 OG_2 OG_3 OG_4, what are they?

FGED GREDG RDFGDR GSFDG