Skip to content

Commit

Permalink
#Version 0.08
Browse files Browse the repository at this point in the history
- Option to show country flags in chat
- Allow double click on player names to challenge/cancel/spectate
- Show Ping and Country for incoming challenge
- Remove challenge/decline table column
  • Loading branch information
doctorguile committed Mar 23, 2014
1 parent 9897286 commit 4f97088
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 44 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7
8
8 changes: 7 additions & 1 deletion WHATSNEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,10 @@ Type `/help` to see a list of commands available
- Add smooth networking settings like in official client
- Add a custom scheme url for accept decline challenge.
- Support custom emoticons
- Use green color for links
- Use green color for links

#Version 0.08
- Option to show country flags in chat
- Allow double click on player names to challenge/cancel/spectate
- Show Ping and Country for incoming challenge
- Remove challenge/decline table column
18 changes: 18 additions & 0 deletions ggpo/common/controller.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import cgi
import os
import re
import socket
Expand Down Expand Up @@ -256,6 +257,23 @@ def getPlayerColor(self, name):
return ColorTheme.getPlayerColor(self.players[name].id)
return '#808080'

def getPlayerFlag(self, name):
if name in self.players:
p = self.players[name]
if p.cc:
return "<img src=':/flags/{}.png'/> ".format(p.cc)

def getPlayerPrefix(self, name, useFlag):
c = self.getPlayerColor(name)
icon = ''
if useFlag:
icon = self.getPlayerFlag(name)
if useFlag:
return '{}<b><font color="{}">{}</font></b> '.format(icon, c, cgi.escape(name))
else:
return '<b><font color="{}">{}</font></b> '.format(c, cgi.escape('<{}>'.format(name)))


def ggpoPathJoin(self, *args):
if self.fba:
return os.path.join(os.path.dirname(self.fba), *args)
Expand Down
2 changes: 1 addition & 1 deletion ggpo/common/copyright.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# define version information
__requires__ = ['PyQt4']
__version__ = 7
__version__ = 8


def versionString():
Expand Down
1 change: 1 addition & 0 deletions ggpo/common/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Settings:
SMOOTHING = 'smoothing'
MUTE_CHALLENGE_SOUND = 'mute'
NOTIFY_PLAYER_STATE_CHANGE = 'notifyPlayerStateChange'
SHOW_COUNTRY_FLAG_IN_CHAT = 'showCountryFlagInChat'
WINDOW_GEOMETRY = 'mainWindowGeometry'
WINDOW_STATE = 'mainWindowState'
SPLITTER_STATE = 'splitterState'
Expand Down
44 changes: 30 additions & 14 deletions ggpo/gui/ggpowindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def onAnchorClicked(self, qurl):
if name in self.controller.challengers:
self.controller.sendDeclineChallenge(name)
self.controller.sigStatusMessage.emit("Declined {}'s challenge".format(name))
self.updateStatusBar()

def onRemoteHasUpdates(self, added, updated, nochange):
totalchanged = added + updated
Expand Down Expand Up @@ -165,10 +166,12 @@ def locateWine(self):
if fname:
Settings.setValue(Settings.WINE_LOCATION, fname)

def notifyStateChange(self, msg):
def notifyStateChange(self, name, msg):
msg = name + msg
if self.lastStateChangeMsg != msg:
self.lastStateChangeMsg = msg
self.uiChatHistoryTxtB.append(ColorTheme.statusHtml(msg))
flag = self.controller.getPlayerFlag(name) or ''
self.uiChatHistoryTxtB.append(flag + ColorTheme.statusHtml(msg))

def onActionFailed(self, txt):
self.uiChatHistoryTxtB.append(ColorTheme.statusHtml(txt))
Expand All @@ -182,18 +185,27 @@ def onChallengeDeclined(self, name):
self.updateStatusBar()

def onChallengeReceived(self, name):
c = self.controller.getPlayerColor(name)
chat = '<b><font color="' + c + '">' + cgi.escape(name) + "</font></b> challenged you - "
extrainfo = []
if name in self.controller.players:
p = self.controller.players[name]
if p.ping:
extrainfo.append('{}ms'.format(p.ping))
if p.country:
extrainfo.append(p.country.decode('utf-8', 'ignore'))
extrainfo = ', '.join(extrainfo)
if extrainfo:
extrainfo = '({}) '.format(extrainfo)
chat = self.controller.getPlayerPrefix(name, True)
chat += " challenged you - " + extrainfo
chat += "<a href='accept:" + name + "'><font color=green>accept</font></a>"
chat += " / <a href='decline:" + name + "'><font color=green>decline</font></a>"
self.uiChatHistoryTxtB.append(chat)
self.playChallengeSound()
self.updateStatusBar()

def onChatReceived(self, name, txt):
c = self.controller.getPlayerColor(name)
chat = '<b><font color="' + c + '">' + cgi.escape('<' + name + '>') + "</font></b> " + cgi.escape(
txt.strip())
chat = self.controller.getPlayerPrefix(name, Settings.value(Settings.SHOW_COUNTRY_FLAG_IN_CHAT)) + \
cgi.escape(txt.strip())
urls = findURLs(txt)
if urls:
for url in urls:
Expand Down Expand Up @@ -231,11 +243,11 @@ def onMOTDReceived(self, channel, topic, msg):
def onPlayerStateChange(self, name, state):
if Settings.value(Settings.NOTIFY_PLAYER_STATE_CHANGE):
if state == PlayerStates.QUIT:
self.notifyStateChange(name + " left")
self.notifyStateChange(name, " left")
elif state == PlayerStates.AVAILABLE:
self.notifyStateChange(name + " becomes available")
self.notifyStateChange(name, " becomes available")
elif state == PlayerStates.PLAYING:
self.notifyStateChange(name + " is in a game")
self.notifyStateChange(name, " is in a game")
self.updateStatusBar()

def onStatusMessage(self, msg):
Expand Down Expand Up @@ -297,6 +309,8 @@ def restorePreference(self):
self.uiMuteChallengeSoundAct.setChecked(True)
if Settings.value(Settings.NOTIFY_PLAYER_STATE_CHANGE):
self.uiNotifyPlayerStateChangeAct.setChecked(True)
if Settings.value(Settings.SHOW_COUNTRY_FLAG_IN_CHAT):
self.uiShowCountryFlagInChatAct.setChecked(True)
fontsetting = Settings.pythonValue(Settings.CHAT_HISTORY_FONT)
if fontsetting:
self.uiChatHistoryTxtB.setFont(QtGui.QFont(*fontsetting))
Expand Down Expand Up @@ -469,6 +483,7 @@ def setupMenuSettings(self):
else:
self.uiLocateGeommdbAct.setVisible(False)
self.uiNotifyPlayerStateChangeAct.toggled.connect(self.__class__.toggleNotifyPlayerStateChange)
self.uiShowCountryFlagInChatAct.toggled.connect(self.__class__.toggleShowCountryFlagInChat)
if Settings.value(Settings.DEBUG_LOG):
self.uiDebugLogAct.setChecked(True)
self.uiDebugLogAct.triggered.connect(self.__class__.debuglogTriggered)
Expand Down Expand Up @@ -526,6 +541,7 @@ def setupUserTable(self):
model = PlayerModel(self.controller)
self.uiPlayersTableV.setModel(model)
self.uiPlayersTableV.clicked.connect(model.onCellClicked)
self.uiPlayersTableV.doubleClicked.connect(model.onCellDoubleClicked)
self.uiPlayersTableV.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
self.uiPlayersTableV.verticalHeader().setVisible(False)
hh = self.uiPlayersTableV.horizontalHeader()
Expand All @@ -540,13 +556,9 @@ def setupUserTable(self):
hh.resizeSection(PlayerModel.IGNORE, 25)
hh.resizeSection(PlayerModel.PLAYER, 165)
hh.resizeSection(PlayerModel.OPPONENT, 165)
hh.resizeSection(PlayerModel.ACCEPT_CHALLENGE, 25)
hh.resizeSection(PlayerModel.DECLINE_CHALLENGE, 25)
hh.setResizeMode(PlayerModel.STATE, QtGui.QHeaderView.Fixed)
hh.setResizeMode(PlayerModel.PING, QtGui.QHeaderView.Fixed)
hh.setResizeMode(PlayerModel.IGNORE, QtGui.QHeaderView.Fixed)
hh.setResizeMode(PlayerModel.ACCEPT_CHALLENGE, QtGui.QHeaderView.Fixed)
hh.setResizeMode(PlayerModel.DECLINE_CHALLENGE, QtGui.QHeaderView.Fixed)
self.uiPlayersTableV.setSortingEnabled(True)
self.uiPlayersTableV.sortByColumn(PlayerModel.DEFAULT_SORT, Qt.AscendingOrder)
hh.sortIndicatorChanged.connect(self.sortIndicatorChanged)
Expand All @@ -563,6 +575,10 @@ def toggleAFK(self, state):
def toggleNotifyPlayerStateChange(state):
Settings.setBoolean(Settings.NOTIFY_PLAYER_STATE_CHANGE, state)

@staticmethod
def toggleShowCountryFlagInChat(state):
Settings.setBoolean(Settings.SHOW_COUNTRY_FLAG_IN_CHAT, state)

@staticmethod
def toggleSound(state):
Settings.setBoolean(Settings.MUTE_CHALLENGE_SOUND, state)
Expand Down
46 changes: 22 additions & 24 deletions ggpo/gui/playermodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ class PlayerModel(QtCore.QAbstractTableModel):

DEFAULT_SORT = PLAYER

# state, player, ping, opponent, ignore, accept challenge, decline challenge
displayColumns = ["", "Player", "Ping", "Opponent", "", "", ""]
ACCEPT_CHALLENGE = 5
DECLINE_CHALLENGE = 6
# state, player, ping, opponent, ignore
displayColumns = ["", "Player", "Ping", "Opponent", ""]
N_DISPLAY_COLS = len(displayColumns)

sortableColumns = [PLAYER, PING, OPPONENT]
Expand All @@ -44,8 +42,6 @@ def __init__(self, controller):
controller.sigPlayersLoaded.connect(self.reloadPlayers)
# TODO: optimize to only update challenge column?
controller.sigChallengeDeclined.connect(self.reloadPlayers)
controller.sigChallengeReceived.connect(self.reloadPlayers)
controller.sigChallengeCancelled.connect(self.reloadPlayers)
# This is very heavy-handed for handling the CLI add/remove changes
controller.sigIgnoreAdded.connect(self.reloadPlayers)
controller.sigIgnoreRemoved.connect(self.reloadPlayers)
Expand All @@ -71,7 +67,6 @@ def data(self, modelIndex, role=None):
return self.controller.players[name].country + ', ' + self.controller.players[name].city
else:
return self.controller.players[name].country

elif role == Qt.CheckStateRole and col == PlayerModel.IGNORE:
return self.players[row][col]
elif role == Qt.DecorationRole:
Expand All @@ -91,12 +86,6 @@ def dataIcon(self, row, col):
icon_path = ':/flags/' + self.players[row][PlayerModel.COUNTRY] + '.png'
elif col == PlayerModel.OPPONENT:
icon_path = ':/flags/' + self.players[row][PlayerModel.OPPONENT_COUNTRY] + '.png'
elif col == PlayerModel.ACCEPT_CHALLENGE:
if self.players[row][PlayerModel.PLAYER] in self.controller.challengers:
icon_path = ':/images/sword-yes.png'
elif col == PlayerModel.DECLINE_CHALLENGE:
if self.players[row][PlayerModel.PLAYER] in self.controller.challengers:
icon_path = ':/images/sword-no.png'
elif col == PlayerModel.STATE:
val = self.players[row][col]
if self.controller.challenged:
Expand Down Expand Up @@ -137,8 +126,6 @@ def headerData(self, section, Qt_Orientation, role=None):
if role == Qt.DecorationRole and Qt_Orientation == Qt.Horizontal:
if section == PlayerModel.IGNORE:
return QtGui.QIcon(':/assets/face-ignore.png')
elif section == PlayerModel.ACCEPT_CHALLENGE:
return QtGui.QIcon(':/images/swords.png')

def onCellClicked(self, index):
col = index.column()
Expand All @@ -159,15 +146,26 @@ def onCellClicked(self, index):
idx2 = self.createIndex(len(self.players) - 1, PlayerModel.STATE)
# noinspection PyUnresolvedReferences
self.dataChanged.emit(idx1, idx2)
if col in [PlayerModel.ACCEPT_CHALLENGE, PlayerModel.DECLINE_CHALLENGE]:
if col == PlayerModel.ACCEPT_CHALLENGE:
self.controller.sendAcceptChallenge(self.players[row][PlayerModel.PLAYER])
elif col == PlayerModel.DECLINE_CHALLENGE:
self.controller.sendDeclineChallenge(self.players[row][PlayerModel.PLAYER])
idx1 = self.createIndex(0, PlayerModel.ACCEPT_CHALLENGE)
idx2 = self.createIndex(len(self.players) - 1, PlayerModel.DECLINE_CHALLENGE)
# noinspection PyUnresolvedReferences
self.dataChanged.emit(idx1, idx2)

def onCellDoubleClicked(self, index):
col = index.column()
row = index.row()
if col == PlayerModel.PLAYER:
modified = False
if self.controller.challenged == self.players[row][PlayerModel.PLAYER]:
self.controller.sendCancelChallenge()
modified = True
elif self.players[row][PlayerModel.STATE] == PlayerModelState.AVAILABLE:
self.controller.sendChallenge(self.players[row][PlayerModel.PLAYER])
modified = True
elif self.players[row][PlayerModel.STATE] == PlayerModelState.PLAYING:
self.controller.sendSpectateRequest(self.players[row][PlayerModel.PLAYER])
modified = True
if modified:
idx1 = self.createIndex(0, PlayerModel.STATE)
idx2 = self.createIndex(len(self.players) - 1, PlayerModel.STATE)
# noinspection PyUnresolvedReferences
self.dataChanged.emit(idx1, idx2)

# noinspection PyUnusedLocal
def reloadPlayers(self, *args):
Expand Down
11 changes: 10 additions & 1 deletion ggpo/gui/ui/ggpowindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@
</property>
</widget>
<addaction name="uiMuteChallengeSoundAct"/>
<addaction name="uiFontAct"/>
<addaction name="uiThemeMenu"/>
<addaction name="uiSmoothingMenu"/>
<addaction name="uiFontAct"/>
<addaction name="uiCustomEmoticonsAct"/>
<addaction name="separator"/>
<addaction name="uiLocateGgpofbaAct"/>
Expand All @@ -142,6 +142,7 @@
<addaction name="uiLocateGeommdbAct"/>
<addaction name="separator"/>
<addaction name="uiNotifyPlayerStateChangeAct"/>
<addaction name="uiShowCountryFlagInChatAct"/>
<addaction name="uiDebugLogAct"/>
</widget>
<widget class="QMenu" name="menuAbout">
Expand Down Expand Up @@ -394,6 +395,14 @@
<string>Custom &amp;Emoticons</string>
</property>
</action>
<action name="uiShowCountryFlagInChatAct">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show &amp;country flag in chat</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
Expand Down
9 changes: 7 additions & 2 deletions ggpo/gui/ui/ggpowindow_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Form implementation generated from reading ui file 'ggpo/gui/ui/ggpowindow.ui'
#
# Created: Sat Mar 22 15:59:28 2014
# Created: Sat Mar 22 18:35:35 2014
# by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!
Expand Down Expand Up @@ -152,6 +152,9 @@ def setupUi(self, MainWindow):
self.action0.setObjectName(_fromUtf8("action0"))
self.uiCustomEmoticonsAct = QtGui.QAction(MainWindow)
self.uiCustomEmoticonsAct.setObjectName(_fromUtf8("uiCustomEmoticonsAct"))
self.uiShowCountryFlagInChatAct = QtGui.QAction(MainWindow)
self.uiShowCountryFlagInChatAct.setCheckable(True)
self.uiShowCountryFlagInChatAct.setObjectName(_fromUtf8("uiShowCountryFlagInChatAct"))
self.menuAction.addAction(self.uiAwayAct)
self.menuAction.addAction(self.uiFocusOnChatAct)
self.menuAction.addAction(self.uiEmoticonAct)
Expand All @@ -169,9 +172,9 @@ def setupUi(self, MainWindow):
self.menuAction.addSeparator()
self.menuAction.addAction(self.uiQuitAct)
self.menuSetting.addAction(self.uiMuteChallengeSoundAct)
self.menuSetting.addAction(self.uiFontAct)
self.menuSetting.addAction(self.uiThemeMenu.menuAction())
self.menuSetting.addAction(self.uiSmoothingMenu.menuAction())
self.menuSetting.addAction(self.uiFontAct)
self.menuSetting.addAction(self.uiCustomEmoticonsAct)
self.menuSetting.addSeparator()
self.menuSetting.addAction(self.uiLocateGgpofbaAct)
Expand All @@ -180,6 +183,7 @@ def setupUi(self, MainWindow):
self.menuSetting.addAction(self.uiLocateGeommdbAct)
self.menuSetting.addSeparator()
self.menuSetting.addAction(self.uiNotifyPlayerStateChangeAct)
self.menuSetting.addAction(self.uiShowCountryFlagInChatAct)
self.menuSetting.addAction(self.uiDebugLogAct)
self.menuAbout.addAction(self.uiSRKForumAct)
self.menuAbout.addAction(self.uiSRKWikiAct)
Expand Down Expand Up @@ -258,5 +262,6 @@ def retranslateUi(self, MainWindow):
self.uiNormalThemeAct.setText(QtGui.QApplication.translate("MainWindow", "&Normal", None, QtGui.QApplication.UnicodeUTF8))
self.action0.setText(QtGui.QApplication.translate("MainWindow", "0", None, QtGui.QApplication.UnicodeUTF8))
self.uiCustomEmoticonsAct.setText(QtGui.QApplication.translate("MainWindow", "Custom &Emoticons", None, QtGui.QApplication.UnicodeUTF8))
self.uiShowCountryFlagInChatAct.setText(QtGui.QApplication.translate("MainWindow", "Show &country flag in chat", None, QtGui.QApplication.UnicodeUTF8))

from ggpo.gui.completionlineedit import CompletionLineEdit

0 comments on commit 4f97088

Please sign in to comment.