1
/***************************************************************************
2
* Copyright (C) 2009 by The qGo Project *
4
* This file is part of qGo. *
6
* qGo is free software: you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 2 of the License, or *
9
* (at your option) any later version. *
11
* This program is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU General Public License for more details. *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program; if not, see <http://www.gnu.org/licenses/> *
18
* or write to the Free Software Foundation, Inc., *
19
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
***************************************************************************/
24
#include "../listviews.h"
25
#include "roomregistries.h"
28
#include "gamedialog.h"
29
#include "../mainwindow.h"
30
#include "playergamelistings.h"
31
#include "boarddispatch.h" //so we can remove observers
32
#include "friendslistdialog.h"
34
//#define PLAYERLISTING_ISSUES
37
playerView = mainwindow->getUi()->playerView;
38
gamesView = mainwindow->getUi()->gamesView;
39
refreshPlayersButton = mainwindow->getUi()->pbRefreshPlayers;
40
refreshGamesButton = mainwindow->getUi()->pbRefreshGames;
41
whoBox1 = mainwindow->getUi()->whoBox1;
42
whoBox2 = mainwindow->getUi()->whoBox2;
43
whoOpenCheckBox = mainwindow->getUi()->whoOpenCheck;
44
friendsCheckBox = mainwindow->getUi()->friendsCheck;
45
watchesCheckBox = mainwindow->getUi()->watchesCheck;
46
editFriendsWatchesListButton = mainwindow->getUi()->editFriendsWatchesPB;
47
/* Normally the dispatch and the UI are created at the sametime
48
* by the connection or dispatch code. In this case,
49
* the UI already exists and is being passed straight in here,
50
* so we'll do things backwards and have this create the dispatch */
51
/* UI MUST be created before dispatch. FIXME
52
* This is an ugly non-apparent dependency because
53
* the dispatch registries depend on the UI's models */
54
/* There are further strangenesses here because of the account_name
55
* for making our player listing blue */
58
playerListingRegistry = 0;
59
playerListingIDRegistry = 0;
65
void Room::setupUI(void)
67
gamesListModel = new GamesListModel();
69
/*ui.ListView_games->header()->setSortIndicatorShown ( FALSE );
70
ui.ListView_games->hideColumn(12);
71
ui.ListView_games->hideColumn(13);*/
72
gamesView->setModel(gamesListModel);
73
gamesView->setFilter(new GamesListFilter(gamesListModel));
74
/* Justifications??? */
75
/* No sort indicator??? */
76
/* Qt 4.4.1 made sortIndicatorShown necesssary for sort behavior
78
gamesView->header()->setSortIndicatorShown ( true );
80
//gamesView->setSelectionBehavior(QAbstractItemView::SelectRows);
81
/*ui.gamesView->setColumnWidth ( 0, 40 ); //35
82
ui.gamesView->setColumnWidth ( 1, 100 );
83
ui.gamesView->setColumnWidth ( 2, 48 ); //35
84
ui.gamesView->setColumnWidth ( 3, 100 );
85
ui.gamesView->setColumnWidth ( 4, 48 ); //35
86
ui.gamesView->setColumnWidth ( 5, 45 ); //30
87
ui.gamesView->setColumnWidth ( 6, 45 ); //25
88
ui.gamesView->setColumnWidth ( 7, 38 ); //20
89
ui.gamesView->setColumnWidth ( 8, 35 ); //30
90
ui.gamesView->setColumnWidth ( 9, 43 ); //25
91
ui.gamesView->setColumnWidth ( 10, 60 ); //20
92
ui.gamesView->setColumnWidth ( 11, 55 ); //25
94
//IGS needs bigger rank column with the "+"s, etc., also whole thing looks sloppy FIXME
95
gamesView->setColumnWidth ( 0, 40 ); //35
96
gamesView->setColumnWidth ( 1, 100 );
97
gamesView->setColumnWidth ( 2, 40 ); //35
98
gamesView->setColumnWidth ( 3, 100 );
99
gamesView->setColumnWidth ( 4, 40 ); //35
100
gamesView->setColumnWidth ( 5, 30 ); //30
101
gamesView->setColumnWidth ( 6, 30 ); //25
102
gamesView->setColumnWidth ( 7, 20 ); //20
103
gamesView->setColumnWidth ( 8, 35 ); //30
104
gamesView->setColumnWidth ( 9, 35 ); //25
105
gamesView->setColumnWidth ( 10, 35 ); //20
106
gamesView->setColumnWidth ( 11, 30 ); //25
107
//ui.gamesView->show();
109
playerListModel = new PlayerListModel();
110
/* FIXME the below seems to have no affect, so I commented it out.
111
* I changed references to the listmodel to the sortproxy in the id
112
* registries, in the hope that they would... well I think that was the
113
* wrong way, but I can't be sure since it could be an issue with
114
* the network connection as well... anyway, if I get it working
115
* correctly, probably more like the way it was, then I should change
116
* the sortproxy references back maybe... */
118
// playerView->setIconSize(QSize(20, 20));
119
playerView->setModel(playerListModel);
120
playerListModel->setView(playerView);
121
playerView->setFilter(new PlayerListFilter(playerListModel));
122
playerView->header()->setSortIndicatorShown ( true );
124
playerView->setColumnWidth ( 0, 40 );
125
playerView->setColumnWidth ( 1, 100 );
126
playerView->setColumnWidth ( 2, 40 );
127
playerView->setColumnWidth ( 3, 40 );
128
playerView->setColumnWidth ( 4, 40);
129
playerView->setColumnWidth ( 5, 40 );
130
playerView->setColumnWidth ( 6, 40 );
131
playerView->setColumnWidth ( 7, 40 );
132
playerView->setColumnWidth ( 8, 80 );
133
/*ui.ListView_players->hideColumn(6);
134
ui.ListView_players->hideColumn(7);
135
ui.ListView_players->hideColumn(8);
136
ui.ListView_players->hideColumn(9);
137
ui.ListView_players->hideColumn(12);
138
ui.ListView_players->setColumnWidth ( 0, 30 );
139
ui.ListView_players->setColumnWidth ( 1, 100 );
140
ui.ListView_players->setColumnWidth ( 2, 30 );
141
ui.ListView_players->setColumnWidth ( 3, 30 );
142
ui.ListView_players->setColumnWidth ( 4, 30);
143
ui.ListView_players->setColumnWidth ( 5, 30 );
144
// ui.ListView_players->setColumnWidth ( 6, 80 );
145
ui.ListView_players->setColumnWidth ( 7, 80 );
146
// ui.ListView_players->setColumnWidth ( 8, 30 );
147
// ui.ListView_players->setColumnWidth ( 9, 25 );
148
ui.ListView_players->setColumnWidth ( 10, 50 );
149
// ui.ListView_players->setColumnWidth ( 11, 25 );*/
151
whoBox1->setCurrentIndex(0);
152
whoBox2->setCurrentIndex(0);
153
/* Maybe also a "clicked" for something? */
154
connect(playerView, SIGNAL(doubleClicked(const QModelIndex &)), SLOT(slot_playersDoubleClicked(const QModelIndex &)));
155
connect(playerView, SIGNAL(customContextMenuRequested (const QPoint &)), SLOT(slot_showPopup(const QPoint &)));
156
connect(gamesView, SIGNAL(doubleClicked(const QModelIndex &)), SLOT(slot_gamesDoubleClicked(const QModelIndex &)));
157
connect(gamesView, SIGNAL(customContextMenuRequested (const QPoint &)), SLOT(slot_showGamesPopup(const QPoint &)));
158
connect(refreshPlayersButton, SIGNAL(pressed()), SLOT(slot_refreshPlayers()));
159
connect(refreshGamesButton, SIGNAL(pressed()), SLOT(slot_refreshGames()));
160
connect(whoBox1, SIGNAL(currentIndexChanged(int)), SLOT(slot_setRankSpreadView()));
161
connect(whoBox2, SIGNAL(currentIndexChanged(int)), SLOT(slot_setRankSpreadView()));
162
connect(whoOpenCheckBox, SIGNAL(stateChanged(int)), SLOT(slot_showOpen(int)));
163
connect(friendsCheckBox, SIGNAL(stateChanged(int)), SLOT(slot_showFriends(int)));
164
connect(watchesCheckBox, SIGNAL(stateChanged(int)), SLOT(slot_showWatches(int)));
165
connect(editFriendsWatchesListButton, SIGNAL(pressed()), SLOT(slot_editFriendsWatchesList()));
166
editFriendsWatchesListButton->setEnabled(true);
167
whoOpenCheckBox->setEnabled(true);
168
friendsCheckBox->setEnabled(true);
169
watchesCheckBox->setEnabled(true);
170
playerView->blockSignals(false);
171
gamesView->blockSignals(false);
172
playerView->header()->blockSignals(false);
173
gamesView->header()->blockSignals(false);
178
delete playerListingRegistry;
179
delete playerListingIDRegistry;
180
delete gameListingRegistry;
182
/* FIXME: Should probably be part of something else this P G stuff */
183
mainwindow->statusUsers->setText(" P: 0");
184
mainwindow->statusGames->setText(" G: 0");
185
//mainwindow->ui.changeServerPB->hide(); //done in mainwindow_server
186
//mainwindow->ui.createRoomPB->hide();
188
/* If this was a stand alone room, we'd also destroy the UI
189
* here, I just want to clear the lists */
190
qDebug("Deconstructing room");
191
/* blockSignals necessary in qt 4.7 otherwise setModel(0) crashes stupidly */
192
playerView->blockSignals(true);
193
gamesView->blockSignals(true);
194
playerView->header()->blockSignals(true);
195
gamesView->header()->blockSignals(true);
196
playerView->setModel(0);
197
gamesView->setModel(0);
198
delete playerListModel;
199
delete gamesListModel;
201
disconnect(whoBox1, SIGNAL(currentIndexChanged(int)), 0, 0);
202
disconnect(whoBox2, SIGNAL(currentIndexChanged(int)), 0, 0);
203
disconnect(editFriendsWatchesListButton, SIGNAL(pressed()), 0, 0);
204
disconnect(whoOpenCheckBox, SIGNAL(stateChanged(int)), 0, 0);
205
disconnect(friendsCheckBox, SIGNAL(stateChanged(int)), 0, 0);
206
disconnect(watchesCheckBox, SIGNAL(stateChanged(int)), 0, 0);
207
editFriendsWatchesListButton->setDisabled(true);
210
settings.setValue("LOWRANKFILTER", whoBox1->currentIndex());
211
settings.setValue("HIGHRANKFILTER", whoBox2->currentIndex());
212
whoBox1->setCurrentIndex(0);
213
whoBox2->setCurrentIndex(0);
215
settings.setValue("OPENFILTER", whoOpenCheckBox->isChecked());
216
settings.setValue("FRIENDSFILTER", friendsCheckBox->isChecked());
217
settings.setValue("WATCHESFILTER", watchesCheckBox->isChecked());
218
whoOpenCheckBox->setChecked(false);
219
friendsCheckBox->setChecked(false);
220
watchesCheckBox->setChecked(false);
221
whoOpenCheckBox->setEnabled(false);
222
friendsCheckBox->setEnabled(false);
223
watchesCheckBox->setEnabled(false);
226
void Room::onError(void)
228
/* We're going to call this straight from the network dispatch
229
* until we work out any room UI issues */
230
//mainwindow->onConnectionError();
233
void Room::setConnection(NetworkConnection * c)
236
if(connection->playerTrackingByID())
238
qDebug("Creating player ID Registry");
239
playerListingIDRegistry = new PlayerListingIDRegistry(playerListModel);
243
qDebug("Creating player Registry");
244
playerListingRegistry = new PlayerListingRegistry(playerListModel);
246
gameListingRegistry = new GameListingRegistry(gamesListModel);
248
playerListModel->setAccountName(connection->getUsername());
249
// FIXME, what about observerListModels when they come up on boards?
250
unsigned long flags = connection->getPlayerListColumns();
251
if(flags & PL_NOWINSLOSSES)
253
playerView->hideColumn(5);
254
playerView->hideColumn(6);
256
if(flags & PL_NOMATCHPREFS)
258
playerView->hideColumn(9);
262
QVariant var = settings.value("LOWRANKFILTER");
263
if(var != QVariant())
265
whoBox1->setCurrentIndex(var.toInt());
266
whoBox2->setCurrentIndex(settings.value("HIGHRANKFILTER").toInt());
269
whoOpenCheckBox->setChecked(settings.value("OPENFILTER").toBool());
270
friendsCheckBox->setChecked(settings.value("FRIENDSFILTER").toBool());
271
watchesCheckBox->setChecked(settings.value("WATCHESFILTER").toBool());
274
void Room::updateRoomStats(void)
276
/* With sort, it might be better to get these from the registries?
278
players = playerListModel->rowCount(QModelIndex());
279
games = gamesListModel->rowCount(QModelIndex());
281
//qDebug("%d %d", players, games);
282
mainwindow->statusUsers->setText(" P: " + QString::number(players));
283
mainwindow->statusGames->setText(" G: " + QString::number(games));
287
void Room::slot_playersDoubleClicked(const QModelIndex & index)
289
QModelIndex translated = index;
290
PlayerListing * opponent = playerListModel->playerListingFromIndex(translated);
291
sendStatsRequest(*opponent);
294
void Room::slot_showPopup(const QPoint & iPoint)
296
popup_item = playerView->indexAt(iPoint);
297
if (popup_item != QModelIndex())
299
/* If we have the listing now, we don't need to look it up
300
* again later FIXME */
301
QModelIndex translated = popup_item;
302
popup_playerlisting = playerListModel->playerListingFromIndex(translated);
303
if(popup_playerlisting->name == connection->getUsername())
306
QMenu menu(playerView);
307
menu.addAction(tr("Stats"), this, SLOT(slot_popupStats()));
308
QAction * matchAct = new QAction(tr("Match"), 0);
309
if(popup_playerlisting->info.contains("X"))
310
matchAct->setEnabled(false);
312
connect(matchAct, SIGNAL(triggered()), this, SLOT(slot_popupMatch()));
314
menu.addAction(matchAct);
317
menu.addAction(tr("Talk"), this, SLOT(slot_popupTalk()));
319
if(popup_playerlisting->friendWatchType == PlayerListing::friended)
320
menu.addAction(tr("Remove from Friends"), this, SLOT(slot_removeFriend()));
322
menu.addAction(tr("Add to Friends"), this, SLOT(slot_addFriend()));
323
if(popup_playerlisting->friendWatchType == PlayerListing::watched)
324
menu.addAction(tr("Remove from Watches"), this, SLOT(slot_removeWatch()));
326
menu.addAction(tr("Add to Watches"), this, SLOT(slot_addWatch()));
327
menu.addAction(tr("Block"), this, SLOT(slot_addBlock()));
328
menu.exec(playerView->mapToGlobal(iPoint));
333
void Room::slot_showGamesPopup(const QPoint & iPoint)
337
if(!connection->supportsObserveOutside())
339
popup_item = gamesView->indexAt(iPoint);
340
if (popup_item != QModelIndex())
342
/* Do not give options on rooms without games */
343
QModelIndex translated = popup_item;
344
popup_gamelisting = gamesListModel->gameListingFromIndex(translated);
345
if(popup_gamelisting->isRoomOnly)
347
QMenu menu(gamesView);
348
if(preferences.observe_outside_on_doubleclick)
350
menu.addAction(tr("Observe Outside"), this, SLOT(slot_popupObserveOutside()));
351
menu.addAction(tr("Join and Observe"), this, SLOT(slot_popupJoinObserve()));
355
menu.addAction(tr("Join and Observe"), this, SLOT(slot_popupJoinObserve()));
356
menu.addAction(tr("Observe Outside"), this, SLOT(slot_popupObserveOutside()));
359
menu.exec(gamesView->mapToGlobal(iPoint));
363
void Room::slot_addFriend(void)
365
connection->addFriend(*popup_playerlisting);
368
/* This needs to call a resort or something on the list
369
* if we have "friends" checked, same thing with blocked
370
* if we don't, just to update that one entry FIXME */
371
void Room::slot_removeFriend(void)
373
connection->removeFriend(*popup_playerlisting);
376
void Room::slot_addWatch(void)
378
connection->addWatch(*popup_playerlisting);
381
void Room::slot_removeWatch(void)
383
connection->removeWatch(*popup_playerlisting);
386
void Room::slot_addBlock(void)
388
connection->addBlock(*popup_playerlisting);
391
void Room::slot_popupStats(void)
393
/* For now, just request stats. Later, we might open a separate window with a tab for
395
connection->sendStatsRequest(*popup_playerlisting);
398
void Room::slot_popupMatch(void)
400
connection->sendMatchInvite(*popup_playerlisting);
403
void Room::slot_popupTalk(void)
405
slot_playersDoubleClicked(popup_item);
408
void Room::slot_popupObserveOutside(void)
410
connection->sendObserveOutside(*popup_gamelisting);
413
void Room::slot_popupJoinObserve(void)
415
connection->sendObserve(*popup_gamelisting);
419
void Room::slot_gamesDoubleClicked(const QModelIndex & index)
421
QModelIndex translated = index;
422
const GameListing * g = gamesListModel->gameListingFromIndex(translated);
423
if(preferences.observe_outside_on_doubleclick &&
424
connection->supportsObserveOutside() && !g->isRoomOnly)
425
connection->sendObserveOutside(*g);
427
connection->sendObserve(*g);
430
void Room::slot_refreshPlayers(void)
432
//we don't have to clear the players list
433
//if we're checking for existing player records
435
connection->sendPlayersRequest();
438
void Room::clearPlayerList(void)
440
playerListModel->clearList();
441
if(connection->playerTrackingByID())
443
qDebug("Recreating player ID Registry");
444
delete playerListingIDRegistry;
445
playerListingIDRegistry = new PlayerListingIDRegistry(playerListModel);
449
qDebug("Recreating player Registry");
450
delete playerListingRegistry;
451
playerListingRegistry = new PlayerListingRegistry(playerListModel);
455
void Room::clearGamesList(void)
457
gamesListModel->clearList();
458
delete gameListingRegistry;
459
gameListingRegistry = new GameListingRegistry(gamesListModel);
462
void Room::slot_refreshGames(void)
464
/* First clear list. There doesn't
465
* seem to be a good way to update it
466
* or update everything [IGS issue]. Since we're
467
* getting all info again anyway...
468
* same with players and perhaps
469
* observers as well. */
471
connection->sendGamesRequest();
474
/* This code was taken from mainwindow_server.cpp
475
* I guess it figures out which is min and which
477
void Room::slot_setRankSpreadView(void)
479
QString rkMin, rkMax;
482
if ((whoBox1->currentIndex() == 0) && (whoBox2->currentIndex() == 0))
488
else if ( ((whoBox1->currentIndex() == 0) && (whoBox2->currentIndex() == 1)) ||
489
((whoBox1->currentIndex() == 1) && (whoBox2->currentIndex() == 0)) ||
490
((whoBox1->currentIndex() == 1) && (whoBox2->currentIndex() ==1)) )
496
else if ((whoBox1->currentIndex() == 0) && (whoBox2->currentIndex() > 1))
498
rkMin = whoBox2->currentText();
499
rkMax = whoBox2->currentText();
503
else if ((whoBox1->currentIndex() > 1) && (whoBox2->currentIndex() == 0))
505
rkMin = whoBox1->currentText();
506
rkMax = whoBox1->currentText();
509
else if ((whoBox1->currentIndex() > 1) && (whoBox2->currentIndex() == 1))
511
rkMin = whoBox1->currentText();
515
else if ((whoBox1->currentIndex() == 1) && (whoBox2->currentIndex() > 1))
517
rkMin = whoBox2->currentText();
522
else if ((whoBox2->currentIndex() >= whoBox1->currentIndex() ))
524
rkMin = whoBox2->currentText();
525
rkMax = whoBox1->currentText();
529
rkMin = whoBox1->currentText();
530
rkMax = whoBox2->currentText();
533
dynamic_cast<PlayerListFilter *>(playerView->getFilter())->setFilter(connection->rankToScore(rkMin), connection->rankToScore(rkMax));
534
qDebug( "rank spread : %s - %s" , rkMin.toLatin1().constData() , rkMax.toLatin1().constData());
537
void Room::slot_showOpen(int)
539
dynamic_cast<PlayerListFilter *>(playerView->getFilter())->setFilter(PlayerListFilter::open);
542
void Room::slot_showFriends(int)
544
dynamic_cast<PlayerListFilter *>(playerView->getFilter())->setFilter(PlayerListFilter::friends);
547
void Room::slot_showWatches(int)
549
dynamic_cast<PlayerListFilter *>(playerView->getFilter())->setFilter(PlayerListFilter::fans);
550
dynamic_cast<GamesListFilter *>(gamesView->getFilter())->toggleWatches();
553
void Room::slot_editFriendsWatchesList(void)
555
//does this crash if we do it too soon?
556
FriendsListDialog * fld = new FriendsListDialog(connection);
561
void Room::talkOpened(Talk * d)
563
mainwindow->talkOpened(d);
566
void Room::recvToggle(int type, bool val)
568
mainwindow->slot_checkbox(type, val);
571
GameListing * Room::registerGameListing(GameListing * l)
573
return gameListingRegistry->getEntry(l->number, l);
576
/* This appears to be unused, recvGameListing does stuff
577
* with "->running" FIXME */
578
void Room::unRegisterGameListing(unsigned int key)
580
gameListingRegistry->deleteEntry(key);
583
PlayerListing * Room::getPlayerListing(const QString & name)
586
if(!playerListingRegistry)
588
if(playerListingIDRegistry)
589
p = playerListingIDRegistry->getPlayerFromName(name);
592
qDebug("No player listing registry!");
597
p = playerListingRegistry->getEntry(name); //note getNewEntry not defined and so returns 0 like getIfEntry
600
/* this is tricky FIXME */
602
connection->sendStatsRequest(name);
604
/* Should probably return & FIXME */
608
PlayerListing * Room::getPlayerListing(const unsigned int id)
610
if(!playerListingIDRegistry) //FIXME
612
qDebug("No player listing registry!");
615
PlayerListing * p = playerListingIDRegistry->getEntry(id);
618
connection->sendStatsRequest(id);*/
619
#ifdef PLAYERLISTING_ISSUES
621
qDebug("Can't get player listing for %d", id);
622
#endif //PLAYERLISTING_ISSUES
626
/* Here's the deal with this. Tygem has a username and a nickname.
627
* the nickname is displayed and generally present, but not always. The username
628
* seems to always be present. At first glance, it makes sense to lookup by
629
* the username since that seems how the information is stored and it seems
630
* unique to username. However, if we need to display and sort by the
631
* nickname, that introduces overhead in the listviews that are slow enough
632
* already. It might be minor overhead, and it might be really ugly
633
* to search through all the listings to find a particular username like
634
* this, but I think its better since its done rarely. I may regret this
635
* and change it later. */
636
/* FIXME don't we usually say "from" instead of "by" change this */
637
PlayerListing * Room::getPlayerListingByNotNickname(const QString & notnickname)
640
if(!playerListingRegistry)
642
qDebug("No player listing registry!");
646
p = playerListingRegistry->getPlayerFromNotNickName(notnickname);
648
/* Should probably return & FIXME */
652
/* Remember that this and getPlayerListing do return 0.
653
* getEntry functions like getIfEntry because getNewEntry
654
* is not defined, since we create registry entries for
655
* the games/player registries by passing them */
656
GameListing * Room::getGameListing(unsigned int key)
658
GameListing * l = gameListingRegistry->getEntry(key);
659
/* I'm not sure we'd ever want to automatically
660
* requestGameStats. Either the listing is on the way
661
* or we request it from some other place. The main
662
* thing is we don't want to be requesting it from
663
* the games listing messages every time we try to
664
* get an existing listing. But if its a problem
665
* to just comment out the below two lines, then
666
* we'll need a getIfGameListing as with the
667
* getIfBoardDispatch FIXME */
669
// connection->requestGameStats(key);
673
/* Called from getNewEntry in BoardDispatchRegistry in networkconnection.cpp */
674
class BoardDispatch * Room::getNewBoardDispatch(unsigned int key)
676
/* Oro might pass a game code rather than a number here. But
677
* the listings sometimes only have numbers. We need to
678
* look up in game stuff like moves and results by game code.
679
* we don't have the number there. But this means always
680
* passing game codes to this, but then we can't use getGameListing
681
* initially. Even if we use the number on the initial board get/create
682
* and the game code thereafter, assuming there aren't collisions in
683
* the id spaces, we still have to alter this to be aware of the
684
* ORO protocol. Its a fucking mess. I think we better just store
685
* everything by the key and have a separate lookup, code to key */
686
GameListing * listing = getGameListing(key);
689
/* I'm not so sure about this. FIXME We want BoardDispatch
690
* to have an initial listing maybe but perhaps we should
691
* alter BoardDispatch to be more adaptable in case there
692
* is no listing rather than create a dummy one like this
693
* and just hope it gets filled in later */
694
listing = new GameListing();
695
listing->number = key;
696
registerGameListing(listing);
698
/* Look up game information to pass to board dispatch, if any
699
* ... actually that might be circular, let's NOT do that.
700
* Except, we don't want to overwrite an existing listing */
702
/*GameListing * temp_listing = new GameListing();
703
temp_listing->number = key;
704
listing = registerGameListing(temp_listing);
705
delete temp_listing;*/
707
return new BoardDispatch(connection, listing);
710
std::map<PlayerListing *, unsigned short> removed_player;
711
void Room::recvPlayerListing(PlayerListing * player)
716
if(player->name == "REMOVEMENOTAPLAYER")
723
i = rand() % players;
725
while(!(player = playerListingIDRegistry->getIfEntry(i)));
726
player->online = false;
728
#endif //VIEWTESTDEBUG
729
removed_player[player] = player->playing;
730
#ifdef PLAYERLISTING_ISSUES
731
qDebug("Removing player %s %p on attached game %d", player->name.toLatin1().constData(), player, player->playing);
732
#endif //PLAYERLISTING_ISSUES
733
/* To prevent crashes due to GameListing link to PlayerListing
737
/* FIXME, something should clear this when games end */
738
GameListing * g = getGameListing(player->playing);
741
if(g->black == player)
744
g->_black_name = player->name;
745
g->_black_rank = player->rank;
747
else if(g->white == player)
750
g->_white_name = player->name;
751
g->_white_rank = player->rank;
755
if(player->observing)
757
/* FIXME remove this check, room_list should be sufficient */
758
/* FIXME, something should clear this when games end */
759
BoardDispatch * b = connection->getIfBoardDispatch(player->observing);
762
#ifdef PLAYERLISTING_ISSUES
763
qDebug("Removing player %s on observing game %d", player->name.toLatin1().constData(), player->observing);
764
#endif //PLAYERLISTING_ISSUES
765
b->recvObserver(player, false);
767
if(player->dialog_opened)
768
connection->closeTalk(*player);
770
std::vector<unsigned short>::iterator room_listit = player->room_list.begin();
771
while(room_listit != player->room_list.end())
773
BoardDispatch * boarddispatch = connection->getIfBoardDispatch(*room_listit);
775
boarddispatch->recvObserver(player, false);
777
player->room_list.erase(room_listit);
778
room_listit = player->room_list.begin();
780
if(player->friendWatchType != PlayerListing::none)
781
connection->getAndSetFriendWatchType(*player); //removes
783
PlayerListing * registered_player = 0;
785
connection->getAndSetFriendWatchType(*player);
786
if(playerListingIDRegistry)
789
registered_player = playerListingIDRegistry->getEntry(player->id, player);
791
playerListingIDRegistry->deleteEntry(player->id);
796
registered_player = playerListingRegistry->getEntry(player->name, player);
798
playerListingRegistry->deleteEntry(player->name);
801
if(registered_player && player->online)
803
/* FIXME consider changing name of getEntry with the object?
804
* so that its more clear that it returns a new stored object
805
* based on the one passed. (i.e., looking it up if
807
if(player->dialog_opened)
809
Talk * t = connection->getIfTalk(*player);
811
t->updatePlayerListing();
813
qDebug("dialog_opened flag set but no talk dialog");
817
/* This is just for those listing bugs... its weird...remove it
819
if(registered_player && player->online)
821
std::map<PlayerListing *, unsigned short>::iterator it;
822
it = removed_player.find(registered_player);
823
if(it != removed_player.end())
824
removed_player.erase(it);
826
updateRoomStats(); //in case we lost one or added one
829
/* These two may want to check that they are the mainwindowroom or the
830
* default room or whatever. But its not necessary to have a whole
831
* other subclass for mainwindowrooms because they both need some
832
* kind of ui. It would be more effective to do something with the
834
void Room::recvExtPlayerListing(class PlayerListing * player)
836
mainwindow->slot_statsPlayer(player);
839
void Room::updatePlayerListing(class PlayerListing & player)
841
playerListModel->updateListing(&player);
844
void Room::recvGameListing(GameListing * game)
847
/* This WAS iffy, we WERE using the other ID registry's
848
* existence to indicate an ORO connection in order
849
* to use a different key. Ugly. Once this works,
850
* we need to find a way to hide this within the
851
* connection. It shouldn't be running around here */
852
/* FIXME, turns out that game_number is better for listings
853
* even if we need the code for joining, etc. Its unique
854
* anyway, so who cares */
855
//if(playerListingIDRegistry)
856
// key = game->game_code;
862
game = gameListingRegistry->getEntry(key, game);
863
connection->checkGameWatched(*game);
866
gameListingRegistry->deleteEntry(key);
867
updateRoomStats(); //in case we lost one or added one
870
/* This isn't really just a "sendStats" function anymore, that's
871
* done by the talk object I think and... well its ugly, responsibilities
872
* are crossed, etc.. FIXME */
873
void Room::sendStatsRequest(PlayerListing & opponent)
876
/* Whenever a talk window is opened, we want stats. This
877
* means its easier to create the talk window and let it
878
* always create stats, then send out stats messages
879
* that generate talk windows */
880
/* This is a little weird now...almost like we're just asking
881
* for an update on the references */
882
talk = connection->getTalk(opponent);
883
//connection->sendStatsRequest(opponent);
884
/* This is really only for ORO, and let's see if it works but... */
886
talk->updatePlayerListing();
889
/*** GameListing/PlayerListing Registry functions ***/
891
void GameListingRegistry::initEntry(GameListing * l)
893
gamesListModel->updateListing(l);
896
void GameListingRegistry::onErase(GameListing * l)
898
gamesListModel->removeListing(l);
899
delete l->gameData; //used by ORO
903
void PlayerListingRegistry::initEntry(PlayerListing * l)
905
playerListModel->updateListing(l);
908
void PlayerListingRegistry::onErase(PlayerListing * l)
910
playerListModel->removeListing(l);
914
PlayerListing * PlayerListingRegistry::getPlayerFromNotNickName(const QString & notnickname)
916
std::map<QString, PlayerListing *>::iterator i;
917
for(i = getStorage()->begin(); i != getStorage()->end(); i++)
919
if(i->second->notnickname == notnickname)
925
void PlayerListingIDRegistry::initEntry(PlayerListing * l)
927
playerListModel->updateListing(l);
930
void PlayerListingIDRegistry::onErase(PlayerListing * l)
932
playerListModel->removeListing(l);
936
PlayerListing * PlayerListingIDRegistry::getPlayerFromName(const QString & name)
938
std::map<unsigned int, PlayerListing *>::iterator i;
939
for(i = getStorage()->begin(); i != getStorage()->end(); i++)
941
if(i->second->name == name)