forked from Wirlaburla/P3NG0
add group chat (but disabled because worlds servers)
This commit is contained in:
parent
87e23c8f00
commit
ffe82e442c
17
src/client.h
17
src/client.h
|
@ -5,6 +5,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "drone.h"
|
#include "drone.h"
|
||||||
|
#include "group.h"
|
||||||
#include "acfile.h"
|
#include "acfile.h"
|
||||||
|
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
|
@ -19,7 +20,8 @@ ACFile* replylist;
|
||||||
AMFile* messages;
|
AMFile* messages;
|
||||||
ALFile* filth;
|
ALFile* filth;
|
||||||
|
|
||||||
#define BUFFERSIZE 65535
|
#define BUFFERSIZE 4096
|
||||||
|
#define MAXGROUPS 64
|
||||||
|
|
||||||
bool autoOnline = false;
|
bool autoOnline = false;
|
||||||
bool roomOnline = false;
|
bool roomOnline = false;
|
||||||
|
@ -60,7 +62,8 @@ uint16_t direction = 0;
|
||||||
uint16_t spin = 0;
|
uint16_t spin = 0;
|
||||||
|
|
||||||
std::map<char, char*> properties;
|
std::map<char, char*> properties;
|
||||||
std::map<char, Drone> objects;
|
std::map<char, Drone*> objects;
|
||||||
|
std::vector<Group> groups;
|
||||||
|
|
||||||
void loadConfig();
|
void loadConfig();
|
||||||
int deinit(int response);
|
int deinit(int response);
|
||||||
|
@ -78,14 +81,24 @@ void setAvatar(int *sock, std::string avstr);
|
||||||
void roomIDReq(int *sock, std::string room);
|
void roomIDReq(int *sock, std::string room);
|
||||||
void teleport(int *sock, int x, int y, int z, int rot);
|
void teleport(int *sock, int x, int y, int z, int rot);
|
||||||
void longloc(int *sock, int x, int y, int z, int rot);
|
void longloc(int *sock, int x, int y, int z, int rot);
|
||||||
|
void setBuddy(int* sock, std::string name, bool status);
|
||||||
void userEnter(char id);
|
void userEnter(char id);
|
||||||
void userExit(char id);
|
void userExit(char id);
|
||||||
|
Group* findGroupOfMember(std::string name);
|
||||||
bool handleCommand(char* buffer, std::string from, std::string message);
|
bool handleCommand(char* buffer, std::string from, std::string message);
|
||||||
bool handlePhrase(char* buffer, std::string from, std::string message);
|
bool handlePhrase(char* buffer, std::string from, std::string message);
|
||||||
void processText(int *sock, std::string username, std::string message);
|
void processText(int *sock, std::string username, std::string message);
|
||||||
void processWhisper(int *sock, std::string username, std::string message);
|
void processWhisper(int *sock, std::string username, std::string message);
|
||||||
void sendChatMessage(int *sock, std::string msg);
|
void sendChatMessage(int *sock, std::string msg);
|
||||||
void sendWhisperMessage(int *sock, std::string to, std::string msg);
|
void sendWhisperMessage(int *sock, std::string to, std::string msg);
|
||||||
|
void relayGroupMessage(Group* g, int *sock, std::string from, std::string text);
|
||||||
|
void sendGroupMessage(Group* g, int *sock, std::string message);
|
||||||
void qsend(int *sock, unsigned char str[], bool queue);
|
void qsend(int *sock, unsigned char str[], bool queue);
|
||||||
|
|
||||||
|
Drone* getDrone(std::string name) {
|
||||||
|
for (auto o : objects)
|
||||||
|
if (o.second->name == name) return o.second;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
22
src/drone.h
22
src/drone.h
|
@ -5,23 +5,17 @@
|
||||||
class Drone {
|
class Drone {
|
||||||
public:
|
public:
|
||||||
bool droneActive = false;
|
bool droneActive = false;
|
||||||
char* name = new char[24];
|
std::string name;
|
||||||
|
|
||||||
Drone() { };
|
Drone() { };
|
||||||
Drone(char* &_name) : name{ _name } { };
|
Drone(char* &_name) {
|
||||||
bool operator != (Drone &d) { return strcmp(this->name, d.name) != 0; };
|
this->name = std::string(_name);
|
||||||
|
};
|
||||||
|
Drone(std::string &_name) {
|
||||||
|
this->name = _name;
|
||||||
|
};
|
||||||
|
bool operator != (Drone &d) { return this->name != d.name; };
|
||||||
Drone operator = (Drone *d) { return *d; };
|
Drone operator = (Drone *d) { return *d; };
|
||||||
void setGroup(Group* newGroup) {
|
|
||||||
activeGroup = newGroup;
|
|
||||||
}
|
|
||||||
Group* getCurrentGroup() {
|
|
||||||
return activeGroup;
|
|
||||||
}
|
|
||||||
bool inGroup() {
|
|
||||||
return activeGroup != nullptr;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Group* activeGroup;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
32
src/group.h
32
src/group.h
|
@ -2,32 +2,36 @@
|
||||||
#define GROUP_H
|
#define GROUP_H
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include "drone.h"
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
class Group {
|
class Group {
|
||||||
public:
|
public:
|
||||||
|
std::vector<std::string> members;
|
||||||
|
|
||||||
Group() {};
|
Group() {};
|
||||||
Group(const Group &other) {
|
Group(const Group &other) {
|
||||||
this->owner = other.owner;
|
|
||||||
this->members = other.members;
|
this->members = other.members;
|
||||||
}
|
}
|
||||||
Group(std::string owner) {
|
|
||||||
this->owner = owner;
|
bool addMember(std::string user) {
|
||||||
|
if (std::find(members.begin(), members.end(), user) == members.end()) {
|
||||||
|
members.push_back(user);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMember(std::string name) {
|
bool delMember(std::string user) {
|
||||||
members.push_back(name);
|
std::vector<std::string>::iterator p = std::find(members.begin(), members.end(), user);
|
||||||
|
if (p != members.end()) {
|
||||||
|
members.erase(p);
|
||||||
|
if (members.size() == 0) delete this;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
void delMember(std::string name) {
|
|
||||||
members.erase(std::find(members.begin(), members.end(), name));
|
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
std::string owner;
|
|
||||||
std::vector<std::string> members;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Group> groups;
|
|
||||||
std::map<std::string, Group*> groupmap;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
141
src/main.cpp
141
src/main.cpp
|
@ -28,7 +28,6 @@
|
||||||
#include "verrors.h"
|
#include "verrors.h"
|
||||||
#include "cmds.h"
|
#include "cmds.h"
|
||||||
#include "props.h"
|
#include "props.h"
|
||||||
#include "group.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
class QueuedPacket {
|
class QueuedPacket {
|
||||||
|
@ -66,7 +65,7 @@ int main(int argc, char const* argv[]) {
|
||||||
autoInit();
|
autoInit();
|
||||||
while (autoOnline) {
|
while (autoOnline) {
|
||||||
while (!roomOnline) {}
|
while (!roomOnline) {}
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
if (bufferQueue.size() > 0) {
|
if (bufferQueue.size() > 0) {
|
||||||
if (debug) printf("debug: flushing buffer queue (%i packets)\n", bufferQueue.size());
|
if (debug) printf("debug: flushing buffer queue (%i packets)\n", bufferQueue.size());
|
||||||
for (QueuedPacket qp : bufferQueue) {
|
for (QueuedPacket qp : bufferQueue) {
|
||||||
|
@ -235,7 +234,8 @@ void reciever(int *sock, uint16_t port) {
|
||||||
offs+=long_len;
|
offs+=long_len;
|
||||||
shortID = bufin[offs++];
|
shortID = bufin[offs++];
|
||||||
if (longID != NULL || strlen(longID) > 0) {
|
if (longID != NULL || strlen(longID) > 0) {
|
||||||
Drone newDrone = *(new Drone(longID));
|
std::string longstr = std::string(longID);
|
||||||
|
Drone* newDrone = new Drone(longstr);
|
||||||
objects[shortID] = newDrone;
|
objects[shortID] = newDrone;
|
||||||
}
|
}
|
||||||
} else if (bufin[p+2] == CMD_SESSEXIT && bufin[p+1] == 0x01) {
|
} else if (bufin[p+2] == CMD_SESSEXIT && bufin[p+1] == 0x01) {
|
||||||
|
@ -317,6 +317,24 @@ void reciever(int *sock, uint16_t port) {
|
||||||
userEnter(objID);
|
userEnter(objID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (bufin[p+2] == CMD_BUDDYNTF && bufin[p+1] == 0x01) {
|
||||||
|
char* username = new char[32];
|
||||||
|
int offs = p+3;
|
||||||
|
int username_len = bufin[offs++];
|
||||||
|
memcpy(username, &bufin[offs], username_len);
|
||||||
|
username[username_len] = 0;
|
||||||
|
offs+=username_len;
|
||||||
|
bool status = (bufin[offs++] == 1);
|
||||||
|
if (!status) {
|
||||||
|
std::string userstr = std::string(username);
|
||||||
|
Group* budGroup = findGroupOfMember(toLower(userstr));
|
||||||
|
if (budGroup != nullptr) {
|
||||||
|
char *whisout = new char[255];
|
||||||
|
sprintf(whisout, mainConf->getValue("leftgrp_msg", "%s has left the group.").c_str(), userstr.c_str());
|
||||||
|
sendGroupMessage(budGroup, sock, whisout);
|
||||||
|
budGroup->delMember(toLower(userstr));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//printf("*LEN[%i] OID[%i] TYPE[%02X] OFF[%i]\n", bufin[p], bufin[p+1], bufin[p+2], p);
|
//printf("*LEN[%i] OID[%i] TYPE[%02X] OFF[%i]\n", bufin[p], bufin[p+1], bufin[p+2], p);
|
||||||
}
|
}
|
||||||
|
@ -507,18 +525,38 @@ void longloc(int *sock, int x, int y, int z, int rot) {
|
||||||
qsend(sock, buftp, true);
|
qsend(sock, buftp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setBuddy(int* sock, std::string name, bool status) {
|
||||||
|
unsigned char bufout[255] = {0};
|
||||||
|
int k = 0;
|
||||||
|
bufout[k++] = name.length()+5;
|
||||||
|
bufout[k++] = 0x01;
|
||||||
|
bufout[k++] = CMD_BUDDYUPD;
|
||||||
|
bufout[k++] = name.length();
|
||||||
|
for(int l = 0; l < name.length(); l++)
|
||||||
|
bufout[k++] = name[l];
|
||||||
|
bufout[k++] = status?1:0;
|
||||||
|
bufout[k] = 0;
|
||||||
|
qsend(sock, bufout, true);
|
||||||
|
}
|
||||||
|
|
||||||
void userEnter(char id) {
|
void userEnter(char id) {
|
||||||
if (!((Drone)objects[id]).droneActive) {
|
if (!objects[id]->droneActive) {
|
||||||
objects[id].droneActive = true;
|
objects[id]->droneActive = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void userExit(char id) {
|
void userExit(char id) {
|
||||||
if (((Drone)objects[id]).droneActive) {
|
if (objects[id]->droneActive) {
|
||||||
objects.erase((char)id);
|
objects.erase((char)id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Group* findGroupOfMember(std::string name) {
|
||||||
|
for (int i = 0; i < groups.size(); i++)
|
||||||
|
if (std::find(groups[i].members.begin(), groups[i].members.end(), name) != groups[i].members.end()) return &groups[i];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool handleCommand(char* buffer, std::string from, std::string message) {
|
bool handleCommand(char* buffer, std::string from, std::string message) {
|
||||||
std::vector<std::string> args = split(message, ' ');
|
std::vector<std::string> args = split(message, ' ');
|
||||||
if (args.size() > 0) {
|
if (args.size() > 0) {
|
||||||
|
@ -582,6 +620,63 @@ bool handleCommand(char* buffer, std::string from, std::string message) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool handleGroups(char* buffer, std::string from, std::string message) {
|
||||||
|
std::vector<std::string> args = split(message, ' ');
|
||||||
|
if (args.size() > 1 && args[0] == "group") {
|
||||||
|
if (args[1] == "help") {
|
||||||
|
sprintf(buffer, "'create' to start a group, 'add ?' to add a user, 'leave' to leave, 'stats' to get a member list.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Group* activeGroup = findGroupOfMember(from);
|
||||||
|
if (activeGroup == nullptr) {
|
||||||
|
if (args[1] == "create") {
|
||||||
|
Group* newGroup = new Group();
|
||||||
|
newGroup->addMember(from);
|
||||||
|
setBuddy(&roomsock, from, true);
|
||||||
|
groups.push_back(*newGroup);
|
||||||
|
sprintf(buffer, mainConf->getValue("newgrp_msg", "A new group has been created.").c_str());
|
||||||
|
return true;
|
||||||
|
} else if (args[1] == "leave" || args[1] == "invite") {
|
||||||
|
sprintf(buffer, mainConf->getValue("nogrp_msg", "You are not in a group.").c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (args[1] == "create") {
|
||||||
|
sprintf(buffer, mainConf->getValue("ingrp_msg", "You are already in a group.").c_str());
|
||||||
|
return true;
|
||||||
|
} else if (args[1] == "leave") {
|
||||||
|
char *whisout = new char[255];
|
||||||
|
sprintf(whisout, mainConf->getValue("leftgrp_msg", "%s has left the group.").c_str(), from.c_str());
|
||||||
|
sendGroupMessage(activeGroup, &roomsock, whisout);
|
||||||
|
activeGroup->delMember(from);
|
||||||
|
sprintf(buffer, mainConf->getValue("exitgrp_msg", "You have left the group.").c_str());
|
||||||
|
setBuddy(&roomsock, from, false);
|
||||||
|
return true;
|
||||||
|
} else if (args[1] == "add" && args.size() > 2) {
|
||||||
|
std::string newmem = toLower(args[2]);
|
||||||
|
if (findGroupOfMember(newmem) == nullptr) {
|
||||||
|
activeGroup->addMember(newmem);
|
||||||
|
char *whisout = new char[255];
|
||||||
|
sprintf(whisout, mainConf->getValue("leftgrp_msg", "%s added you to the group.").c_str(), from.c_str());
|
||||||
|
sendWhisperMessage(&roomsock, newmem, whisout);
|
||||||
|
sprintf(buffer, mainConf->getValue("invitegrp_msg", "%s was added to the group by %s.").c_str(), args[2].c_str(), from.c_str());
|
||||||
|
setBuddy(&roomsock, newmem, true);
|
||||||
|
} else {
|
||||||
|
sprintf(buffer, mainConf->getValue("noinvitegrp_msg", "User is already in a group.").c_str());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else if (args[1] == "stats") {
|
||||||
|
std::string statmsg = "Users in group: ";
|
||||||
|
for (std::vector<std::string>::iterator v = activeGroup->members.begin(); v != activeGroup->members.end(); ++v)
|
||||||
|
statmsg+=((v!=activeGroup->members.begin()?", ":"")+*v);
|
||||||
|
sprintf(buffer, statmsg.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool handlePhrase(char* buffer, std::string from, std::string message) {
|
bool handlePhrase(char* buffer, std::string from, std::string message) {
|
||||||
std::vector<std::string> args = split(message, ' ');
|
std::vector<std::string> args = split(message, ' ');
|
||||||
if (strcontains("flip a coin", message)) {
|
if (strcontains("flip a coin", message)) {
|
||||||
|
@ -667,18 +762,23 @@ void processText(int *sock, std::string username, std::string message) {
|
||||||
|
|
||||||
void processWhisper(int *sock, std::string username, std::string message) {
|
void processWhisper(int *sock, std::string username, std::string message) {
|
||||||
if (debug) printf("debug: received whisper from %s: \"%s\"\n", username.c_str(), message.c_str());
|
if (debug) printf("debug: received whisper from %s: \"%s\"\n", username.c_str(), message.c_str());
|
||||||
char *msgout = new char[255];
|
std::string lowermsg = toLower(message);
|
||||||
message = toLower(message);
|
char *msgout = new char[BUFFERSIZE];
|
||||||
|
|
||||||
if (message == "ping") {
|
if (lowermsg == "ping") {
|
||||||
sendWhisperMessage(sock, username, mainConf->getValue("pong_msg", "Pong!"));
|
sendWhisperMessage(sock, username, mainConf->getValue("pong_msg", "Pong!"));
|
||||||
} else {
|
} else {
|
||||||
if (handleCommand(msgout, username, message)) {
|
if (false) {//handleGroups(msgout, toLower(username), lowermsg)) { // until an anti-spam exception is made
|
||||||
|
printf("info: processed group\n");
|
||||||
|
} else if (handleCommand(msgout, username, message)) {
|
||||||
printf("info: processed command\n");
|
printf("info: processed command\n");
|
||||||
} else if (handlePhrase(msgout, username, message)) {
|
|
||||||
printf("info: processed phrase\n");
|
|
||||||
} else {
|
} else {
|
||||||
snprintf(msgout, 255, messages->getMessage("unknown").c_str());
|
Group* actG = findGroupOfMember(toLower(username));
|
||||||
|
if (actG != nullptr) {
|
||||||
|
relayGroupMessage(actG, sock, username, message);
|
||||||
|
} else {
|
||||||
|
sprintf(msgout, messages->getMessage("unknown").c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sendWhisperMessage(sock, username, msgout);
|
sendWhisperMessage(sock, username, msgout);
|
||||||
}
|
}
|
||||||
|
@ -727,17 +827,28 @@ void sendWhisperMessage(int *sock, std::string to, std::string msg) {
|
||||||
msgout[k++] = line[l];
|
msgout[k++] = line[l];
|
||||||
msgout[k] = 0;
|
msgout[k] = 0;
|
||||||
msgout[0] = k;
|
msgout[0] = k;
|
||||||
if(debug) printf("debug: sending whisper \"%s\"\n", line.c_str());
|
if(debug) printf("debug: sending whisper to '%s' \"%s\"\n", to.c_str(), line.c_str());
|
||||||
qsend(sock, *(&msgout), true);
|
qsend(sock, *(&msgout), true);
|
||||||
memset(&msgout[0], 0, sizeof(msgout));
|
memset(&msgout[0], 0, sizeof(msgout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void relayGroupMessage(Group* g, int *sock, std::string from, std::string text) {
|
||||||
|
for (std::string member : g->members)
|
||||||
|
if (member != toLower(from)) sendWhisperMessage(sock, member, from+"> "+text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendGroupMessage(Group* g, int *sock, std::string message) {
|
||||||
|
for (std::string member : g->members)
|
||||||
|
sendWhisperMessage(sock, member, message);
|
||||||
|
}
|
||||||
|
|
||||||
void qsend(int *sock, unsigned char str[], bool queue) {
|
void qsend(int *sock, unsigned char str[], bool queue) {
|
||||||
if (debug) printf("debug: queuing packet type %i with length %i.\n", str[2], str[0]);
|
if (debug) printf("debug: queuing packet type %i with length %i.\n", str[2], str[0]);
|
||||||
QueuedPacket* qp = new QueuedPacket(sock, str);
|
QueuedPacket* qp = new QueuedPacket(sock, str);
|
||||||
if (queue) bufferQueue.push_back(*qp);
|
if (queue) bufferQueue.push_back(*qp);
|
||||||
else qp->flush(0);
|
else
|
||||||
|
qp->flush(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user