How to send data with lidgren while Distribution is ON

Oct 6, 2009 at 7:49 AM

Hi,

first i wanna say, that this library is awesome.

Q: How could i ( if its even possible ) code chat server/client? How to send string data? ( I can do this with lidgren, but not with Kaleta )

Q2: If strings are not possible to distribute, how can i do it with lidgren? If i send data manually, everything breaks up, becouse if i try to read my message, it could be distributed message and therefor it crashes everything.

 

Needed In this kind of situations:

  • Sending Username/Password
  • Sending Message to other players ( ie. chat )

 

Thanks in advance. Hope you can answer fast, so i can get around this somehow.

 

-Katu

Coordinator
Oct 6, 2009 at 9:00 AM

Hi,

I am glad hearing that! As for your questions: the distribution library CAN serialize the string type, e.g. in class definition:

private DistributableProperty<string> _str;

[Distribute]
public string Str {get { return _str.GetValue(); } set { _str.SetValue(value); } }

in class constructor:
str = DistributableProperty<string>.Register("Str", this);

please refer to the tutorials, where basic & more advanced stuff is explained.

Chat can be implemented this way: each client has a distributed object (of type chatClient), this has the distr.property chatClient.CurrentMessage.
On start up, you distribute the chatClient (DistributionSession.CreateNew<chatClient>()) this distributes also the CurrentMessage property.
If you change this property, then the new data will be propagated to all registred clients.

Note that if you have to connect all clients to server prior registering for Distribution objects.

Hope this helps!

David
Oct 6, 2009 at 12:02 PM

Great, thanks!

I will try that.

And yes, im aware of the "register before distribute" things.

I found this library yesterday, so havent done much with it yet, just few test apps and test games ( So far it has been very easy to do ). I created lobby room, so that clients can gather there, before starting to distribute, but how could i implement FPS game style joining/leaving?After i get good hang on this, i might write tutorial or two to Ziggy. This is so awesome library, that every wanna be indie gamemaker needs this. They just dont know this exists.

 

 

Oct 6, 2009 at 12:35 PM
Edited Oct 6, 2009 at 3:25 PM

Error    1    The type 'string' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Kaleta.Network.DistributableProperty<T>'    C:\Documents and Settings\Katu\Omat tiedostot\Visual Studio 2008\Projects\BetterProjects\KaletaNetworkTesting\KaletaTesting2\OnlineClass.cs    31    42    KaletaTesting2

_str = DistributableProperty<string>.Register("Str", this); <- this is Line 31 and "string" is getting the error in it.

and after compile test, this trows the error: "private DistributableProperty<string> _str;" gives the same error.

This is the error i get, when i try to use string. I tryed this before too and same results. Thats why i asked if strings are possible.

 

Coordinator
Oct 6, 2009 at 2:51 PM

Aha I see, yes the string type is indeed a nullable type, therefore it cannot be used as data distribution type (this is a bug, i will fix this, thanks ;)).. But there is a quick solution:

There is the IDataSerialization interface which you can use to serialize (e.g. distribute) whatever data you want (I use it also in the Outcast example)..

Sample:

  public struct DistributableString {

         public char[] Chars;

         public override string ToString() { return new String(this.Chars); }

         public void SetValue(string value) { Chars = value.ToCharArray(); }

  }

public class StringSerialization : IDataTypeSerialization
{
public void WriteData(ref object data, ref NetBuffer sendBuffer)
{
string data = (DistributableString) data;
char[] chars = data.Chars;
sendBuffer.Write((System.Int16) chars.length);
foreach(var c in chars.Reverse()) sendBuffer.Write((Byte) c);
 
}

public object ReadData(ref NetBuffer readBuffer)
{
int howMany=readBuffer.ReadInt16();
var str = new DistributableString();
for(int i=0;i<howMany;i++)
str.Char[i] = readBuffer.ReadByte();

return str;
}
}


Then you can use this new type in the DistributableProperty.Register<DistString> in your class and use it as ordinary property..

Prior using the custom type you have to register it :

DistributionSerializer.CustomTypesForSerialization.Add(new KeyValuePair<Type, IDataTypeSerialization>(
typeof(DistString), new StringSerialization()));

that should do it..

David
ReadByte
Oct 6, 2009 at 3:26 PM

Ok, will try that. Thanks

 

Coordinator
Oct 6, 2009 at 3:44 PM

it came to my mind that in the stated ReadData is something wrong:

the length of the string should be written at last order, e.g.;

public void WriteData(ref object data, ref NetBuffer sendBuffer)
{
string data = (DistributableString) data;
char[] chars = data.Chars;

foreach(var c in chars.Reverse()) sendBuffer.Write((Byte) c);
 
           sendBuffer.Write((System.Int16) chars.length); //last because the ReadData reads it as first byte

}

david

Coordinator
Oct 7, 2009 at 2:26 PM

Please check latest source codes as I added the

1. synchronization feature,

2. string distribution,

3. simple client-server chat application for learning purpose

 

david

 

Oct 7, 2009 at 6:55 PM

Ok, great! Ill take a look at it!