mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
Added chat mute and user (de)activation actions to the Mage server console.
This commit is contained in:
parent
7c4b40073c
commit
c46f75ac28
18 changed files with 511 additions and 213 deletions
|
@ -215,6 +215,10 @@ public interface MageServer {
|
|||
|
||||
void muteUser(String sessionId, String userName, long durationMinutes) throws MageException;
|
||||
|
||||
void lockUser(String sessionId, String userName, long durationMinutes) throws MageException;
|
||||
|
||||
void toggleActivation(String sessionId, String userName) throws MageException;
|
||||
|
||||
void removeTable(String sessionId, UUID tableId) throws MageException;
|
||||
|
||||
void sendBroadcastMessage(String sessionId, String message) throws MageException;
|
||||
|
|
|
@ -1440,6 +1440,36 @@ public class SessionImpl implements Session {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean toggleActivation(String userName) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
server.toggleActivation(sessionId, userName);
|
||||
return true;
|
||||
}
|
||||
} catch (MageException ex) {
|
||||
handleMageException(ex);
|
||||
} catch (Throwable t) {
|
||||
handleThrowable(t);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lockUser(String userName, long durationMinute) {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
server.lockUser(sessionId, userName, durationMinute);
|
||||
return true;
|
||||
}
|
||||
} catch (MageException ex) {
|
||||
handleMageException(ex);
|
||||
} catch (Throwable t) {
|
||||
handleThrowable(t);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleThrowable(Throwable t) {
|
||||
logger.fatal("Communication error", t);
|
||||
// Probably this can cause hanging the client under certain circumstances as the disconnect method is synchronized
|
||||
|
|
|
@ -58,5 +58,9 @@ public interface Connect {
|
|||
|
||||
boolean muteUserChat(String userName, long durationMinute);
|
||||
|
||||
boolean toggleActivation(String userName);
|
||||
|
||||
boolean lockUser(String userName, long durationMinute);
|
||||
|
||||
String getSessionId();
|
||||
}
|
||||
|
|
|
@ -43,14 +43,16 @@ public class UserView implements Serializable {
|
|||
private final Date timeConnected;
|
||||
private final String gameInfo;
|
||||
private final String userState;
|
||||
private final Date muteChatUntil;
|
||||
|
||||
public UserView(String userName, String host, String sessionId, Date timeConnected, String gameInfo, String userState) {
|
||||
public UserView(String userName, String host, String sessionId, Date timeConnected, String gameInfo, String userState, Date muteChatUntil) {
|
||||
this.userName = userName;
|
||||
this.host = host;
|
||||
this.sessionId = sessionId;
|
||||
this.timeConnected = timeConnected;
|
||||
this.gameInfo = gameInfo;
|
||||
this.userState = userState;
|
||||
this.muteChatUntil = muteChatUntil;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
|
@ -77,4 +79,8 @@ public class UserView implements Serializable {
|
|||
return userState;
|
||||
}
|
||||
|
||||
public Date getMuteChatUntil() {
|
||||
return muteChatUntil;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,8 +52,9 @@
|
|||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="jPanel3" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jPanel4" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="jPanel4" min="-2" pref="57" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -69,7 +70,7 @@
|
|||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="347" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" alignment="0" pref="339" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
|
@ -104,26 +105,51 @@
|
|||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnDisconnect" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnEndSession" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="sliderMuteDurationMinutes" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="btnMuteUser" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="btnEndSession" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnMuteUser" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="btnDeActivate" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnLockUser" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="50" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblMinutes" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="spinnerMuteDurationMinutes" min="-2" pref="64" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnDisconnect" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnEndSession" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnMuteUser" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnDisconnect" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnEndSession" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnMuteUser" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnDeActivate" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnLockUser" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblMinutes" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spinnerMuteDurationMinutes" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="9" max="32767" attributes="0"/>
|
||||
<Component id="sliderMuteDurationMinutes" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -154,11 +180,30 @@
|
|||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMuteUserActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSlider" name="sliderMuteDurationMinutes">
|
||||
<Component class="javax.swing.JButton" name="btnDeActivate">
|
||||
<Properties>
|
||||
<Property name="maximum" type="int" value="3600"/>
|
||||
<Property name="value" type="int" value="60"/>
|
||||
<Property name="text" type="java.lang.String" value="(de)activate"/>
|
||||
<Property name="actionCommand" type="java.lang.String" value="Mute 1h"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDeActivateActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnLockUser">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Lock user"/>
|
||||
<Property name="actionCommand" type="java.lang.String" value="Mute 1h"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnLockUserActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblMinutes">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Minutes"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spinnerMuteDurationMinutes">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
|
@ -182,7 +227,7 @@
|
|||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="jPanel5" max="32767" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="jPanel6" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
|
@ -194,15 +239,12 @@
|
|||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane2" alignment="0" pref="351" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane2" alignment="0" pref="453" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jScrollPane2" min="-2" pref="343" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jScrollPane2" alignment="0" pref="340" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
|
|
|
@ -70,6 +70,7 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
this.tableUserModel = new TableUserModel();
|
||||
this.tableTableModel = new TableTableModel();
|
||||
initComponents();
|
||||
spinnerMuteDurationMinutes.setValue(60);
|
||||
this.tblUsers.createDefaultColumnsFromModel();
|
||||
this.tblUsers.setRowSorter(new TableRowSorter(tableUserModel));
|
||||
this.tblUsers.setAutoResizeMode(AUTO_RESIZE_OFF);
|
||||
|
@ -127,7 +128,10 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
btnDisconnect = new javax.swing.JButton();
|
||||
btnEndSession = new javax.swing.JButton();
|
||||
btnMuteUser = new javax.swing.JButton();
|
||||
sliderMuteDurationMinutes = new javax.swing.JSlider();
|
||||
btnDeActivate = new javax.swing.JButton();
|
||||
btnLockUser = new javax.swing.JButton();
|
||||
lblMinutes = new javax.swing.JLabel();
|
||||
spinnerMuteDurationMinutes = new javax.swing.JSpinner();
|
||||
jPanel2 = new javax.swing.JPanel();
|
||||
jPanel5 = new javax.swing.JPanel();
|
||||
jScrollPane2 = new javax.swing.JScrollPane();
|
||||
|
@ -149,7 +153,7 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
);
|
||||
jPanel3Layout.setVerticalGroup(
|
||||
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 347, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 339, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
jPanel4.setVerifyInputWhenFocusTarget(false);
|
||||
|
@ -176,8 +180,23 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
}
|
||||
});
|
||||
|
||||
sliderMuteDurationMinutes.setMaximum(3600);
|
||||
sliderMuteDurationMinutes.setValue(60);
|
||||
btnDeActivate.setText("(de)activate");
|
||||
btnDeActivate.setActionCommand("Mute 1h");
|
||||
btnDeActivate.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnDeActivateActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnLockUser.setText("Lock user");
|
||||
btnLockUser.setActionCommand("Mute 1h");
|
||||
btnLockUser.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnLockUserActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblMinutes.setText("Minutes");
|
||||
|
||||
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
|
||||
jPanel4.setLayout(jPanel4Layout);
|
||||
|
@ -187,22 +206,40 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
.addContainerGap()
|
||||
.addComponent(btnDisconnect)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnEndSession)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(sliderMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||
.addComponent(btnMuteUser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap(50, Short.MAX_VALUE))
|
||||
.addGroup(jPanel4Layout.createSequentialGroup()
|
||||
.addComponent(btnEndSession)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnMuteUser))
|
||||
.addGroup(jPanel4Layout.createSequentialGroup()
|
||||
.addComponent(btnDeActivate)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnLockUser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblMinutes)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(spinnerMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel4Layout.setVerticalGroup(
|
||||
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel4Layout.createSequentialGroup()
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnDisconnect)
|
||||
.addComponent(btnEndSession)
|
||||
.addComponent(btnMuteUser))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 9, Short.MAX_VALUE)
|
||||
.addComponent(sliderMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel4Layout.createSequentialGroup()
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnDisconnect)
|
||||
.addComponent(btnEndSession)
|
||||
.addComponent(btnMuteUser))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnDeActivate)
|
||||
.addComponent(btnLockUser)))
|
||||
.addGroup(jPanel4Layout.createSequentialGroup()
|
||||
.addGap(16, 16, 16)
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblMinutes)
|
||||
.addComponent(spinnerMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
|
@ -216,8 +253,9 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
|
||||
jSplitPane1.setLeftComponent(jPanel1);
|
||||
|
@ -229,13 +267,11 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
jPanel5.setLayout(jPanel5Layout);
|
||||
jPanel5Layout.setHorizontalGroup(
|
||||
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 351, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 453, Short.MAX_VALUE)
|
||||
);
|
||||
jPanel5Layout.setVerticalGroup(
|
||||
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel5Layout.createSequentialGroup()
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 343, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 340, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
btnRemoveTable.setLabel("Remove Table");
|
||||
|
@ -272,7 +308,7 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
|
||||
.addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
);
|
||||
|
||||
|
@ -307,12 +343,24 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
|
||||
private void btnMuteUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMuteUserActionPerformed
|
||||
int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow());
|
||||
ConsoleFrame.getSession().muteUserChat((String) tableUserModel.getValueAt(row, TableUserModel.POS_USER_NAME), sliderMuteDurationMinutes.getValue());
|
||||
ConsoleFrame.getSession().muteUserChat((String) tableUserModel.getValueAt(row, TableUserModel.POS_USER_NAME), ((Number) spinnerMuteDurationMinutes.getValue()).longValue());
|
||||
}//GEN-LAST:event_btnMuteUserActionPerformed
|
||||
|
||||
private void btnDeActivateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeActivateActionPerformed
|
||||
int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow());
|
||||
ConsoleFrame.getSession().toggleActivation((String) tableUserModel.getValueAt(row, TableUserModel.POS_USER_NAME));
|
||||
}//GEN-LAST:event_btnDeActivateActionPerformed
|
||||
|
||||
private void btnLockUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLockUserActionPerformed
|
||||
int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow());
|
||||
ConsoleFrame.getSession().lockUser((String) tableUserModel.getValueAt(row, TableUserModel.POS_USER_NAME), ((Number) spinnerMuteDurationMinutes.getValue()).longValue());
|
||||
}//GEN-LAST:event_btnLockUserActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnDeActivate;
|
||||
private javax.swing.JButton btnDisconnect;
|
||||
private javax.swing.JButton btnEndSession;
|
||||
private javax.swing.JButton btnLockUser;
|
||||
private javax.swing.JButton btnMuteUser;
|
||||
private javax.swing.JButton btnRemoveTable;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
|
@ -324,7 +372,8 @@ public class ConsolePanel extends javax.swing.JPanel {
|
|||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JScrollPane jScrollPane2;
|
||||
private javax.swing.JSplitPane jSplitPane1;
|
||||
private javax.swing.JSlider sliderMuteDurationMinutes;
|
||||
private javax.swing.JLabel lblMinutes;
|
||||
private javax.swing.JSpinner spinnerMuteDurationMinutes;
|
||||
private javax.swing.JTable tblTables;
|
||||
private javax.swing.JTable tblUsers;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
@ -338,10 +387,12 @@ class TableUserModel extends AbstractTableModel {
|
|||
public static final int POS_SESSION_ID = 3;
|
||||
public static final int POS_GAME_INFO = 4;
|
||||
public static final int POS_USER_STATE = 5;
|
||||
public static final int POS_CHAT_MUTE = 6;
|
||||
|
||||
private final String[] columnNames = new String[]{"User Name", "Host", "Time Connected", "SessionId", "Gameinfo", "User State"};
|
||||
private final String[] columnNames = new String[]{"User Name", "Host", "Time Connected", "SessionId", "Gameinfo", "User state", "Chat mute"};
|
||||
private UserView[] users = new UserView[0];
|
||||
private static final DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
|
||||
private static final DateFormat formatterTime = new SimpleDateFormat("HH:mm:ss");
|
||||
private static final DateFormat formatterTimeStamp = new SimpleDateFormat("yy-M-dd HH:mm:ss");
|
||||
|
||||
public void loadData(List<UserView> users) {
|
||||
this.users = users.toArray(new UserView[0]);
|
||||
|
@ -366,13 +417,18 @@ class TableUserModel extends AbstractTableModel {
|
|||
case POS_HOST:
|
||||
return users[arg0].getHost();
|
||||
case POS_TIME_CONNECTED:
|
||||
return formatter.format(users[arg0].getConnectionTime());
|
||||
return formatterTime.format(users[arg0].getConnectionTime());
|
||||
case POS_SESSION_ID:
|
||||
return users[arg0].getSessionId();
|
||||
case POS_GAME_INFO:
|
||||
return users[arg0].getGameInfo();
|
||||
case POS_USER_STATE:
|
||||
return users[arg0].getUserState();
|
||||
case POS_CHAT_MUTE:
|
||||
if (users[arg0].getMuteChatUntil() == null) {
|
||||
return "";
|
||||
}
|
||||
return formatterTimeStamp.format(users[arg0].getMuteChatUntil());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
package mage.server;
|
||||
|
||||
import com.j256.ormlite.field.DataType;
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
import java.util.Date;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
||||
import org.apache.shiro.util.ByteSource;
|
||||
import org.apache.shiro.codec.Base64;
|
||||
import org.apache.shiro.crypto.hash.Hash;
|
||||
import org.apache.shiro.util.ByteSource;
|
||||
|
||||
@DatabaseTable(tableName = "authorized_user")
|
||||
public class AuthorizedUser {
|
||||
|
||||
@DatabaseField(indexName = "name_index", unique = true)
|
||||
@DatabaseField(id = true, indexName = "name_index", unique = true)
|
||||
protected String name;
|
||||
|
||||
@DatabaseField
|
||||
|
@ -32,6 +34,18 @@ public class AuthorizedUser {
|
|||
@DatabaseField(indexName = "email_index", unique = true)
|
||||
protected String email;
|
||||
|
||||
@DatabaseField
|
||||
protected boolean active; // the user can't sign in
|
||||
|
||||
@DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss")
|
||||
protected Date lockedUntil; // the user can't sign in until timestamp
|
||||
|
||||
@DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss")
|
||||
protected Date chatLockedUntil; // the user can't use the chat until timestamp
|
||||
|
||||
@DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss")
|
||||
protected Date lastConnection; // time of the last user connect
|
||||
|
||||
public AuthorizedUser() {
|
||||
}
|
||||
|
||||
|
@ -42,6 +56,9 @@ public class AuthorizedUser {
|
|||
this.hashAlgorithm = hash.getAlgorithmName();
|
||||
this.hashIterations = hash.getIterations();
|
||||
this.email = email;
|
||||
this.chatLockedUntil = null;
|
||||
this.active = true;
|
||||
this.lockedUntil = null;
|
||||
}
|
||||
|
||||
public boolean doCredentialsMatch(String name, String password) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.j256.ormlite.table.TableUtils;
|
|||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import mage.cards.repository.CardRepository;
|
||||
import mage.cards.repository.RepositoryUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.shiro.crypto.RandomNumberGenerator;
|
||||
|
@ -27,7 +28,7 @@ public enum AuthorizedUserRepository {
|
|||
private static final String JDBC_URL = "jdbc:h2:file:./db/authorized_user.h2;AUTO_SERVER=TRUE";
|
||||
private static final String VERSION_ENTITY_NAME = "authorized_user";
|
||||
// raise this if db structure was changed
|
||||
private static final long DB_VERSION = 1;
|
||||
private static final long DB_VERSION = 2;
|
||||
private static final RandomNumberGenerator rng = new SecureRandomNumberGenerator();
|
||||
|
||||
private Dao<AuthorizedUser, Object> dao;
|
||||
|
@ -39,16 +40,10 @@ public enum AuthorizedUserRepository {
|
|||
}
|
||||
try {
|
||||
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
|
||||
boolean obsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, DB_VERSION);
|
||||
|
||||
if (obsolete) {
|
||||
TableUtils.dropTable(connectionSource, AuthorizedUser.class, true);
|
||||
}
|
||||
|
||||
TableUtils.createTableIfNotExists(connectionSource, AuthorizedUser.class);
|
||||
dao = DaoManager.createDao(connectionSource, AuthorizedUser.class);
|
||||
} catch (SQLException ex) {
|
||||
Logger.getLogger(AuthorizedUserRepository.class).error("Error creating authorized_user repository - ", ex);
|
||||
Logger.getLogger(AuthorizedUserRepository.class).error("Error creating / assigning authorized_user repository - ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,6 +82,14 @@ public enum AuthorizedUserRepository {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void update(AuthorizedUser authorizedUser) {
|
||||
try {
|
||||
dao.update(authorizedUser);
|
||||
} catch (SQLException ex) {
|
||||
Logger.getLogger(AuthorizedUserRepository.class).error("Error updating authorized_user", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public AuthorizedUser getByEmail(String userName) {
|
||||
try {
|
||||
QueryBuilder<AuthorizedUser, Object> qb = dao.queryBuilder();
|
||||
|
@ -112,4 +115,38 @@ public enum AuthorizedUserRepository {
|
|||
Logger.getLogger(AuthorizedUserRepository.class).error("Error closing authorized_user repository - ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public long getDBVersionFromDB() {
|
||||
try {
|
||||
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
|
||||
return RepositoryUtil.getDatabaseVersion(connectionSource, VERSION_ENTITY_NAME);
|
||||
} catch (SQLException ex) {
|
||||
Logger.getLogger(CardRepository.class).error("Error getting DB version from DB - ", ex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean checkAlterAndMigrateAuthorizedUser() {
|
||||
long currentDBVersion = getDBVersionFromDB();
|
||||
if (currentDBVersion == 1 && DB_VERSION == 2) {
|
||||
return migrateFrom1To2();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean migrateFrom1To2() {
|
||||
try {
|
||||
Logger.getLogger(AuthorizedUserRepository.class).info("Starting " + VERSION_ENTITY_NAME + " DB migration from version 1 to version 2");
|
||||
dao.executeRaw("ALTER TABLE authorized_user ADD COLUMN active BOOLEAN DEFAULT true;");
|
||||
dao.executeRaw("ALTER TABLE authorized_user ADD COLUMN lockedUntil DATETIME;");
|
||||
dao.executeRaw("ALTER TABLE authorized_user ADD COLUMN chatLockedUntil DATETIME;");
|
||||
dao.executeRaw("ALTER TABLE authorized_user ADD COLUMN lastConnection DATETIME;");
|
||||
RepositoryUtil.updateVersion(dao.getConnectionSource(), VERSION_ENTITY_NAME, DB_VERSION);
|
||||
Logger.getLogger(AuthorizedUserRepository.class).info("Migration finished.");
|
||||
return true;
|
||||
} catch (SQLException ex) {
|
||||
Logger.getLogger(AuthorizedUserRepository.class).error("Error while migrating from version 1 to version 2 - ", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,11 @@
|
|||
package mage.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import mage.server.util.SystemUtil;
|
||||
import mage.view.ChatMessage.MessageColor;
|
||||
import mage.view.ChatMessage.MessageType;
|
||||
import mage.view.ChatMessage.SoundToPlay;
|
||||
|
@ -94,10 +96,6 @@ public class ChatManager {
|
|||
}
|
||||
}
|
||||
|
||||
public void broadcast(UUID chatId, String userName, String message, MessageColor color) {
|
||||
this.broadcast(chatId, userName, message, color, true);
|
||||
}
|
||||
|
||||
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime) {
|
||||
this.broadcast(chatId, userName, message, color, withTime, MessageType.TALK);
|
||||
}
|
||||
|
@ -121,8 +119,25 @@ public class ChatManager {
|
|||
}
|
||||
}
|
||||
|
||||
if (!messageType.equals(MessageType.GAME) && message.equals(lastMessage)) {
|
||||
return;
|
||||
if (!messageType.equals(MessageType.GAME)) {
|
||||
if (message.equals(lastMessage)) {
|
||||
// prevent identical messages
|
||||
return;
|
||||
}
|
||||
if (messageType.equals(MessageType.TALK)) {
|
||||
User user = UserManager.getInstance().getUserByName(userName);
|
||||
if (user != null) {
|
||||
if (user.getChatLockedUntil() != null) {
|
||||
if (user.getChatLockedUntil().compareTo(Calendar.getInstance().getTime()) > 0) {
|
||||
chatSessions.get(chatId).broadcastInfoToUser(user, "Your chat is muted until " + SystemUtil.dateFormat.format(user.getChatLockedUntil()));
|
||||
return;
|
||||
} else {
|
||||
user.setChatLockedUntil(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
lastMessage = message;
|
||||
chatSession.broadcast(userName, message, color, withTime, messageType, soundToPlay);
|
||||
|
@ -195,7 +210,7 @@ public class ChatManager {
|
|||
if (user != null) {
|
||||
for (ChatSession chat : chatSessions.values()) {
|
||||
if (chat.hasUser(userId)) {
|
||||
chat.broadcast(user.getName(), message, color);
|
||||
chat.broadcast(user.getName(), message, color, true, MessageType.TALK, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +221,7 @@ public class ChatManager {
|
|||
if (user != null) {
|
||||
for (ChatSession chat : chatSessions.values()) {
|
||||
if (chat.hasUser(userId)) {
|
||||
chat.broadcast(null, user.getName() + " has reconnected", MessageColor.BLUE, true, MessageType.STATUS);
|
||||
chat.broadcast(null, user.getName() + " has reconnected", MessageColor.BLUE, true, MessageType.STATUS, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public class ChatSession {
|
|||
if (user != null && !clients.containsKey(userId)) {
|
||||
String userName = user.getName();
|
||||
clients.put(userId, userName);
|
||||
broadcast(null, userName + " has joined", MessageColor.BLUE, true, MessageType.STATUS);
|
||||
broadcast(null, userName + " has joined", MessageColor.BLUE, true, MessageType.STATUS, null);
|
||||
logger.trace(userName + " joined chat " + chatId);
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ public class ChatSession {
|
|||
message = " left (" + reason.toString() + ")";
|
||||
}
|
||||
if (message != null) {
|
||||
broadcast(null, userName + message, MessageColor.BLUE, true, MessageType.STATUS);
|
||||
broadcast(null, userName + message, MessageColor.BLUE, true, MessageType.STATUS, null);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
|
@ -136,18 +136,6 @@ public class ChatSession {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void broadcast(String userName, String message, MessageColor color) {
|
||||
this.broadcast(userName, message, color, true);
|
||||
}
|
||||
|
||||
public void broadcast(String userName, String message, MessageColor color, boolean withTime) {
|
||||
this.broadcast(userName, message, color, withTime, MessageType.TALK);
|
||||
}
|
||||
|
||||
public void broadcast(String userName, String message, MessageColor color, boolean withTime, MessageType messageType) {
|
||||
this.broadcast(userName, message, color, withTime, messageType, null);
|
||||
}
|
||||
|
||||
public void broadcast(String userName, String message, MessageColor color, boolean withTime, MessageType messageType, SoundToPlay soundToPlay) {
|
||||
if (!message.isEmpty()) {
|
||||
boolean remove = false;
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
package mage.server;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -77,6 +75,7 @@ import mage.server.tournament.TournamentFactory;
|
|||
import mage.server.tournament.TournamentManager;
|
||||
import mage.server.util.ConfigSettings;
|
||||
import mage.server.util.ServerMessagesUtil;
|
||||
import mage.server.util.SystemUtil;
|
||||
import mage.server.util.ThreadExecutor;
|
||||
import mage.utils.ActionWithBooleanResult;
|
||||
import mage.utils.ActionWithNullNegativeResult;
|
||||
|
@ -105,8 +104,6 @@ public class MageServerImpl implements MageServer {
|
|||
private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor();
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-M-dd hh:mm:ss");
|
||||
|
||||
private final String adminPassword;
|
||||
private final boolean testMode;
|
||||
private final LinkedHashMap<String, String> activeAuthTokens = new LinkedHashMap<String, String>() {
|
||||
|
@ -540,7 +537,7 @@ public class MageServerImpl implements MageServer {
|
|||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ChatManager.getInstance().broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE);
|
||||
ChatManager.getInstance().broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE, true, ChatMessage.MessageType.TALK, null);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -1075,7 +1072,9 @@ public class MageServerImpl implements MageServer {
|
|||
user.getSessionId(),
|
||||
user.getConnectionTime(),
|
||||
user.getGameInfo(),
|
||||
user.getUserState().toString()));
|
||||
user.getUserState().toString(),
|
||||
user.getChatLockedUntil()
|
||||
));
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
@ -1100,8 +1099,38 @@ public class MageServerImpl implements MageServer {
|
|||
User user = UserManager.getInstance().getUserByName(userName);
|
||||
if (user != null) {
|
||||
Date muteUntil = new Date(Calendar.getInstance().getTimeInMillis() + (durationMinutes * Timer.ONE_MINUTE));
|
||||
user.showUserMessage("Admin info", "You were muted for chat messages until " + dateFormat.format(muteUntil) + ".");
|
||||
// user.setChatMuteUntil(new Date() + duationMinutes);
|
||||
user.showUserMessage("Admin info", "You were muted for chat messages until " + SystemUtil.dateFormat.format(muteUntil) + ".");
|
||||
user.setChatLockedUntil(muteUntil);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockUser(String sessionId, final String userName, final long durationMinutes) throws MageException {
|
||||
execute("muteUser", sessionId, new Action() {
|
||||
@Override
|
||||
public void execute() {
|
||||
User user = UserManager.getInstance().getUserByName(userName);
|
||||
if (user != null) {
|
||||
Date lockUntil = new Date(Calendar.getInstance().getTimeInMillis() + (durationMinutes * Timer.ONE_MINUTE));
|
||||
user.showUserMessage("Admin info", "Your user profile was locked until " + SystemUtil.dateFormat.format(lockUntil) + ".");
|
||||
user.setLockedUntil(lockUntil);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggleActivation(String sessionId, final String userName) throws MageException {
|
||||
execute("muteUser", sessionId, new Action() {
|
||||
@Override
|
||||
public void execute() {
|
||||
User user = UserManager.getInstance().getUserByName(userName);
|
||||
if (user != null) {
|
||||
user.setActive(!user.isActive());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.repository.CardScanner;
|
||||
|
@ -118,25 +117,42 @@ public class Main {
|
|||
}
|
||||
}
|
||||
|
||||
if (ConfigSettings.getInstance().isAuthenticationActivated()) {
|
||||
logger.info("Check authorized user DB version ...");
|
||||
if (!AuthorizedUserRepository.instance.checkAlterAndMigrateAuthorizedUser()) {
|
||||
logger.fatal("Failed to start server.");
|
||||
return;
|
||||
}
|
||||
logger.info("Done.");
|
||||
}
|
||||
|
||||
logger.info("Loading extension packages...");
|
||||
List<ExtensionPackage> extensions = new ArrayList<>();
|
||||
if(!extensionFolder.exists()) if(!extensionFolder.mkdirs())
|
||||
logger.error("Could not create extensions directory.");
|
||||
File[] extensionDirectories = extensionFolder.listFiles();
|
||||
if(extensionDirectories != null) for(File f : extensionDirectories) if(f.isDirectory())
|
||||
try {
|
||||
logger.info(" - Loading extension from "+f);
|
||||
extensions.add(ExtensionPackageLoader.loadExtension(f));
|
||||
} catch (IOException e) {
|
||||
logger.error("Could not load extension in "+f+"!", e);
|
||||
if (!extensionFolder.exists()) {
|
||||
if (!extensionFolder.mkdirs()) {
|
||||
logger.error("Could not create extensions directory.");
|
||||
}
|
||||
}
|
||||
File[] extensionDirectories = extensionFolder.listFiles();
|
||||
if (extensionDirectories != null) {
|
||||
for (File f : extensionDirectories) {
|
||||
if (f.isDirectory()) {
|
||||
try {
|
||||
logger.info(" - Loading extension from " + f);
|
||||
extensions.add(ExtensionPackageLoader.loadExtension(f));
|
||||
} catch (IOException e) {
|
||||
logger.error("Could not load extension in " + f + "!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("Done.");
|
||||
|
||||
if(!extensions.isEmpty()) {
|
||||
if (!extensions.isEmpty()) {
|
||||
logger.info("Registering custom sets...");
|
||||
for(ExtensionPackage pkg : extensions) {
|
||||
for(ExpansionSet set : pkg.getSets()) {
|
||||
logger.info("- Loading "+set.getName()+" ("+set.getCode()+")");
|
||||
for (ExtensionPackage pkg : extensions) {
|
||||
for (ExpansionSet set : pkg.getSets()) {
|
||||
logger.info("- Loading " + set.getName() + " (" + set.getCode() + ")");
|
||||
Sets.getInstance().addSet(set);
|
||||
}
|
||||
PluginClassloaderRegistery.registerPluginClassloader(pkg.getClassLoader());
|
||||
|
@ -155,7 +171,6 @@ public class Main {
|
|||
logger.info("Updating user stats DB...");
|
||||
UserStatsRepository.instance.updateUserStats();
|
||||
logger.info("Done.");
|
||||
|
||||
deleteSavedGames();
|
||||
ConfigSettings config = ConfigSettings.getInstance();
|
||||
for (GamePlugin plugin : config.getGameTypes()) {
|
||||
|
@ -177,12 +192,12 @@ public class Main {
|
|||
for (ExtensionPackage pkg : extensions) {
|
||||
Map<String, Class> draftCubes = pkg.getDraftCubes();
|
||||
for (String name : draftCubes.keySet()) {
|
||||
logger.info("Loading extension: ["+name+"] "+draftCubes.get(name).toString());
|
||||
logger.info("Loading extension: [" + name + "] " + draftCubes.get(name).toString());
|
||||
CubeFactory.getInstance().addDraftCube(name, draftCubes.get(name));
|
||||
}
|
||||
Map<String, Class> deckTypes = pkg.getDeckTypes();
|
||||
for (String name : deckTypes.keySet()) {
|
||||
logger.info("Loading extension: ["+name+"] "+deckTypes.get(name));
|
||||
logger.info("Loading extension: [" + name + "] " + deckTypes.get(name));
|
||||
DeckValidatorFactory.getInstance().addDeckType(name, deckTypes.get(name));
|
||||
}
|
||||
}
|
||||
|
@ -408,11 +423,11 @@ public class Main {
|
|||
}
|
||||
File[] files = directory.listFiles(
|
||||
new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".game");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".game");
|
||||
}
|
||||
}
|
||||
);
|
||||
for (File file : files) {
|
||||
file.delete();
|
||||
|
|
|
@ -180,14 +180,15 @@ public class Session {
|
|||
|
||||
public String connectUserHandling(String userName, String password) throws MageException {
|
||||
this.isAdmin = false;
|
||||
AuthorizedUser authorizedUser = null;
|
||||
if (ConfigSettings.getInstance().isAuthenticationActivated()) {
|
||||
AuthorizedUser authorizedUser = AuthorizedUserRepository.instance.getByName(userName);
|
||||
authorizedUser = AuthorizedUserRepository.instance.getByName(userName);
|
||||
if (authorizedUser == null || !authorizedUser.doCredentialsMatch(userName, password)) {
|
||||
return "Wrong username or password. In case you haven't, please register your account first.";
|
||||
}
|
||||
}
|
||||
|
||||
User user = UserManager.getInstance().createUser(userName, host);
|
||||
User user = UserManager.getInstance().createUser(userName, host, authorizedUser);
|
||||
boolean reconnect = false;
|
||||
if (user == null) { // user already exists
|
||||
user = UserManager.getInstance().getUserByName(userName);
|
||||
|
@ -223,7 +224,7 @@ public class Session {
|
|||
|
||||
public void connectAdmin() {
|
||||
this.isAdmin = true;
|
||||
User user = UserManager.getInstance().createUser("Admin", host);
|
||||
User user = UserManager.getInstance().createUser("Admin", host, null);
|
||||
if (user == null) {
|
||||
user = UserManager.getInstance().getUserByName("Admin");
|
||||
}
|
||||
|
|
|
@ -91,15 +91,30 @@ public class User {
|
|||
private UserState userState;
|
||||
private UserData userData;
|
||||
private UserStats userStats;
|
||||
private Date chatLockedUntil;
|
||||
private boolean active;
|
||||
private Date lockedUntil;
|
||||
private final AuthorizedUser authorizedUser;
|
||||
|
||||
public User(String userName, String host) {
|
||||
public User(String userName, String host, AuthorizedUser authorizedUser) {
|
||||
this.userId = UUID.randomUUID();
|
||||
this.userName = userName;
|
||||
this.host = host;
|
||||
this.userState = UserState.Created;
|
||||
|
||||
this.connectionTime = new Date();
|
||||
this.lastActivity = new Date();
|
||||
if (authorizedUser != null) {
|
||||
this.active = authorizedUser.active;
|
||||
this.chatLockedUntil = authorizedUser.chatLockedUntil;
|
||||
this.lockedUntil = authorizedUser.lockedUntil;
|
||||
this.authorizedUser = authorizedUser;
|
||||
updateAuthorizedUser();
|
||||
} else {
|
||||
this.active = true;
|
||||
this.chatLockedUntil = null;
|
||||
this.lockedUntil = null;
|
||||
this.authorizedUser = null;
|
||||
}
|
||||
|
||||
this.tables = new ConcurrentHashMap<>();
|
||||
this.gameSessions = new ConcurrentHashMap<>();
|
||||
|
@ -128,6 +143,18 @@ public class User {
|
|||
return sessionId;
|
||||
}
|
||||
|
||||
public Date getChatLockedUntil() {
|
||||
return chatLockedUntil;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public Date getLockedUntil() {
|
||||
return lockedUntil;
|
||||
}
|
||||
|
||||
public void setSessionId(String sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
if (sessionId.isEmpty()) {
|
||||
|
@ -145,6 +172,21 @@ public class User {
|
|||
}
|
||||
}
|
||||
|
||||
public void setChatLockedUntil(Date chatLockedUntil) {
|
||||
this.chatLockedUntil = chatLockedUntil;
|
||||
updateAuthorizedUser();
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
updateAuthorizedUser();
|
||||
}
|
||||
|
||||
public void setLockedUntil(Date lockedUntil) {
|
||||
this.lockedUntil = lockedUntil;
|
||||
updateAuthorizedUser();
|
||||
}
|
||||
|
||||
public void lostConnection() {
|
||||
// Because watched games don't get restored after reconnection call stop watching
|
||||
for (Iterator<UUID> iterator = watchedGames.iterator(); iterator.hasNext();) {
|
||||
|
@ -731,4 +773,12 @@ public class User {
|
|||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
private void updateAuthorizedUser() {
|
||||
if (authorizedUser != null) {
|
||||
authorizedUser.lastConnection = this.connectionTime;
|
||||
authorizedUser.chatLockedUntil = this.chatLockedUntil;
|
||||
AuthorizedUserRepository.instance.update(authorizedUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,11 +76,11 @@ public class UserManager {
|
|||
}, 60, 60, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public User createUser(String userName, String host) {
|
||||
public User createUser(String userName, String host, AuthorizedUser authorizedUser) {
|
||||
if (getUserByName(userName) != null) {
|
||||
return null; //user already exists
|
||||
}
|
||||
User user = new User(userName, host);
|
||||
User user = new User(userName, host, authorizedUser);
|
||||
users.put(user.getId(), user);
|
||||
usersByName.put(userName, user);
|
||||
return user;
|
||||
|
|
|
@ -166,11 +166,11 @@ public class GameController implements GameCallback {
|
|||
updateGame();
|
||||
break;
|
||||
case INFO:
|
||||
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, ChatMessage.MessageType.GAME);
|
||||
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, ChatMessage.MessageType.GAME, null);
|
||||
logger.trace(game.getId() + " " + event.getMessage());
|
||||
break;
|
||||
case STATUS:
|
||||
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), ChatMessage.MessageType.GAME);
|
||||
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), ChatMessage.MessageType.GAME, null);
|
||||
logger.trace(game.getId() + " " + event.getMessage());
|
||||
break;
|
||||
case ERROR:
|
||||
|
@ -346,7 +346,7 @@ public class GameController implements GameCallback {
|
|||
}
|
||||
user.addGame(playerId, gameSession);
|
||||
logger.debug("Player " + player.getName() + " " + playerId + " has " + joinType + " gameId: " + game.getId());
|
||||
ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getLogName() + " has " + joinType + " the game", MessageColor.ORANGE, true, MessageType.GAME);
|
||||
ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getLogName() + " has " + joinType + " the game", MessageColor.ORANGE, true, MessageType.GAME, null);
|
||||
checkStart();
|
||||
}
|
||||
|
||||
|
@ -372,7 +372,7 @@ public class GameController implements GameCallback {
|
|||
GameManager.getInstance().joinGame(game.getId(), user.getId());
|
||||
logger.debug("Player " + player.getName() + " (disconnected) has joined gameId: " + game.getId());
|
||||
}
|
||||
ChatManager.getInstance().broadcast(chatId, player.getName(), user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
|
||||
ChatManager.getInstance().broadcast(chatId, player.getName(), user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
|
||||
if (user.getSecondsDisconnected() > 240) {
|
||||
// Cancel player join possibility lately after 4 minutes
|
||||
logger.debug("Player " + player.getName() + " - canceled game (after 240 seconds) gameId: " + game.getId());
|
||||
|
@ -443,7 +443,7 @@ public class GameController implements GameCallback {
|
|||
watchers.put(userId, gameWatcher);
|
||||
gameWatcher.init();
|
||||
user.addGameWatchInfo(game.getId());
|
||||
ChatManager.getInstance().broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
|
||||
ChatManager.getInstance().broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,7 +451,7 @@ public class GameController implements GameCallback {
|
|||
watchers.remove(userId);
|
||||
User user = UserManager.getInstance().getUser(userId);
|
||||
if (user != null) {
|
||||
ChatManager.getInstance().broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
|
||||
ChatManager.getInstance().broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -678,7 +678,7 @@ public class GameController implements GameCallback {
|
|||
String sb = player.getLogName()
|
||||
+ " has timed out (player had priority and was not active for "
|
||||
+ ConfigSettings.getInstance().getMaxSecondsIdle() + " seconds ) - Auto concede.";
|
||||
ChatManager.getInstance().broadcast(chatId, "", sb, MessageColor.BLACK, true, MessageType.STATUS);
|
||||
ChatManager.getInstance().broadcast(chatId, "", sb, MessageColor.BLACK, true, MessageType.STATUS, null);
|
||||
game.idleTimeout(playerId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,73 +89,73 @@ public class TournamentController {
|
|||
private void init() {
|
||||
tournament.addTableEventListener(
|
||||
new Listener<TableEvent>() {
|
||||
@Override
|
||||
public void event(TableEvent event) {
|
||||
switch (event.getEventType()) {
|
||||
case CHECK_STATE_PLAYERS:
|
||||
checkPlayersState();
|
||||
break;
|
||||
case INFO:
|
||||
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS);
|
||||
logger.debug(tournament.getId() + " " + event.getMessage());
|
||||
break;
|
||||
case START_DRAFT:
|
||||
startDraft(event.getDraft());
|
||||
break;
|
||||
case CONSTRUCT:
|
||||
if (!isAbort()) {
|
||||
construct();
|
||||
} else {
|
||||
endTournament();
|
||||
}
|
||||
break;
|
||||
case START_MATCH:
|
||||
if (!isAbort()) {
|
||||
initTournament(); // set state
|
||||
startMatch(event.getPair(), event.getMatchOptions());
|
||||
}
|
||||
break;
|
||||
case START_MULTIPLAYER_MATCH:
|
||||
if (!isAbort()) {
|
||||
initTournament(); // set state
|
||||
MatchOptions matchOptions = event.getMatchOptions();
|
||||
if (matchOptions != null && event.getMultiplayerRound() != null) {
|
||||
for (TournamentPlayer player : event.getMultiplayerRound().getAllPlayers()) {
|
||||
matchOptions.getPlayerTypes().add(player.getPlayerType());
|
||||
}
|
||||
}
|
||||
|
||||
startMultiplayerMatch(event.getMultiplayerRound(), event.getMatchOptions());
|
||||
}
|
||||
break;
|
||||
case END:
|
||||
endTournament();
|
||||
break;
|
||||
@Override
|
||||
public void event(TableEvent event) {
|
||||
switch (event.getEventType()) {
|
||||
case CHECK_STATE_PLAYERS:
|
||||
checkPlayersState();
|
||||
break;
|
||||
case INFO:
|
||||
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS, null);
|
||||
logger.debug(tournament.getId() + " " + event.getMessage());
|
||||
break;
|
||||
case START_DRAFT:
|
||||
startDraft(event.getDraft());
|
||||
break;
|
||||
case CONSTRUCT:
|
||||
if (!isAbort()) {
|
||||
construct();
|
||||
} else {
|
||||
endTournament();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case START_MATCH:
|
||||
if (!isAbort()) {
|
||||
initTournament(); // set state
|
||||
startMatch(event.getPair(), event.getMatchOptions());
|
||||
}
|
||||
break;
|
||||
case START_MULTIPLAYER_MATCH:
|
||||
if (!isAbort()) {
|
||||
initTournament(); // set state
|
||||
MatchOptions matchOptions = event.getMatchOptions();
|
||||
if (matchOptions != null && event.getMultiplayerRound() != null) {
|
||||
for (TournamentPlayer player : event.getMultiplayerRound().getAllPlayers()) {
|
||||
matchOptions.getPlayerTypes().add(player.getPlayerType());
|
||||
}
|
||||
}
|
||||
|
||||
startMultiplayerMatch(event.getMultiplayerRound(), event.getMatchOptions());
|
||||
}
|
||||
break;
|
||||
case END:
|
||||
endTournament();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
tournament.addPlayerQueryEventListener(
|
||||
new Listener<PlayerQueryEvent>() {
|
||||
@Override
|
||||
public void event(PlayerQueryEvent event) {
|
||||
try {
|
||||
switch (event.getQueryType()) {
|
||||
case CONSTRUCT:
|
||||
construct(event.getPlayerId(), event.getMax());
|
||||
break;
|
||||
}
|
||||
} catch (MageException ex) {
|
||||
logger.fatal("Player event listener error", ex);
|
||||
}
|
||||
@Override
|
||||
public void event(PlayerQueryEvent event) {
|
||||
try {
|
||||
switch (event.getQueryType()) {
|
||||
case CONSTRUCT:
|
||||
construct(event.getPlayerId(), event.getMax());
|
||||
break;
|
||||
}
|
||||
} catch (MageException ex) {
|
||||
logger.fatal("Player event listener error", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
for (TournamentPlayer player : tournament.getPlayers()) {
|
||||
if (!player.getPlayer().isHuman()) {
|
||||
player.setJoined();
|
||||
logger.debug("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId());
|
||||
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS);
|
||||
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS, null);
|
||||
}
|
||||
}
|
||||
checkStart();
|
||||
|
@ -185,7 +185,7 @@ public class TournamentController {
|
|||
TournamentPlayer player = tournament.getPlayer(playerId);
|
||||
player.setJoined();
|
||||
logger.debug("player " + player.getPlayer().getName() + " - client has joined tournament " + tournament.getId());
|
||||
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS);
|
||||
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS, null);
|
||||
checkStart();
|
||||
} else {
|
||||
logger.error("User not found userId: " + userId + " tournamentId: " + tournament.getId());
|
||||
|
@ -209,11 +209,11 @@ public class TournamentController {
|
|||
if (!started && allJoined()) {
|
||||
ThreadExecutor.getInstance().getCallExecutor().execute(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startTournament();
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void run() {
|
||||
startTournament();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ public class TournamentController {
|
|||
logger.fatal("TournamentController startMatch error", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void startMultiplayerMatch(MultiplayerRound round, MatchOptions matchOptions) {
|
||||
try {
|
||||
TableManager tableManager = TableManager.getInstance();
|
||||
|
@ -286,7 +286,7 @@ public class TournamentController {
|
|||
table.setTournamentSubTable(true);
|
||||
table.setTournament(tournament);
|
||||
table.setState(TableState.WAITING);
|
||||
|
||||
|
||||
for (TournamentPlayer player : round.getAllPlayers()) {
|
||||
tableManager.addPlayer(getPlayerUserId(player.getPlayer().getId()), table.getId(), player.getPlayer(), player.getPlayerType(), player.getDeck());
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ public class TournamentController {
|
|||
} catch (GameException ex) {
|
||||
logger.fatal("TournamentController startMatch error", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startDraft(Draft draft) {
|
||||
TableManager.getInstance().startDraft(tableId, draft);
|
||||
|
@ -447,7 +447,7 @@ public class TournamentController {
|
|||
user.removeTable(leavingPlayer.getPlayer().getId());
|
||||
user.removeTournament(leavingPlayer.getPlayer().getId());
|
||||
}
|
||||
ChatManager.getInstance().broadcast(chatId, "", leavingPlayer.getPlayer().getLogName() + " was replaced by draftbot", MessageColor.BLACK, true, MessageType.STATUS);
|
||||
ChatManager.getInstance().broadcast(chatId, "", leavingPlayer.getPlayer().getLogName() + " was replaced by draftbot", MessageColor.BLACK, true, MessageType.STATUS, null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
package mage.server.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.repository.CardInfo;
|
||||
import mage.cards.repository.CardRepository;
|
||||
|
@ -8,36 +19,30 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
import mage.util.RandomUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
public class SystemUtil {
|
||||
|
||||
public static final DateFormat dateFormat = new SimpleDateFormat("yy-M-dd HH:mm:ss");
|
||||
|
||||
private static final String INIT_FILE_PATH = "config" + File.separator + "init.txt";
|
||||
private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(SystemUtil.class);
|
||||
private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(SystemUtil.class);
|
||||
|
||||
/**
|
||||
* Replaces cards in player's hands by specified in config/init.txt.<br/>
|
||||
* <br/>
|
||||
* <b>Implementation note:</b><br/>
|
||||
* 1. Read init.txt line by line<br/>
|
||||
* 2. Parse line using the following format: line ::= <zone>:<nickname>:<card name>:<amount><br/>
|
||||
* 2. Parse line using the following format: line ::=
|
||||
* <zone>:<nickname>:<card name>:<amount><br/>
|
||||
* 3. If zone equals to 'hand', add card to player's library<br/>
|
||||
* 3a. Then swap added card with any card in player's hand<br/>
|
||||
* 3b. Parse next line (go to 2.), If EOF go to 4.<br/>
|
||||
* 4. Log message to all players that cards were added (to prevent unfair play).<br/>
|
||||
* 3a. Then swap added card with any card in player's hand<br/>
|
||||
* 3b. Parse next line (go to 2.), If EOF go to 4.<br/>
|
||||
* 4. Log message to all players that cards were added (to prevent unfair
|
||||
* play).<br/>
|
||||
* 5. Exit<br/>
|
||||
*
|
||||
* @param game
|
||||
*/
|
||||
public static void addCardsForTesting(Game game) {
|
||||
|
@ -109,8 +114,7 @@ public class SystemUtil {
|
|||
swapWithAnyCard(game, player, card, gameZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
scanner.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -137,7 +141,7 @@ public class SystemUtil {
|
|||
} else {
|
||||
card.moveToZone(zone, null, game, false);
|
||||
}
|
||||
logger.info("Added card to player's " + zone.toString() + ": " + card.getName() +", player = " + player.getName());
|
||||
logger.info("Added card to player's " + zone.toString() + ": " + card.getName() + ", player = " + player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,7 +152,7 @@ public class SystemUtil {
|
|||
* @return
|
||||
*/
|
||||
private static Player findPlayer(Game game, String name) {
|
||||
for (Player player: game.getPlayers().values()) {
|
||||
for (Player player : game.getPlayers().values()) {
|
||||
if (player.getName().equals(name)) {
|
||||
return player;
|
||||
}
|
||||
|
@ -162,7 +166,7 @@ public class SystemUtil {
|
|||
//return matcher.replaceAll("");
|
||||
return input.replaceAll("[^a-zA-Z0-9]", "");
|
||||
}
|
||||
|
||||
|
||||
public static void main(String... args) {
|
||||
System.out.println(sanitize("123"));
|
||||
System.out.println(sanitize("AaAaD_123"));
|
||||
|
|
Loading…
Reference in a new issue