Changeset 777 for code/branches/FICN/src/network/GameStateClient.cc
- Timestamp:
- Dec 31, 2007, 7:40:23 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/FICN/src/network/GameStateClient.cc
r636 r777 1 1 /* 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * ... 23 * Co-authors: 24 * ... 25 * 26 */ 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * ... 23 * Co-authors: 24 * ... 25 * 26 */ 27 #include <zlib.h> 27 28 29 #include "core/CoreIncludes.h" 30 #include "Synchronisable.h" 28 31 #include "GameStateClient.h" 29 32 30 namespace network { 31 32 GameStateClient::GameStateClient() 33 namespace network 33 34 { 34 } 35 36 37 GameStateClient::~GameStateClient() 38 { 39 } 40 41 bool GameStateClient::pushGameState(GameStateCompressed *compstate){ 42 if(compstate->diffed) 43 return loadSnapshot(decode(reference, *compstate)); 44 else 45 return loadSnapshot(decode(*compstate)); 46 } 47 48 49 /** 50 * This function removes a Synchronisable out of the universe 51 * @param it iterator of the list pointing to the object 52 * @return iterator pointing to the next object in the list 53 */ 54 void GameStateClient::removeObject(orxonox::Iterator<Synchronisable> &it){ 55 orxonox::Iterator<Synchronisable> temp=it; 56 ++it; 57 delete *temp; 58 } 59 60 /** 61 * This function loads a Snapshort of the gamestate into the universe 62 * @param state a GameState struct containing the size of the gamestate and a pointer linking to a flat list (returned by getSnapshot) 63 */ 64 bool GameStateClient::loadSnapshot(GameState state) 65 { 66 unsigned char *data=state.data; 67 std::cout << "loadSnapshot: loading gs: " << state.id << std::endl; 68 // get the start of the Synchronisable list 69 orxonox::Iterator<Synchronisable> it=orxonox::ObjectList<Synchronisable>::start(); 70 syncData sync; 71 // loop as long as we have some data ;) 72 while(data < state.data+state.size){ 73 // prepare the syncData struct 74 sync.length = (int)*data; 75 data+=sizeof(int); 76 sync.objectID = (int)*data; 77 data+=sizeof(int); 78 sync.classID = (int)*data; 79 data+=sizeof(int); 80 sync.data = data; 81 data+=sync.length; 82 83 if(it->objectID!=sync.objectID){ 84 // bad luck ;) 85 // delete the synchronisable (obviously seems to be deleted on the server) 86 while(it != 0 && it->objectID!=sync.objectID){ 87 removeObject(it); 88 } 89 if(it==0){ 90 std::cout << "classid: " << sync.classID << ", name: " << ID(sync.classID)->getName() << std::endl; 91 orxonox::BaseObject *no = ID(sync.classID)->fabricate(); 92 ((Synchronisable *)no)->objectID=sync.objectID; 93 ((Synchronisable *)no)->classID=sync.classID; 94 it=orxonox::ObjectList<Synchronisable>::end(); 95 // update data and create object/entity... 96 if( !(((Synchronisable *)no)->updateData(sync)) && !(((Synchronisable *)no)->create()) ) 97 COUT(0) << "We couldn't create/update the object: " << sync.objectID << std::endl; 98 ++it; 99 } 100 } else { 101 // we have our object 102 if(! it->updateData(sync)) 103 std::cout << "We couldn't update objectID: " \ 104 << sync.objectID << "; classID: " << sync.classID << std::endl; 105 } 106 ++it; 35 GameStateClient::GameStateClient() { 107 36 } 108 37 109 return true;110 }38 GameStateClient::~GameStateClient() { 39 } 111 40 112 GameState GameStateClient::diff(GameState a, GameState b){ 113 unsigned char *ap = a.data, *bp = b.data; 114 int of=0; // pointers offset 115 int dest_length=0; 116 if(a.size>=b.size) 117 dest_length=a.size; 118 else 119 dest_length=b.size; 120 unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char)); 121 while(of<a.size && of<b.size){ 122 *(dp+of)=*(ap+of)^*(bp+of); // do the xor 123 ++of; 41 bool GameStateClient::pushGameState(GameStateCompressed *compstate) { 42 if(compstate->diffed) 43 return loadSnapshot(decode(reference, *compstate)); 44 else 45 return loadSnapshot(decode(*compstate)); 124 46 } 125 if(a.size!=b.size){ // do we have to fill up ? 126 unsigned char n=0; 127 if(a.size<b.size){ 128 while(of<dest_length){ 129 *(dp+of)=n^*(bp+of); 130 of++; 47 48 /** 49 * This function removes a Synchronisable out of the universe 50 * @param it iterator of the list pointing to the object 51 * @return iterator pointing to the next object in the list 52 */ 53 void GameStateClient::removeObject(orxonox::Iterator<Synchronisable> &it) { 54 orxonox::Iterator<Synchronisable> temp=it; 55 ++it; 56 delete *temp; 57 } 58 59 /** 60 * This function loads a Snapshort of the gamestate into the universe 61 * @param state a GameState struct containing the size of the gamestate and a pointer linking to a flat list (returned by getSnapshot) 62 */ 63 bool GameStateClient::loadSnapshot(GameState state) { 64 unsigned char *data=state.data; 65 std::cout << "loadSnapshot: loading gs: " << state.id << std::endl; 66 // get the start of the Synchronisable list 67 orxonox::Iterator<Synchronisable> it=orxonox::ObjectList<Synchronisable>::start(); 68 syncData sync; 69 // loop as long as we have some data ;) 70 while(data < state.data+state.size){ 71 // prepare the syncData struct 72 sync.length = (int)*data; 73 data+=sizeof(int); 74 sync.objectID = (int)*data; 75 data+=sizeof(int); 76 sync.classID = (int)*data; 77 data+=sizeof(int); 78 sync.data = data; 79 data+=sync.length; 80 81 if(it->objectID!=sync.objectID){ 82 // bad luck ;) 83 // delete the synchronisable (obviously seems to be deleted on the server) 84 while(it != 0 && it->objectID!=sync.objectID){ 85 removeObject(it); 86 } 87 if(it==0){ 88 std::cout << "classid: " << sync.classID << ", name: " << ID(sync.classID)->getName() << std::endl; 89 Synchronisable *no = (Synchronisable*)(ID(sync.classID)->fabricate()); 90 no->objectID=sync.objectID; 91 no->classID=sync.classID; 92 it=orxonox::ObjectList<Synchronisable>::end(); 93 // update data and create object/entity... 94 if( !no->updateData(sync) && !no->create() ) 95 COUT(0) << "We couldn't create/update the object: " << sync.objectID << std::endl; 96 ++it; 97 } 98 } else { 99 // we have our object 100 if(! it->updateData(sync)) 101 std::cout << "We couldn't update objectID: " \ 102 << sync.objectID << "; classID: " << sync.classID << std::endl; 131 103 } 132 } else{ 133 while(of<dest_length){ 134 *(dp+of)=*(ap+of)^n; 135 of++; 104 ++it; 105 } 106 107 return true; 108 } 109 110 GameState GameStateClient::diff(GameState a, GameState b) { 111 unsigned char *ap = a.data, *bp = b.data; 112 int of=0; // pointers offset 113 int dest_length=0; 114 if(a.size>=b.size) 115 dest_length=a.size; 116 else 117 dest_length=b.size; 118 unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char)); 119 while(of<a.size && of<b.size){ 120 *(dp+of)=*(ap+of)^*(bp+of); // do the xor 121 ++of; 122 } 123 if(a.size!=b.size){ // do we have to fill up ? 124 unsigned char n=0; 125 if(a.size<b.size){ 126 while(of<dest_length){ 127 *(dp+of)=n^*(bp+of); 128 of++; 129 } 130 } else{ 131 while(of<dest_length){ 132 *(dp+of)=*(ap+of)^n; 133 of++; 134 } 136 135 } 137 136 } 138 } 139 // should be finished now 140 GameState r = {b.id, dest_length, dp}; 141 return r; 142 } 143 144 145 GameState GameStateClient::decompress(GameStateCompressed a){ 146 int normsize = a.normsize; 147 int compsize = a.compsize; 148 int bufsize; 149 if(normsize < compsize) 150 bufsize = compsize; 151 else 152 bufsize = normsize; 153 unsigned char* dest = (unsigned char*)malloc( bufsize ); 154 int retval; 155 uLongf length=normsize; 156 //std::cout << "gamestateclient" << std::endl; 157 //std::cout << "normsize " << a.normsize << " compsize " << a.compsize << " " << bufsize << std::endl; 158 retval = uncompress( dest, &length, a.data, (uLong)compsize ); 159 //std::cout << "length " << length << std::endl; 160 switch ( retval ) { 161 case Z_OK: std::cout << "successfully decompressed" << std::endl; break; 162 case Z_MEM_ERROR: std::cout << "not enough memory available" << std::endl; break; 163 case Z_BUF_ERROR: std::cout << "not enough memory available in the buffer" << std::endl; break; 164 case Z_DATA_ERROR: std::cout << "data corrupted" << std::endl; break; 137 // should be finished now 138 GameState r = {b.id, dest_length, dp}; 139 return r; 165 140 } 166 141 167 GameState gamestate; 168 gamestate.id = a.id; 169 gamestate.size = normsize; 170 gamestate.data = dest; 171 gamestate.diffed = a.diffed; 172 173 return gamestate; 174 } 142 GameState GameStateClient::decompress(GameStateCompressed a) { 143 int normsize = a.normsize; 144 int compsize = a.compsize; 145 int bufsize; 146 if(normsize < compsize) 147 bufsize = compsize; 148 else 149 bufsize = normsize; 150 unsigned char* dest = (unsigned char*)malloc( bufsize ); 151 int retval; 152 uLongf length=normsize; 153 //std::cout << "gamestateclient" << std::endl; 154 //std::cout << "normsize " << a.normsize << " compsize " << a.compsize << " " << bufsize << std::endl; 155 retval = uncompress( dest, &length, a.data, (uLong)compsize ); 156 //std::cout << "length " << length << std::endl; 157 switch ( retval ) { 158 case Z_OK: std::cout << "successfully decompressed" << std::endl; break; 159 case Z_MEM_ERROR: std::cout << "not enough memory available" << std::endl; break; 160 case Z_BUF_ERROR: std::cout << "not enough memory available in the buffer" << std::endl; break; 161 case Z_DATA_ERROR: std::cout << "data corrupted" << std::endl; break; 162 } 175 163 164 GameState gamestate; 165 gamestate.id = a.id; 166 gamestate.size = normsize; 167 gamestate.data = dest; 168 gamestate.diffed = a.diffed; 176 169 177 GameState GameStateClient::decode(GameState a, GameStateCompressed x){ 178 GameState t = decompress(x); 179 return diff(a, t); 180 } 170 return gamestate; 171 } 181 172 182 GameState GameStateClient::decode(GameStateCompressed x){183 GameState t = decompress(x);184 return t;185 }173 GameState GameStateClient::decode(GameState a, GameStateCompressed x) { 174 GameState t = decompress(x); 175 return diff(a, t); 176 } 186 177 187 178 GameState GameStateClient::decode(GameStateCompressed x) { 179 GameState t = decompress(x); 180 return t; 181 } 188 182 189 183 }
Note: See TracChangeset
for help on using the changeset viewer.