mirror of
https://github.com/kevinbentley/Descent3.git
synced 2026-04-10 02:00:05 -04:00
274 lines
6.3 KiB
C++
274 lines
6.3 KiB
C++
#include "DMFC.h"
|
|
#include "dmfcinternal.h"
|
|
|
|
PlayerStack::PlayerStack(){root = NULL;}
|
|
PlayerStack::~PlayerStack(){RemoveAll();}
|
|
void PlayerStack::Add(char *callsign,network_address *addr,tDMFCPlayerStat *pstat,void *GameStatItem,int GameStatItemsize)
|
|
{
|
|
if(!callsign)
|
|
return;
|
|
if(!addr)
|
|
return;
|
|
if(!pstat)
|
|
return;
|
|
|
|
DLLmprintf((0,"Pushing %s onto a PlayerStack %s\n",callsign,GameStatItem?"(With Stats)":"(No Stats)"));
|
|
|
|
if(!root){
|
|
root = (tPlayerStackItem *)malloc(sizeof(tPlayerStackItem));
|
|
if(!root)
|
|
return;
|
|
root->next = NULL;
|
|
memcpy(&root->stat,pstat,sizeof(tDMFCPlayerStat));
|
|
memcpy(&root->addr,addr,sizeof(network_address));
|
|
root->callsign = (char *)malloc(strlen(callsign)+1);
|
|
root->timeadded = *basethis->DLLGametime;
|
|
if(!root->callsign){
|
|
free(root);
|
|
root = NULL;
|
|
return;
|
|
}
|
|
if(GameStatItem){
|
|
root->GameStatItem = malloc(GameStatItemsize);
|
|
if(!root->GameStatItem){
|
|
free(root->callsign);
|
|
free(root);
|
|
root=NULL;
|
|
return;
|
|
}
|
|
memcpy(root->GameStatItem,GameStatItem,GameStatItemsize);
|
|
}
|
|
else
|
|
root->GameStatItem = NULL;
|
|
strcpy(root->callsign,callsign);
|
|
return;
|
|
}else{
|
|
tPlayerStackItem *curr;
|
|
curr = root;
|
|
while(curr->next){curr=curr->next;}
|
|
curr->next = (tPlayerStackItem *)malloc(sizeof(tPlayerStackItem));
|
|
if(!curr->next)
|
|
return;
|
|
curr->next->callsign = (char *)malloc(strlen(callsign)+1);
|
|
if(!curr->next->callsign){
|
|
free(curr->next);
|
|
curr->next = NULL;
|
|
return;
|
|
}
|
|
if(GameStatItem){
|
|
curr->next->GameStatItem = malloc(GameStatItemsize);
|
|
if(!curr->next->GameStatItem){
|
|
free(curr->next->callsign);
|
|
free(curr->next);
|
|
curr->next = NULL;
|
|
return;
|
|
}
|
|
memcpy(curr->next->GameStatItem,GameStatItem,GameStatItemsize);
|
|
}else
|
|
curr->next->GameStatItem = NULL;
|
|
|
|
curr = curr->next;
|
|
curr->next = NULL;
|
|
memcpy(&curr->stat,pstat,sizeof(tDMFCPlayerStat));
|
|
memcpy(&curr->addr,addr,sizeof(network_address));
|
|
strcpy(curr->callsign,callsign);
|
|
curr->timeadded = *basethis->DLLGametime;
|
|
}
|
|
return;
|
|
}
|
|
void PlayerStack::RemoveAll(void)
|
|
{
|
|
if(root){
|
|
tPlayerStackItem *curr,*next;
|
|
curr = next = root;
|
|
while(curr){
|
|
next = curr->next;
|
|
Remove(curr);
|
|
curr = next;
|
|
}
|
|
}
|
|
root = NULL;
|
|
}
|
|
|
|
void PlayerStack::Remove(tPlayerStackItem *item)
|
|
{
|
|
if(!item)
|
|
return;
|
|
|
|
if(item->callsign)
|
|
free(item->callsign);
|
|
if(item->GameStatItem)
|
|
free(item->GameStatItem);
|
|
free(item);
|
|
}
|
|
|
|
bool PlayerStack::Find(char *callsign,network_address *addr,tDMFCPlayerStat *stat,bool remove,void *GameStatItem,int GameStatItemsize)
|
|
{
|
|
if(!root){
|
|
DLLmprintf((0,"PlayerStack: No Items\n"));
|
|
return false;
|
|
}
|
|
if(!addr){
|
|
return false;
|
|
}
|
|
if(!callsign){
|
|
return false;
|
|
}
|
|
if(!stat){
|
|
return false;
|
|
}
|
|
|
|
DLLmprintf((0,"PlayerStack: Looking for Player\n"));
|
|
|
|
tPlayerStackItem *curr,*prev;
|
|
curr = prev = root;
|
|
|
|
while(curr){
|
|
if(!strcmp(callsign,curr->callsign)){
|
|
DLLmprintf((0,"Found a pilot by the name of %s...",callsign));
|
|
if(!memcmp(addr,&curr->addr,sizeof(network_address))){
|
|
DLLmprintf((0,"Network address matches!\n"));
|
|
memcpy(stat,&curr->stat,sizeof(tDMFCPlayerStat));
|
|
if((curr->GameStatItem)&&(GameStatItem)){
|
|
memcpy(GameStatItem,curr->GameStatItem,GameStatItemsize);
|
|
}
|
|
if(remove){
|
|
if(curr!=root){
|
|
tPlayerStackItem *temp;
|
|
temp = curr->next;
|
|
Remove(curr);
|
|
prev->next = temp;
|
|
}else{
|
|
tPlayerStackItem *temp;
|
|
temp = root->next;
|
|
Remove(root);
|
|
root = temp;
|
|
}
|
|
}
|
|
return true;
|
|
}else
|
|
DLLmprintf((0,"But network address doesn't match!\n"));
|
|
}
|
|
|
|
prev = curr;
|
|
curr = curr->next;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void PlayerStack::Remove(char *callsign,network_address *addr)
|
|
{
|
|
if(!root)
|
|
return;
|
|
if(!addr)
|
|
return;
|
|
if(!callsign)
|
|
return;
|
|
|
|
tPlayerStackItem *curr,*prev;
|
|
curr = prev = root;
|
|
|
|
while(curr){
|
|
if(!strcmp(callsign,curr->callsign)){
|
|
DLLmprintf((0,"Found a pilot by the name of %s...",callsign));
|
|
if(!memcmp(addr,&curr->addr,sizeof(network_address))){
|
|
DLLmprintf((0,"Network address matches!\n"));
|
|
DLLmprintf((0,"Removing %s from list\n",callsign));
|
|
if(curr!=root){
|
|
tPlayerStackItem *temp;
|
|
temp = curr->next;
|
|
Remove(curr);
|
|
prev->next = temp;
|
|
}else{
|
|
tPlayerStackItem *temp;
|
|
temp = root->next;
|
|
Remove(root);
|
|
root = temp;
|
|
}
|
|
return;
|
|
}else
|
|
DLLmprintf((0,"But network address doesn't match!\n"));
|
|
}
|
|
prev = curr;
|
|
curr = curr->next;
|
|
}
|
|
}
|
|
|
|
bool PlayerStack::Pop(char *callsign,int maxlength,tDMFCPlayerStat *stat,void *GameStatItem,int GameStatItemsize)
|
|
{
|
|
if(!root)
|
|
return false;
|
|
if(!callsign)
|
|
return false;
|
|
if(!stat)
|
|
return false;
|
|
|
|
tPlayerStackItem *curr,*prev;
|
|
curr = prev = root;
|
|
|
|
while(curr->next){
|
|
prev = curr;
|
|
curr = curr->next;
|
|
}
|
|
|
|
//When this ends
|
|
// Last node == curr
|
|
// Second to last node == prev (if curr not at root)
|
|
DLLmprintf((0,"Popping %s from list\n",curr->callsign));
|
|
memcpy(stat,&curr->stat,sizeof(tDMFCPlayerStat));
|
|
if((curr->GameStatItem)&&(GameStatItem)){
|
|
memcpy(GameStatItem,curr->GameStatItem,GameStatItemsize);
|
|
}
|
|
strncpy(callsign,curr->callsign,maxlength);
|
|
curr->callsign[maxlength-1]='\0';
|
|
|
|
if(curr!=root){
|
|
Remove(curr);
|
|
prev->next = NULL;
|
|
}
|
|
else{
|
|
Remove(curr);
|
|
root = NULL;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int PlayerStack::PeekLast(float time,int max,char *callsigns[],int maxlength,tDMFCPlayerStat *stats,
|
|
void *GameStatItem,int GameStatItemsize)
|
|
{
|
|
if(!root)
|
|
return 0;
|
|
if(!callsigns)
|
|
return 0;
|
|
if(!stats)
|
|
return 0;
|
|
|
|
tPlayerStackItem *curr,*next;
|
|
curr = next = root;
|
|
int count = 0;
|
|
float cutofftime = *basethis->DLLGametime;
|
|
|
|
while(curr){
|
|
next = curr->next;
|
|
|
|
//see if this fits within our time
|
|
if(curr->timeadded + time>cutofftime){
|
|
//we gots a winner
|
|
memcpy(&stats[count],&curr->stat,sizeof(tDMFCPlayerStat));
|
|
if((curr->GameStatItem)&&(GameStatItem)){
|
|
memcpy(((ubyte *)GameStatItem) + (GameStatItemsize*count),curr->GameStatItem,GameStatItemsize);
|
|
}
|
|
strncpy(callsigns[count],curr->callsign,maxlength);
|
|
curr->callsign[maxlength-1]='\0';
|
|
|
|
count++;
|
|
if(count>=max){
|
|
return count;
|
|
}
|
|
}
|
|
curr = next;
|
|
}
|
|
|
|
//we're done
|
|
return count;
|
|
} |