Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
48 KB
Referenced Files
None
Subscribers
None
diff --git a/util/gui/context-box.cpp b/util/gui/context-box.cpp
index c23ac227..f002c0bb 100644
--- a/util/gui/context-box.cpp
+++ b/util/gui/context-box.cpp
@@ -1,358 +1,359 @@
#include "util/graphics/bitmap.h"
#include "context-box.h"
#include "util/font.h"
#include <math.h>
#include "util/token.h"
static const double FONT_SPACER = 1.3;
static const int GradientMax = 50;
static Graphics::Color selectedGradientStart(){
static Graphics::Color color = Graphics::makeColor(19, 167, 168);
return color;
}
static Graphics::Color selectedGradientEnd(){
static Graphics::Color color = Graphics::makeColor(27, 237, 239);
return color;
}
using namespace std;
namespace Gui{
Effects::Gradient standardGradient(int max){
Effects::Gradient standard(max, selectedGradientStart(), selectedGradientEnd());
return standard;
}
Effects::Gradient modifiedGradient(Graphics::Color low, Graphics::Color high, int max){
Effects::Gradient modified(max, low, high);
return modified;
}
ListValues::ListValues():
interpolate(true),
lowColor(selectedGradientStart()),
highColor(selectedGradientEnd()),
maxGradient(GradientMax),
selectedColor(selectedGradientStart()),
selectedAlpha(255),
otherColor(Graphics::makeColor(255, 255, 255)),
otherAlpha(255),
distanceFadeMultiplier(35),
fade(true){
}
ListValues::ListValues(const ListValues & copy):
interpolate(copy.interpolate),
lowColor(copy.lowColor),
highColor(copy.highColor),
maxGradient(copy.maxGradient),
selectedColor(copy.selectedColor),
selectedAlpha(copy.selectedAlpha),
otherColor(copy.otherColor),
otherAlpha(copy.otherAlpha),
distanceFadeMultiplier(copy.distanceFadeMultiplier),
fade(copy.fade){
}
ListValues::~ListValues(){
}
const ListValues & ListValues::operator=(const ListValues & copy){
interpolate = copy.interpolate;
lowColor = copy.lowColor;
highColor = copy.highColor;
maxGradient = copy.maxGradient;
selectedColor = copy.selectedColor;
selectedAlpha = copy.selectedAlpha;
otherColor = copy.otherColor;
otherAlpha = copy.otherAlpha;
distanceFadeMultiplier = copy.distanceFadeMultiplier;
fade = copy.fade;
return *this;
}
static int clamp(int in, int low = 0, int high = 255){
if (in < low){
return low;
}
if (in > high){
return high;
}
return in;
}
void ListValues::getValues(const Token * token){
TokenView view = token->view();
while (view.hasMore()){
const Token * token;
view >> token;
try{
int red = 0, green = 0, blue = 0, alpha = 0, gradient=1;
if (token->match("interpolate-selected", interpolate)){
} else if (token->match("color-low", red, green, blue)){
lowColor = Graphics::makeColor(clamp(red), clamp(green), clamp(blue));
} else if (token->match("color-high", red, green, blue)){
highColor = Graphics::makeColor(clamp(red), clamp(green), clamp(blue));
} else if (token->match("interpolate-distance", gradient)){
maxGradient = clamp(gradient, 1, 1000);
} else if (token->match("selected-color", red, green, blue)){
selectedColor = Graphics::makeColor(clamp(red), clamp(green), clamp(blue));
} else if (token->match("selected-color-alpha", alpha)){
selectedAlpha = clamp(alpha);
} else if (token->match("other-color", red, green, blue)){
otherColor = Graphics::makeColor(clamp(red), clamp(green), clamp(blue));
} else if (token->match("other-color-alpha", alpha)){
otherAlpha = clamp(alpha);
} else if (token->match("distance-fade-multiplier", distanceFadeMultiplier)){
} else if (token->match("distance-fade", fade)){
}
} catch (const TokenException & ex){
// Output something
}
}
}
ContextItem::ContextItem(const std::string & name, const ContextBox & parent):
text(name),
parent(parent){
}
ContextItem::~ContextItem(){
}
void ContextItem::draw(int x, int y, const Graphics::Bitmap & where, const Font & font, int distance) const {
if (distance == 0){
if (parent.getListValues().getInterpolate()){
Graphics::Bitmap::transBlender(0, 0, 0, parent.getFadeAlpha());
font.printf(x, y, parent.getSelectedColor(), where.translucent(), getText(), 0);
} else {
Graphics::Bitmap::transBlender(0, 0, 0, parent.getListValues().getSelectedAlpha());
font.printf(x, y, parent.getListValues().getSelectedColor(), where.translucent(), getText(), 0);
}
} else {
if (parent.getListValues().getDistanceFade()){
int alpha = parent.getListValues().getOtherAlpha() - fabs((double) distance) * parent.getListValues().getDistanceFadeMultiplier();
alpha = clamp(alpha);
Graphics::Bitmap::transBlender(0, 0, 0, alpha);
font.printf(x, y, parent.getListValues().getOtherColor(), where.translucent(), getText(), 0);
} else {
Graphics::Bitmap::transBlender(0, 0, 0, parent.getListValues().getOtherAlpha());
font.printf(x, y, parent.getListValues().getOtherColor(), where.translucent(), getText(), 0);
}
}
}
void ContextItem::setText(const LanguageString & t){
text = t;
}
int ContextItem::size(const Font & font) const {
return font.textLength(getText().c_str());
}
ContextBox::ContextBox():
fadeState(NotActive),
list(new ScrollList()),
fadeSpeed(12),
fadeAlpha(0),
cursorCenter(0),
cursorLocation(0),
scrollWait(4),
selectedGradient(standardGradient(GradientMax)),
renderOnlyText(false){
}
ContextBox::ContextBox( const ContextBox & copy ):
fadeState(NotActive),
list(new ScrollList()),
selectedGradient(standardGradient(GradientMax)),
renderOnlyText(false){
this->list = copy.list;
this->fadeSpeed = copy.fadeSpeed;
this->fadeAlpha = copy.fadeAlpha;
this->cursorCenter = copy.cursorCenter;
this->cursorLocation = copy.cursorLocation;
this->scrollWait = copy.scrollWait;
this->renderOnlyText = copy.renderOnlyText;
}
ContextBox::~ContextBox(){
}
ContextBox & ContextBox::operator=( const ContextBox & copy){
this->fadeState = NotActive;
this->list = copy.list;
this->fadeSpeed = copy.fadeSpeed;
this->fadeAlpha = copy.fadeAlpha;
this->cursorCenter = copy.cursorCenter;
this->cursorLocation = copy.cursorLocation;
this->scrollWait = copy.scrollWait;
this->renderOnlyText = copy.renderOnlyText;
return *this;
}
void ContextBox::act(const Font & font){
// update board
board.act(font);
// Calculate text info
list->act();
// do fade
doFade();
// Update gradient
selectedGradient.update();
}
void ContextBox::render(const Graphics::Bitmap & work){
}
void ContextBox::render(const Graphics::Bitmap & work, const Font & font){
if (!renderOnlyText){
board.render(work);
}
drawText(work, font);
}
bool ContextBox::next(const Font & font){
if (fadeState == FadeOut){
return false;
}
list->next();
return true;
}
bool ContextBox::previous(const Font & font){
if (fadeState == FadeOut){
return false;
}
list->previous();
return true;
}
Graphics::Color ContextBox::getSelectedColor() const {
return values.getInterpolate() ? selectedGradient.current() : values.getSelectedColor();
}
void ContextBox::setListValues(const Gui::ListValues & values){
this->values = values;
selectedGradient = modifiedGradient(values.getLowColor(), values.getHighColor(), values.getMaxGradient());
}
void ContextBox::adjustLeft(){
}
void ContextBox::adjustRight(){
}
void ContextBox::open(){
// Set the fade stuff
fadeState = FadeIn;
//board.position = position;
board.location = location;
board.transforms = transforms;
board.colors = colors;
board.open();
fadeAlpha = 0;
cursorLocation = 0;
}
void ContextBox::close(){
fadeState = FadeOut;
board.close();
fadeAlpha = 255;
cursorLocation = 480;
}
void ContextBox::doFade(){
switch (fadeState){
case FadeIn: {
if (fadeAlpha < 255){
fadeAlpha += (fadeSpeed+2);
}
if (fadeAlpha >= 255){
fadeAlpha = 255;
if (board.isActive()){
fadeState = Active;
}
}
break;
}
case FadeOut: {
if (fadeAlpha > 0){
fadeAlpha -= (fadeSpeed+2);
}
if (fadeAlpha <= 0){
fadeAlpha = 0;
if (!board.isActive()){
fadeState = NotActive;
}
}
break;
}
case Active:
case NotActive:
default:
break;
}
}
void ContextBox::setList(const std::vector<Util::ReferenceCount<ContextItem> > & list){
this->list->clearItems();
for (vector<Util::ReferenceCount<ContextItem> >::const_iterator it = list.begin(); it != list.end(); it++){
const Util::ReferenceCount<ContextItem> & item = *it;
this->list->addItem(item.convert<ScrollItem>());
}
}
void ContextBox::addItem(const Util::ReferenceCount<ContextItem> & item){
this->list->addItem(item.convert<ScrollItem>());
}
void ContextBox::setListType(const ListType & type){
switch (type){
case Normal:{
Util::ReferenceCount<ScrollListInterface> newList(new NormalList());
newList->addItems(list->getItems());
list = newList;
break;
}
case Scroll:{
Util::ReferenceCount<ScrollListInterface> newList(new ScrollList());
newList->addItems(list->getItems());
list = newList;
break;
}
default:
break;
}
}
void ContextBox::setListWrap(bool wrap){
list->setWrap(wrap);
}
void ContextBox::drawText(const Graphics::Bitmap & bmp, const Font & font){
const int x1 = board.getArea().getX()+(int)(board.getTransforms().getRadius()/2);
const int y1 = board.getArea().getY()+2;//(board.getArea().radius/2);
const int x2 = board.getArea().getX2()-(int)(board.getTransforms().getRadius()/2);
const int y2 = board.getArea().getY2()-2;//(board.getArea().radius/2);
-
- Graphics::Bitmap area(bmp, x1, y1, x2 - x1, y2 - y1);
-
- list->render(area, font);
+
+ if (x2 > x1 && y2 > y1){
+ Graphics::Bitmap area(bmp, x1, y1, x2 - x1, y2 - y1);
+ list->render(area, font);
+ }
}
}
diff --git a/util/gui/lineedit.cpp b/util/gui/lineedit.cpp
index 1849a31d..abbc28b8 100644
--- a/util/gui/lineedit.cpp
+++ b/util/gui/lineedit.cpp
@@ -1,254 +1,258 @@
#include "util/graphics/bitmap.h"
#include "util/font.h"
#include "lineedit.h"
#include "util/debug.h"
#include <iostream>
using namespace Gui;
static Global::stream_type & debug(int level){
Global::debug(level) << "[line edit] ";
return Global::debug(level);
}
LineEdit::LineEdit() :
currentSetFont(0),
hAlignment(T_Middle),
hAlignMod(T_Middle),
vAlignment(T_Middle),
inputTypeValue(inputGeneral),
changed_(0),
autoResizable(0),
textX(0),
textY(0),
cursorX(0),
cursorY(0),
cursorIndex(0),
textColor(Graphics::makeColor(0, 0, 0)),
textSizeH(0),
limit(0),
blinkRate(500),
blink(false),
focused(false),
changeCounter(0){
cursorTime.reset();
}
LineEdit::~LineEdit(){
if (focused){
input.disable();
}
}
void LineEdit::hookKey(int key, void (*callback)(void *), void * arg){
input.addBlockingHandle(key, callback, arg);
}
bool LineEdit::didChanged(unsigned long long & counter){
bool did = counter < changeCounter;
counter = changeCounter;
return did;
}
// If the font size changes
void LineEdit::fontChange(){
changed();
}
// Update
void LineEdit::act(const Font & font){
+ if (currentSetFont == NULL){
+ currentSetFont = &font;
+ }
if (cursorTime.msecs() >= blinkRate){
cursorTime.reset();
blink = !blink;
changed();
}
/*
if ((blinkRate * 2) <= cursorTime.msecs()){
cursorTime.reset();
changed();
}
*/
if (input.doInput()){
changed();
cursorIndex = input.getText().size();
}
if (changed_){
textSizeH = currentSetFont->getHeight();
if (autoResizable) {
location.setDimensions(textSizeH+2, currentSetFont->textLength(input.getText().c_str()) + 4);
} else {
if (hAlignMod==T_Left){
if (currentSetFont->textLength(input.getText().c_str())>location.getWidth()){
hAlignment = T_Right;
} else {
hAlignment = T_Left;
}
}
}
switch (hAlignment) {
case T_Left:
textX = 2;
cursorX = textX + currentSetFont->textLength(input.getText().substr(0,cursorIndex).c_str()) + 1;
break;
case T_Middle:
textX = (location.getWidth()/2) - (currentSetFont->textLength(input.getText().c_str())/2);
cursorX = (textX) + currentSetFont->textLength(input.getText().substr(0,cursorIndex).c_str()) + 1;
break;
case T_Right:
textX = location.getWidth() - currentSetFont->textLength(input.getText().c_str());//(position.width - 1)-2;
cursorX = location.getWidth() - currentSetFont->textLength(input.getText().substr(0, input.getText().length()-cursorIndex).c_str());
break;
case T_Bottom:
case T_Top:
break;
}
switch (vAlignment) {
case T_Top:
textY = 1;
cursorY = 1;
break;
case T_Middle:
textY = cursorY = (location.getHeight() - textSizeH-(5))/2;
break;
case T_Bottom:
textY = (location.getHeight() - 1) - textSizeH - 1;
cursorY = textY - textSizeH;
break;
case T_Right:
case T_Left:
break;
}
//textY++;
//textX++;
stable();
}
}
// Draw
void LineEdit::render(const Graphics::Bitmap & work){
- Util::ReferenceCount<Graphics::Bitmap> workArea = checkWorkArea(work);
+ //Util::ReferenceCount<Graphics::Bitmap> workArea = checkWorkArea(work);
+ Graphics::Bitmap workArea = Graphics::Bitmap(workArea, location.getX(), location.getY(), location.getWidth(), location.getHeight());
/* Check if we are using a rounded box */
if (transforms.getRadius() > 0){
- workArea->translucent(0, 0, 0, colors.bodyAlpha).roundRectFill((int)transforms.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
- workArea->translucent(0, 0, 0, colors.borderAlpha).roundRect((int)transforms.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border);
+ workArea.translucent(0, 0, 0, colors.bodyAlpha).roundRectFill((int)transforms.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
+ workArea.translucent(0, 0, 0, colors.borderAlpha).roundRect((int)transforms.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border);
} else {
- workArea->translucent(0, 0, 0, colors.bodyAlpha).rectangleFill(0, 0, location.getWidth()-1, location.getHeight()-1, colors.body);
- workArea->translucent(0, 0, 0, colors.borderAlpha).rectangle(0, 0, location.getWidth()-1, location.getHeight()-1, colors.border);
+ workArea.translucent(0, 0, 0, colors.bodyAlpha).rectangleFill(0, 0, location.getWidth()-1, location.getHeight()-1, colors.body);
+ workArea.translucent(0, 0, 0, colors.borderAlpha).rectangle(0, 0, location.getWidth()-1, location.getHeight()-1, colors.border);
}
if (currentSetFont){
- currentSetFont->printf(textX, textY, textColor, *workArea, input.getText(), 0);
+ currentSetFont->printf(textX, textY, textColor, workArea, input.getText(), 0);
}
if (focused){
if (blink){
- workArea->line(cursorX, cursorY, cursorX, cursorY+textSizeH-5, textColor);
+ workArea.line(cursorX, cursorY, cursorX, cursorY+textSizeH-5, textColor);
}
}
}
// Set text
void LineEdit::setText(const std::string & text){
input.setText(text);
if (limit!=0) {
if (input.getText().length() > limit) {
while (input.getText().length() > limit){
// currentSetText.erase(currentSetText.begin()+currentSetText.length()-1);
}
}
}
cursorIndex = input.getText().length();
changed();
}
//! Get text
const std::string LineEdit::getText(){
return input.getText();
}
//! Clear text
void LineEdit::clearText(){
input.clearInput();
cursorIndex=0;
changed();
}
//! Set text limit
void LineEdit::setLimit(unsigned int l){
limit = l;
if (limit!=0){
if (input.getText().length()>limit){
while (input.getText().length()>limit){
// currentSetText.erase(currentSetText.begin()+currentSetText.length()-1);
}
}
}
cursorIndex = input.getText().length();
changed();
}
// Set Horizontal Alignment
void LineEdit::setHorizontalAlign(const textAlign & a){
hAlignment = hAlignMod = a;
changed();
}
// Set Vertical Alignment
void LineEdit::setVerticalAlign(const textAlign & a){
vAlignment = a;
changed();
}
//! Set the type of input default general
void LineEdit::setInputType(const inputType i){
inputTypeValue = i;
}
// Set textColor
void LineEdit::setTextColor(const Graphics::Color color){
textColor = color;
}
//! Set textColor
void LineEdit::setCursorColor(const Graphics::Color color){
textColor = color;
}
// Set font
void LineEdit::setFont(const Font *f){
currentSetFont = f;
if (currentSetFont) changed();
}
// Set autoResizeable
void LineEdit::setAutoResize(bool r){
autoResizable = r;
}
// Set the cursor blink rate in miliseconds (default 500)
void LineEdit::setCursorBlinkRate(unsigned int msecs){
blinkRate = msecs;
}
//! set Focus
void LineEdit::setFocused(bool focus){
focused = focus;
if (focus){
input.enable();
} else {
input.disable();
}
}
//! check Focus
bool LineEdit::isFocused(){
return focused;
}
diff --git a/util/network/irc.cpp b/util/network/irc.cpp
index 32108c3b..2041ad8a 100644
--- a/util/network/irc.cpp
+++ b/util/network/irc.cpp
@@ -1,617 +1,635 @@
#include "irc.h"
+#include "util/font.h"
#include "util/regex.h"
-
#include "util/graphics/bitmap.h"
+#include "util/configuration.h"
#include <stdexcept>
namespace Network{
namespace IRC{
static Command::Type convertCommand(const std::string & cmd){
Command::Type command = Command::Unknown;
if (cmd == "PASS"){
command = Command::Pass;
} else if (cmd == "NICK"){
command = Command::Nick;
} else if (cmd == "USER"){
command = Command::User;
} else if (cmd == "SERVER"){
command = Command::Server;
} else if (cmd == "OPER"){
command = Command::Oper;
} else if (cmd == "QUIT"){
command = Command::Quit;
} else if (cmd == "SQUIT"){
command = Command::Squit;
} else if (cmd == "JOIN"){
command = Command::Join;
} else if (cmd == "PART"){
command = Command::Part;
} else if (cmd == "MODE"){
command = Command::Mode;
} else if (cmd == "TOPIC"){
command = Command::Topic;
} else if (cmd == "NAMES"){
command = Command::Names;
} else if (cmd == "LIST"){
command = Command::List;
} else if (cmd == "INVITE"){
command = Command::Invite;
} else if (cmd == "KICK"){
command = Command::Kick;
} else if (cmd == "VERSION"){
command = Command::Version;
} else if (cmd == "STATS"){
command = Command::Stats;
} else if (cmd == "LINKS"){
command = Command::Links;
} else if (cmd == "TIME"){
command = Command::Time;
} else if (cmd == "CONNECT"){
command = Command::Connect;
} else if (cmd == "TRACE"){
command = Command::Trace;
} else if (cmd == "ADMIN"){
command = Command::Admin;
} else if (cmd == "INFO"){
command = Command::Info;
} else if (cmd == "PRIVMSG"){
command = Command::PrivateMessage;
} else if (cmd == "NOTICE"){
command = Command::Notice;
} else if (cmd == "WHO"){
command = Command::Who;
} else if (cmd == "WHOIS"){
command = Command::Whois;
} else if (cmd == "WHOWAS"){
command = Command::Whowas;
} else if (cmd == "KILL"){
command = Command::Kill;
} else if (cmd == "PING"){
command = Command::Ping;
} else if (cmd == "PONG"){
command = Command::Pong;
} else if (cmd == "ERROR"){
command = Command::Error;
} else if (cmd == "433"){
command = Command::ErrorNickInUse;
} else if (cmd == "401"){
command = Command::ErrorNoSuchNick;
} else if (cmd == "403"){
command = Command::ErrorNoSuchChannel;
} else if (cmd == "461"){
command = Command::ErrorNeedMoreParams;
} else if (cmd == "473"){
command = Command::ErrorInviteOnlyChannel;
} else if (cmd == "474"){
command = Command::ErrorBannedFromChannel;
} else if (cmd == "475"){
command = Command::ErrorBadChannelKey;
} else if (cmd == "471"){
command = Command::ErrorChannelIsFull;
} else if (cmd == "331"){
command = Command::ReplyNoTopic;
} else if (cmd == "332"){
command = Command::ReplyTopic;
} else if (cmd == "333"){
command = Command::ReplyTopicAuthor;
} else if (cmd == "353"){
command = Command::ReplyNames;
} else if (cmd == "366"){
command = Command::ReplyNamesEndOf;
} else if (cmd == "372"){
command = Command::ReplyMOTD;
} else if (cmd == "375"){
command = Command::ReplyMOTDStart;
} else if (cmd == "376"){
command = Command::ReplyMOTDEndOf;
}
return command;
}
static std::string convertCommand(const Command::Type & cmd){
switch (cmd){
case Command::Pass: return "PASS";
case Command::Nick: return "NICK";
case Command::User: return "USER";
case Command::Server: return "SERVER";
case Command::Oper: return "OPER";
case Command::Quit: return "QUIT";
case Command::Squit: return "SQUIT";
case Command::Join: return "JOIN";
case Command::Part: return "PART";
case Command::Mode: return "MODE";
case Command::Topic: return "TOPIC";
case Command::Names: return "NAMES";
case Command::List: return "LIST";
case Command::Invite: return "INVITE";
case Command::Kick: return "KICK";
case Command::Version: return "VERSION";
case Command::Stats: return "STATS";
case Command::Links: return "LINKS";
case Command::Time: return "TIME";
case Command::Connect: return "CONNECT";
case Command::Trace: return "TRACE";
case Command::Admin: return "ADMIN";
case Command::Info: return "INFO";
case Command::PrivateMessage: return "PRIVMSG";
case Command::Notice: return "NOTICE";
case Command::Who: return "WHO";
case Command::Whois: return "WHOIS";
case Command::Whowas: return "WHOAS";
case Command::Kill: return "KILL";
case Command::Ping: return "PING";
case Command::Pong: return "PONG";
case Command::Error: return "ERROR";
case Command::Unknown:
default:
break;
}
return "";
}
static std::vector<std::string> split(std::string str, char splitter){
std::vector<std::string> strings;
size_t next = str.find(splitter);
while (next != std::string::npos){
strings.push_back(str.substr(0, next));
str = str.substr(next+1);
next = str.find(splitter);
}
if (str != ""){
strings.push_back(str);
}
return strings;
}
Command::Command(const std::string & message){
std::vector< std::string > messageSplit = split(message, ' ');
std::vector< std::string >::iterator current = messageSplit.begin();
if (Util::matchRegex(*current, Util::Regex("^:.*"))){
// Found owner (":") indicates the user, otherwise it's going to be the command
// Grab just the username, ignore everything else
try{
owner = split(*current, '!').at(0).substr(1);
} catch (const std::out_of_range & ex){
}
current++;
}
// Next is the actual command
type = convertCommand(*current);
if (type == Unknown){
Global::debug(0) << "Got unhandled response: " << message << std::endl;
}
current++;
// Parameters
bool foundCtcp = false;
bool concactenate = false;
std::string concactenated;
for (std::vector< std::string >::iterator i = current; i != messageSplit.end(); ++i){
const std::string & parameter = *i;
// If there is a colon in the parameter the rest of split string is the whole parameter rejoin
if (Util::matchRegex(parameter, Util::Regex("^:\001.*")) && !foundCtcp){
foundCtcp = true;
// Drop the ':\001'
ctcp.push_back(parameter.substr(2));
continue;
} else if (Util::matchRegex(parameter, Util::Regex(".*\001")) && foundCtcp){
foundCtcp = false;
// Drop the '\001'
ctcp.push_back(parameter.substr(0, parameter.size()-1));
continue;
} else if (Util::matchRegex(parameter, Util::Regex("^:.*")) && !concactenate){
concactenate = true;
// Drop the ':'
concactenated += parameter.substr(1) + " ";
continue;
} else if (Util::matchRegex(parameter, Util::Regex("=")) ||
Util::matchRegex(parameter, Util::Regex("@"))){
// Ignore
continue;
}
if (concactenate){
concactenated += parameter + " ";
} else {
if (!foundCtcp){
parameters.push_back(parameter);
} else {
ctcp.push_back(parameter);
}
}
}
if (concactenate){
parameters.push_back(concactenated);
}
}
Command::Command(const std::string & owner, const Type & type):
owner(owner),
type(type){
}
Command::Command(const Command & copy):
owner(copy.owner),
type(copy.type),
parameters(copy.parameters),
ctcp(copy.ctcp){
}
Command::~Command(){
}
const Command & Command::operator=(const Command & copy){
owner = copy.owner;
type = copy.type;
parameters = copy.parameters;
ctcp = copy.ctcp;
return *this;
}
std::string Command::getSendable() const {
std::string sendable;
// Name
if (!owner.empty()){
sendable += ":" + owner + " ";
}
// Command
sendable += convertCommand(type) + " ";
// Params
/*for (std::vector<std::string>::const_iterator i = parameters.begin(); i != parameters.end(); ++i){
sendable+= *i + " ";
}*/
for (unsigned int i = 0; i < parameters.size(); ++i){
sendable += parameters[i] + (i < parameters.size()-1 ? " " : "");
}
// End
sendable += "\r\n";
return sendable;
}
Channel::Channel(){
}
Channel::Channel(const std::string & name):
name(name){
}
Channel::Channel(const Channel & copy):
name(copy.name),
topic(copy.topic),
topicAuthor(copy.topicAuthor),
topicDate(copy.topicDate),
users(copy.users){
}
Channel::~Channel(){
}
const Channel & Channel::operator=(const Channel & copy){
name = copy.name;
topic = copy.topic;
topicAuthor = copy.topicAuthor;
topicDate = copy.topicDate;
users = copy.users;
return *this;
}
void Channel::addUser(const std::string & user){
// Can't add same user twice
for (std::vector<std::string>::iterator i = users.begin(); i != users.end(); ++i){
const std::string & name = *i;
if (name == user){
return;
}
}
users.push_back(user);
}
void Channel::removeUser(const std::string & user){
for (std::vector<std::string>::iterator i = users.begin(); i != users.end(); ++i){
const std::string & name = *i;
if (name == user){
users.erase(i);
break;
}
}
}
void Channel::addUsers(const std::vector<std::string> & list){
for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); ++i){
const std::string & name = *i;
addUser(name);
}
}
Client::Client(const std::string & hostname, int port):
previousUsername("AUTH"),
username("AUTH"),
previousActiveChannel(0),
currentChannel(0),
hostname(hostname),
port(port),
end(false){
}
Client::~Client(){
}
void Client::connect(){
if (username.empty()){
throw NetworkException("Set username first.");
}
Global::debug(0) << "Connecting to " << hostname << " on port " << port << std::endl;
socket = Network::connectReliable(hostname, port);
start();
setName("paintown-test");
Command user("AUTH", Command::User);
user.setParameters(username, "*", "0", ":auth");
sendCommand(user);
// ^^^^^^^^ Should get a response from this crap!
joinChannel("#paintown");
Global::debug(0) << "Connected" << std::endl;
}
bool Client::hasCommands() const{
::Util::Thread::ScopedLock scope(lock);
return !commands.empty();
}
Command Client::nextCommand() const {
::Util::Thread::ScopedLock scope(lock);
Command command = commands.front();
commands.pop();
return command;
}
void Client::sendCommand(const Command & command){
const std::string & sendable = command.getSendable();
Network::sendBytes(socket, (uint8_t *) sendable.c_str(), sendable.size());
}
void Client::sendCommand(const Command::Type & type){
Command command(username, type);
sendCommand(command);
}
void Client::sendCommand(const Command::Type & type, const std::string & param1){
Command command(username, type);
command.setParameters(param1);
sendCommand(command);
}
void Client::sendCommand(const Command::Type & type, const std::string & param1, const std::string & param2){
Command command(username, type);
command.setParameters(param1, param2);
sendCommand(command);
}
void Client::sendCommand(const Command::Type & type, const std::string & param1, const std::string & param2, const std::string & param3){
Command command(username, type);
command.setParameters(param1, param2, param3);
sendCommand(command);
}
void Client::sendCommand(const Command::Type & type, const std::string & param1, const std::string & param2, const std::string & param3, const std::string & param4){
Command command(username, type);
command.setParameters(param1, param2, param3, param4);
sendCommand(command);
}
void Client::setName(const std::string & name){
previousUsername = username;
// Update channel list
//channel.removeUser(username);
//channel.addUser(name);
for (std::vector< ChannelPointer >::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
activeChannel->removeUser(username);
activeChannel->addUser(name);
}
username = name;
sendCommand(Command::Nick, name);
}
void Client::joinChannel(const std::string & chan){
for (std::vector< ChannelPointer >::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
if (activeChannel->getName() == chan){
// Already belonging to this channel
return;
}
}
previousActiveChannel = currentChannel;
ChannelPointer newChannel = ChannelPointer(new Channel(chan));
/*if (!currentChannel.getName().empty()){
sendCommand(Command::Part, currentChannel.getName());
}*/
activeChannels.push_back(newChannel);
currentChannel = activeChannels.size()-1;
sendCommand(Command::Join, getChannel()->getName());
}
std::string Client::channelListAsString(){
std::string list;
for (std::vector<ChannelPointer>::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
list += activeChannel->getName() + ", ";
}
return list.substr(0, list.size()-2);
}
unsigned int Client::getChannelIndex(const std::string & channel){
for (unsigned int i = 0; i < activeChannels.size(); ++i){
if (activeChannels[i]->getName() == channel){
return i;
}
}
return 0;
}
bool Client::isCurrentChannel(const std::string & channel){
return (activeChannels[currentChannel]->getName() == channel);
}
void Client::setChannel(unsigned int channel){
if (channel >= activeChannels.size()){
return;
}
currentChannel = channel;
}
void Client::nextChannel(){
currentChannel = (currentChannel + 1) % activeChannels.size();
}
void Client::previousChannel(){
if (currentChannel == 0){
currentChannel = activeChannels.size()-1;
} else {
currentChannel--;
}
}
void Client::removeChannel(const std::string & name){
for (std::vector< ChannelPointer >::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
if (activeChannel->getName() == name){
activeChannels.erase(i);
return;
}
}
}
ChannelPointer Client::findChannel(const std::string & name){
for (std::vector< ChannelPointer >::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
if (activeChannel->getName() == name){
return activeChannel;
}
}
return ChannelPointer(NULL);
}
void Client::sendMessage(const std::string & msg){
sendCommand(Command::PrivateMessage, getChannel()->getName(), ":" + msg);
}
void Client::sendPong(const Command & ping){
Command pong(username, Command::Pong);
pong.setParameters(ping.getParameters());
sendCommand(pong);
}
std::string Client::readMessage(){
std::string received;
bool foundReturn = false;
while (true){
try {
char nextCharacter = Network::read8(socket);
/* NOTE the latest RFC says that either \r or \n is the end of the message
* http://www.irchelp.org/irchelp/rfc/chapter8.html
*/
if (nextCharacter == '\r'){
// Found return
foundReturn = true;
continue;
} else if ((nextCharacter == '\n') && foundReturn){
// Should be the end of the message assuming \r is before it
break;
}
received += nextCharacter;
} catch (const Network::MessageEnd & ex){
// end of message get out
throw ex;
}
}
//Global::debug(0) << "Read next string: " << received << std::endl;
return received;
}
void Client::checkResponseAndHandle(const Command & command){
// Checks for username or channel errors
if (command.getType() == Command::ErrorNickInUse){
::Util::Thread::ScopedLock scope(lock);
// Change the username back to what it was
getChannel()->removeUser(username);
username = previousUsername;
getChannel()->addUser(username);
} else if (command.getType() == Command::ErrorBannedFromChannel ||
command.getType() == Command::ErrorInviteOnlyChannel ||
command.getType() == Command::ErrorBadChannelKey ||
command.getType() == Command::ErrorChannelIsFull ||
command.getType() == Command::ErrorNoSuchChannel){
::Util::Thread::ScopedLock scope(lock);
// Revert old channel
removeChannel(getChannel()->getName());
currentChannel = previousActiveChannel;
} else if (command.getType() == Command::ReplyTopic){
::Util::Thread::ScopedLock scope(lock);
// Set topic
getChannel()->setTopic(command.getParameters().at(2));
} else if (command.getType() == Command::ReplyTopicAuthor){
::Util::Thread::ScopedLock scope(lock);
// Set topic and author
const std::vector<std::string> & params = command.getParameters();
getChannel()->setTopicAuthor(split(params.at(1), '!').at(0), atoi(params.at(2).c_str()));
} else if (command.getType() == Command::ReplyNames){
// Add names
const std::vector<std::string> & params = command.getParameters();
//if (params.at(1) == currentChannel->getName()){
const std::vector<std::string> & names = split(params.at(2), ' ');
::Util::Thread::ScopedLock scope(lock);
//currentChannel->addUsers(names);
ChannelPointer update = findChannel(params.at(1));
if (update != NULL){
update->addUsers(names);
}
//}
}
}
void Client::run(){
while (!end){
try {
const std::string & message = readMessage();
// Check if the message is empty it might be because of (\n)
if (!message.empty()){
Command command(message);
::Util::Thread::ScopedLock scope(lock);
checkResponseAndHandle(command);
commands.push(command);
} else {
}
} catch (const Network::MessageEnd & ex){
end = true;
}
}
}
-ChatInterface::ChatInterface(){
- // Just go to irc.freenode.net for now
- //client = Util::ReferenceCount< Client >(new Client("irc.freenode.net", 8001));
+ChatInterface::ChatInterface(const std::string & host, int port){
+ //client = Util::ReferenceCount< Client >(new Client(host, port));
//client->connect();
+
+ // Setup window size and chat list
+ int width = Configuration::getScreenWidth();
+ int height = Configuration::getScreenHeight();
+
+ Global::debug(0) << "Current Height: " << height * .8 << " Current Width: " << width *.09 << std::endl;
+
+ // chat panel 80% width 90% height
+ chatBox.location.set(0, 0, 0, 0);
+ chatBox.location.setDimensions(width * .8, height * .9);
+ // edit box
+ inputBox.location.set(0, height * .91, 0, 0);
+ inputBox.location.setDimensions(width * .8, height * .09);
+ // Set the location of user list width * .8 and height
}
ChatInterface::~ChatInterface(){
}
void ChatInterface::act(){
+ chatBox.act(Font::getDefaultFont());
+ inputBox.act(Font::getDefaultFont());
}
void ChatInterface::draw(const Graphics::Bitmap & work){
+ chatBox.render(work);
+ inputBox.render(work);
}
Util::ReferenceCount<Client> ChatInterface::getClient(){
return client;
}
}
}
diff --git a/util/network/irc.h b/util/network/irc.h
index ea6efc3c..4212a957 100644
--- a/util/network/irc.h
+++ b/util/network/irc.h
@@ -1,272 +1,274 @@
#ifndef _util_network_irc_h
#define _util_network_irc_h
#include "network.h"
#include "chat.h"
#include "util/pointer.h"
#include "util/thread.h"
#include "util/gui/tabbed-box.h"
+#include "util/gui/lineedit.h"
#include <string>
#include <vector>
#include <queue>
namespace Network{
namespace IRC{
class Command{
public:
enum Type{
Unknown,
Pass,
Nick,
User,
Server,
Oper,
Quit,
Squit,
Join,
Part,
Mode,
Topic,
Names,
List,
Invite,
Kick,
Version,
Stats,
Links,
Time,
Connect,
Trace,
Admin,
Info,
PrivateMessage,
Notice,
Who,
Whois,
Whowas,
Kill,
Ping,
Pong,
Error,
ErrorNickInUse,
ErrorNoSuchNick,
ErrorNoSuchChannel,
ErrorNeedMoreParams,
ErrorBannedFromChannel,
ErrorInviteOnlyChannel,
ErrorBadChannelKey,
ErrorChannelIsFull,
ReplyNames,
ReplyNamesEndOf,
ReplyNoTopic,
ReplyTopic,
ReplyTopicAuthor,
ReplyMOTD,
ReplyMOTDStart,
ReplyMOTDEndOf,
};
// Initializes it from an incoming message off of socket
Command(const std::string &);
// Create a message with owner and type
Command(const std::string &, const Type &);
Command(const Command &);
virtual ~Command();
virtual const Command & operator=(const Command &);
virtual std::string getSendable() const;
virtual inline const std::string & getOwner() const {
return this->owner;
}
virtual inline const Type & getType() const {
return this->type;
}
virtual inline void setParameters(const std::string & param1){
this->parameters.clear();
this->parameters.push_back(param1);
}
virtual inline void setParameters(const std::string & param1, const std::string & param2){
this->parameters.clear();
this->parameters.push_back(param1);
this->parameters.push_back(param2);
}
virtual inline void setParameters(const std::string & param1, const std::string & param2, const std::string & param3){
this->parameters.clear();
this->parameters.push_back(param1);
this->parameters.push_back(param2);
this->parameters.push_back(param3);
}
virtual inline void setParameters(const std::string & param1, const std::string & param2, const std::string & param3, const std::string & param4){
this->parameters.clear();
this->parameters.push_back(param1);
this->parameters.push_back(param2);
this->parameters.push_back(param3);
this->parameters.push_back(param4);
}
virtual inline void setParameters(const std::vector< std::string > & params){
this->parameters = params;
}
virtual inline const std::vector< std::string > & getParameters() const {
return this->parameters;
}
virtual inline bool hasCtcp() {
return !this->ctcp.empty();
}
virtual inline const std::vector< std::string > & getCtcp() const {
return this->ctcp;
}
protected:
std::string owner;
Type type;
std::vector< std::string > parameters;
std::vector< std::string > ctcp;
};
class Channel{
public:
Channel();
Channel(const std::string &);
Channel(const Channel &);
~Channel();
const Channel & operator=(const Channel &);
void addUser(const std::string &);
void removeUser(const std::string &);
void addUsers(const std::vector<std::string> &);
inline const std::vector<std::string> & getUsers() const{
return this->users;
}
inline const std::string & getName() const {
return this->name;
}
inline void setTopic(const std::string & topic){
this->topic = topic;
}
inline void setTopicAuthor(const std::string & topicAuthor, uint64_t topicDate){
this->topicAuthor = topicAuthor;
this->topicDate = topicDate;
}
protected:
std::string name;
std::string topic;
std::string topicAuthor;
uint64_t topicDate;
std::vector<std::string> users;
};
// Channel ReferenceCount
typedef Util::ReferenceCount<Channel> ChannelPointer;
class Client : public Chat::Threadable{
public:
Client(const std::string &, int port);
virtual ~Client();
virtual void connect();
virtual void run();
virtual bool hasCommands() const;
virtual Command nextCommand() const;
virtual void sendCommand(const Command &);
virtual void sendCommand(const Command::Type &);
virtual void sendCommand(const Command::Type &, const std::string &);
virtual void sendCommand(const Command::Type &, const std::string &, const std::string &);
virtual void sendCommand(const Command::Type &, const std::string &, const std::string &, const std::string &);
virtual void sendCommand(const Command::Type &, const std::string &, const std::string &, const std::string &, const std::string &);
virtual void setName(const std::string &);
virtual inline const std::string & getName() const {
return this->username;
}
virtual void joinChannel(const std::string &);
virtual inline ChannelPointer getChannel() const {
return this->activeChannels[this->currentChannel];
}
virtual inline std::vector< ChannelPointer > & channelList(){
return this->activeChannels;
}
virtual std::string channelListAsString();
virtual unsigned int getChannelIndex(const std::string &);
virtual bool isCurrentChannel(const std::string &);
virtual void setChannel(unsigned int channel);
virtual void nextChannel();
virtual void previousChannel();
virtual void sendMessage(const std::string &);
virtual void sendPong(const Command &);
protected:
void removeChannel(const std::string &);
ChannelPointer findChannel(const std::string &);
std::string readMessage();
//! Doesn't do anything to the command just handle some internal changes like username and channel stuff
void checkResponseAndHandle(const Command &);
Network::Socket socket;
std::string previousUsername;
std::string username;
unsigned int previousActiveChannel;
unsigned int currentChannel;
std::vector< ChannelPointer > activeChannels;
std::string hostname;
int port;
bool end;
mutable std::queue< Command > commands;
};
// Create a tabbed chatter to implement in games
class ChatInterface{
public:
- ChatInterface();
+ ChatInterface(const std::string &, int port);
virtual ~ChatInterface();
void act();
void draw(const Graphics::Bitmap &);
Util::ReferenceCount<Client> getClient();
protected:
Util::ReferenceCount<Client> client;
Gui::TabbedBox chatBox;
+ Gui::LineEdit inputBox;
};
}// end irc
}
#endif

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 16, 12:07 AM (2 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71182
Default Alt Text
(48 KB)

Event Timeline