Page 6 of 8

Re: Networking Question

Posted: 30 Jan 2012, 19:17
by CodeWolf
mm ,pag tak iepriekš minēji ka viss kods jaapvieno kopā..
vai tad nevajadzēja būt tā..?
1. norādam pozīcijas
2. saspiežam tās vienā intā..//pos_pack
3.pos_pack sadalam bitos..//initBits()..storeBits untt
4.nosūtam..//chara ,izmerā..

Re: Networking Question

Posted: 31 Jan 2012, 00:04
by bubu
Tieši tā. Pareizi esi sapratis.

Re: Networking Question

Posted: 31 Jan 2012, 20:00
by CodeWolf
nu bet tādā gadījumā sanāk sūtīt to lielo skaitli kuru viņš nemaz neļauj nosūtīt. Jo Izsūtāmo vai saņemamo failu max .. to neatļauj
Limits +100 ir x, y un z mainīgajiem. Nevis pos_packet.
+ kur tas ir minētsēts ka es tieši x,y,z definēju to +100-100 katrai vertibai?
Pēc shemas kā iepriekš rakstiju

Code: Select all

int xi=(int)(x*10),yi=(int)(y*10),zi=(int)(z*10);
pos_packet_0 = xi | (yi << 10) | (zi << 20);
Paka0->write(pos_packet_0,-100.0f,+100.0f,0.01f,SPW_PK);//SPW_PK = GameMessageID -130

Re: Networking Question

Posted: 31 Jan 2012, 20:11
by bubu
Nepareizi esi tu tur uzrakstījis kodu.
Vispirms vajag pakā pa bitiem sarakstīt individuāli to x/y/z (katram norādot kautvai savu min/max/prec). Paka uztur buferi, kuru tu vēlāk vari aizsūtīt pa soketu.

Reku biju rakstījis kas un kā: http://forums.gamedev.lv/viewtopic.php?p=1658#p1658

Code: Select all

Paka0->writeInt(SPW_PK, 5);
Paka0->writeFloat(x,-100.0f,+100.0f,0.01f);
Paka0->writeFloat(y,-100.0f,+100.0f,0.01f);
Paka0->writeFloat(z,-100.0f,+100.0f,0.01f);

socket->send(Paka0->getBuffer(), Paka0->getBufferSize());
Saspiešana intā notiek writeFloat'ā + turpatās no tā int'u sadala pa bitiem un ieraksta iekšējā buferī. writeInt paņem tik cik tev bitus norāda. Manā piemērā piecus - tas dos iespēju nosūtīt max 32 id vērtības.

Re: Networking Question

Posted: 31 Jan 2012, 23:39
by CodeWolf
Njam., meiģināju izveidot tā kā teici bet velāk atsevišķi izsaucot "Send" komandu izmetas errors..
tā pat arī meiģināju uztaisīt. write3floats( ar 3 verībam)
vēlāk tās visas reizē izsūtot..
šādā veidā

Code: Select all

bsOut.Write((RakNet::MessageID)GameMessageIDs);
	bsOut.Write((char*)buffer_1,BBC_1);//x
	bsOut.Write((char*)buffer_2,BBC_2);//y
	bsOut.Write((char*)buffer_3,BBC_3);//z

	peer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
jo es atsevišķi send funkciju nevarēju iegūt viņa vienkārši tad bija 0 vai tukš sūtijums
bet tad man problēmas radās šo te nolasīt..
meiģināju gan ar float gan void(x,y,z-100......)
izsaukt bet neizdevās..

sāku domāt.. varbūt izdarīt nedaudz savādāk
1.klientam pieslēdzoties nosūtīt tīrus 3 floatus //kā spawn poziciju (12baitu izmērā)
2. un tad
sūtīt saspiesto skaitli kuru iepriekš esmu apzīmējis
piem pie pozīcijām
0-stāvēt
1-iet pa dioganāli
2-uz augšu
3-uz leju
untt
un ~ iekļauties tajos -10 /+10
un iekš klienta rēķināt pārējo pozīcijas..

nedaudz arī palasīju RakNet pamācības..
nesaprotu to kā viņi var nosūtīt floatus struktūrā (lielos daudzumos neko nesaspiežot)

unsigned char useTimeStamp; // Assign this to ID_TIMESTAMP
RakNet::Time timeStamp; // Put the system time in here returned by RakNet::GetTime()
unsigned char typeId; // This will be assigned to a type I've added after ID_USER_PACKET_ENUM, lets say ID_SET_TIMED_MINE
useTimeStamp = ID_TIMESTAMP;
timeStamp = RakNet::GetTime();
typeId=ID_SET_TIMED_MINE;
Bitstream myBitStream;
myBitStream.Write(useTimeStamp);
myBitStream.Write(timeStamp);
myBitStream.Write(typeId);
// Assume we have a Mine* mine object
// If the mine is at 0,0,0, use 1 bit to represent this
if (mine->GetPosition().x==0.0f && mine->GetPosition().y==0.0f && mine->GetPosition().z==0.0f)
{
myBitStream.Write(true);
}
else
{
myBitStream.Write(false);
myBitStream.Write(mine->GetPosition().x);
myBitStream.Write(mine->GetPosition().y);
myBitStream.Write(mine->GetPosition().z);
}
myBitStream.Write(mine->GetNetworkID()); // In the struct this is NetworkID networkId
myBitStream.Write(mine->GetOwner()); // In the struct this is SystemAddress systemAddress

This can potentially save us sending 3 floats over the network, at the cost of 1 bit.
+

Code: Select all

You can also write bits. Most of the time you will not care about this.
http://www.raknet.net/raknet/manual/bitstreams.html
:?

Re: Networking Question

Posted: 01 Feb 2012, 02:11
by bubu
Nesaprotu tavu kodu. Kas tev tur par tik daudz buferiem? Vienu tikai vajag.
Reku tev gatavs un strādājošs kods ar visu lietošanas piemēru. Kļūdu gadījumus, protams, neapstrādāju, un tā vietā lietoju assert. Tavā ziņā ir tas, kā to labot, ja vajadzīgs. Ar optimizāciju arī neaizrāvos, uzsvars uz koda saprotamību.

Code: Select all

#include <string.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>

class BitBuffer
{
public:
    BitBuffer()
    {
        reset();
    }
    
    void reset()
    {
        pos = 0;
        maxPos = 8*MAX_BYTE_COUNT;
        memset(buf, 0, sizeof(buf));
    }
    
    void assign(const unsigned char* bytes, int byteCount)
    {
        assert(byteCount <= MAX_BYTE_COUNT);
        
        pos = 0;
        maxPos = byteCount * 8;
        memcpy(buf, bytes, byteCount);
    }
    
    void writeInt(unsigned int x, int bits)
    {
        assert(bits <= 32);
        assert(x < (1U<<bits));

        for (int i=0; i<bits; i++)
        {
            putBit((x >> i) & 1);
        }
    }
    
    void writeFloat(float x, float min, float max, float prec)
    {
        assert(x >= min && x <= max);

        int bits = (int)ceilf(logf((max - min) / prec) / logf(2.0f));
        writeInt((unsigned int)(0.5f + (x - min) / prec), bits);
    }
    
    unsigned int readInt(int bits)
    {
        assert(bits <= 32);

        unsigned int x = 0;
        for (int i=0; i<bits; i++)
        {
            x |= getBit() << i;
        }
        return x;
    }
    
    float readFloat(float min, float max, float prec)
    {
        int bits = (int)ceilf(logf((max - min) / prec) / logf(2.0f));
        return min + readInt(bits) * prec;
    }
    
    const unsigned char* getBuffer() const
    {
        return buf;
    }
    
    unsigned int getBufferSize() const
    {
        return (pos+7)/8;
    }
    
private:
     void putBit(int bit)
     {
         buf[pos/8] |= bit << (pos%8);
         pos++;
         
         assert(pos < maxPos);
     }
     
     int getBit()
     {
         assert(pos < maxPos);

         int bit = buf[pos/8] >> (pos%8);
         pos++;
         return bit & 1;
     }
     
     static const int MAX_BYTE_COUNT = 128; // max 1024 bits
     unsigned char buf[MAX_BYTE_COUNT];

     int pos;
     int maxPos;
};


int main()
{
    BitBuffer packet2;

    {
        int id = 12;
        float x = 1.0f;
        float y = -55.5f;
        float z = 77.0f;

        BitBuffer packet;

        packet.writeInt(id, 4); // id = [0..15]
        packet.writeFloat(x, -100.0f, +100.0f, 0.1f);
        packet.writeFloat(y, -100.0f, +100.0f, 0.1f);
        packet.writeFloat(z, -100.0f, +100.0f, 0.1f);

        // te suuti otrai pusei
        //socket->write(buf1.getBuffer(), buf1.getBufferSize());
        
        // otraa puse sanjem un ieraksti buferii
        packet2.assign(packet.getBuffer(), packet.getBufferSize());
    }

    int id;
    float x, y, z;

    id = packet2.readInt(4);
    x = packet2.readFloat(-100.0f, +100.0f, 0.1f);
    y = packet2.readFloat(-100.0f, +100.0f, 0.1f);
    z = packet2.readFloat(-100.0f, +100.0f, 0.1f);

    printf("%i %.1f %.1f %.1f\n", id, x, y, z);
   
}
Ļoti precīzi saglabā, aizsūta un izdrukā tavu id un x/y/z skaitļus 5 baitos (izmēru atgriež getBufferSize() metode).

RakNet'a koda gabalā tiek ietaupīts uz to, ka ja visas trīs pozīcijas x/y/z komponentes ir 0, tad tas tiek aizsūtīts īsāk. Nav diezko laba "optimizācija".

Re: Networking Question

Posted: 01 Feb 2012, 21:23
by CodeWolf
es jau teicu ka mēģināju.. to ka iespējamo varinatu ,tāpēc tur bija tik daudz bufferu.. Jo kodu taisiju pec tada principa kā
-> sūtīt 1ienu //apvienoto intu vērtību..
un neko vairāk.. tikai vienai vertibai

hmh.. īsti nesapratu izsūtīšanas vietu..
tur kur ir tas buf1.getBuf..
// te suuti otrai pusei
//socket->write(buf1.getBuffer(), buf1.getBufferSize());

// otraa puse sanjem un ieraksti buferii
packet2.assign(packet.getBuffer(), packet.getBufferSize());
Tas ir kautkāds random buferis(chars) vai vienkārši..klases pārstāvis
jo sūtot Paku kā tādu, otrā pusē neko nesaņemu..
parbaudīju savienojumu..parastās komandas strādā (//bsOut.Write(..kkads floats), bet tad kad velos nosutit paku
klienta puse x,y,z=-100. ... ... ..

Re: Networking Question

Posted: 01 Feb 2012, 21:33
by bubu
Es nesaprotu, ko tu nesaproti.

Tev ir socket klase kautkāda ar vismaz šādu funkcionalitāti, pareizi?

Code: Select all

class Socket {

    // aizsūta no buffer bufera size baitus
    void Write(const unsigned char* buffer, unsigned int size);

    // mēģina nolasīt maxSize baitus buferī, un atgriež nolasīto baitu skaitu
    int Read(unsigned char* buffer, unsigned int maxSize);
}
Tad nu sūtīšanas vietā raksti:

Code: Select all

BitBuffer buf;
buf.writeInt(id, 5);
buf.writeFloat(x, ...);

socket->Write(buf.getBuffer(), buf.getBufferSize());
Saņemšanas vietā raksti:

Code: Select all

unsigned char temp[100]; // cik nu tev tur max baiti atnāk no tīkla
int size = socket->Read(temp, sizeof(temp));
BitBuffer buf;
buf.assign(temp, size);

id = buf.readInt(5);
x = buf.readFloat(...);
Kas te ir nesaprotams?

Re: Networking Question

Posted: 01 Feb 2012, 23:33
by CodeWolf
hmh viss strada labi
vienīgi nolasot
ja izmantoju

Code: Select all

bsIn.Read((char*)temp,sizeof(temp)); 
tad visas vertibas nemaz chara netiek ierakstītas..
ja izsaucu

Code: Select all

bsIn.Read((char*)temp,sizeof((char*)temp)); 
tad iegūstu pie izmēra 4 kas itkā ir par maz jo salīdzināju saņemtos čarus un pēdējā vērtība atšķīrās
char temp([0]76'L' | [1]126'~' | [2]189'1/2'[3]55'Q')
vietā saņēmu
char temp([0]76'L' | [1]126'~' | [2]189'1/2'[3]81'Q')
vēlāk nosverot sapratu ka trūkst 1 b..
tāpēc izdomāju to pieskaitīt klāt..

Code: Select all

bsIn.Read((char*)temp,sizeof((char*)temp)+1); 
tad viss nosūtījās.. bet es nēsmu pārliecināts vai tā drīkstēja darīt.. :)
+ pirmstam kodā redzēju to ka ar bitiem apzīmē inta izmēru ..to ierobežojot
packet.writeInt(id, 4); // id = [0..15]
nevari ludzu pateikt pēc kā es varu aprēķināt to cik daudz intus es iegūšu pēc attiecīgā izmēra..?

Re: Networking Question

Posted: 01 Feb 2012, 23:43
by bubu
Paskaties, ko sizeof dara, un ko tas nozīmē, pirms lietot savu kodu, kuru tu, kā izskatās randomā raksti... Kamon, sizeof((char*)temp) ???

Code: Select all

#include <stdio.h>

int main()
{
    char c;
    char* buf;
    char big[100];

    printf("%i\n", sizeof(c));
    printf("%i\n", sizeof(buf));
    printf("%i\n", sizeof(big));
}
Vai tagad saproti atšķirību, starp "char c", "char* c", un "char c[100]" ?
nevari ludzu pateikt pēc kā es varu aprēķināt to cik daudz intus es iegūšu pēc attiecīgā izmēra..?
Kas ir "cik daudz", un kas ir "pēc attiecīgā izmēra"? Cik daudz no kurienes? Kas ir tas ko tu skaiti? Kādus intus? Kas par izmēru?