📄 accountbuilder.java
字号:
/*
* Light And Shadow. A Persistent Universe based on Robert Jordan's Wheel of Time Books.
* Copyright (C) 2001-2003 WOTLAS Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package wotlas.server;
import wotlas.common.character.*;
import wotlas.common.universe.*;
import wotlas.common.message.account.*;
import wotlas.utils.*;
import wotlas.libs.net.*;
import wotlas.libs.wizard.*;
import wotlas.common.objects.inventories.Inventory;
import java.lang.reflect.*;
import java.util.Properties;
/** An AccountBuilder helps the creation of a GameAccount for a client. Here is
* how it works :<p><br>
*
* 1 - The client connects to the AccountServer.<br>
*
* 2 - The AccountServer creates a new AccountBuilder and sets it as the client's
* NetMessage context.<br>
*
* 3 - The client discusses with the AccountBuilder to build his GameAccount and
* his PlayerImpl.<br>
*
* 4 - When the account is ready it is saved to disk via the PersistenceManager
* and added to the current running game.<br>
*
* 5 - The client connection is then closed and the AccountBuilder handled to the
* garbage collector. The client can now connect to the GameServer.<br><p>
*
*
* If the creation is successful, the accountServer sends a AccountCreationEndedMessage
* containing the player's IDs.
*
* @author Aldiss, Diego
* @see wotlas.server.AccountServer
*/
public class AccountBuilder implements NetConnectionListener
{
/*------------------------------------------------------------------------------------*/
/** The Game Account we are building
*/
private GameAccount account;
/** The Player Data associated to this GameAccount
*/
private PlayerImpl player;
/** Connection of our client.
*/
private NetConnection connection;
/** Our Account Server
*/
private AccountServer accountServer;
/** Our current step.
*/
private JWizardStepParameters currentParameters;
/*------------------------------------------------------------------------------------*/
/** Constructor.
*/
public AccountBuilder( AccountServer accountServer ) {
this.accountServer = accountServer;
currentParameters=null;
// the account is empty for now...
account = new GameAccount();
player = new PlayerImpl();
player.setDefaultPlayerLocation();
}
/*------------------------------------------------------------------------------------*/
/** Method called when the connection with the client is established.
*
* @param connection
*/
public void connectionCreated( NetConnection connection ) {
this.connection = connection;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** Method called when the connection with the client is established.
*
* @param connection
*/
public void connectionClosed( NetConnection connection ) {
// clean-up
connection = null;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** Called to start the account build.
*/
public void startFirstStep() {
if(currentParameters!=null)
return; // can only call this method once
currentParameters = accountServer.getStepFactory().getStep( AccountStepFactory.FIRST_STEP );
JWizardStepParameters clientParams = currentParameters.getCopyWithNoServerProps();
personalizeParameters( clientParams, currentParameters );
connection.queueMessage( new AccountStepMessage( clientParams ) );
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To return to the previous step.
*/
public void returnToPreviousStep() {
// A - Do we have a previous step to call ?
if( !currentParameters.getIsPrevButtonEnabled() ) {
sendStepError("Previous command is not enabled for this step !!");
return;
}
String previous = currentParameters.getProperty("server.previous");
if(previous==null) {
sendStepError("Previous step not found !");
return;
}
// B - We load the previous step and send it to the client
currentParameters = accountServer.getStepFactory().getStep( previous );
if(currentParameters==null) {
sendStepError("Internal Error. This server was badly configurated.\nPlease mail this server's administrator ! (code: #stpNotFnd)");
return;
}
JWizardStepParameters clientParams = currentParameters.getCopyWithNoServerProps();
personalizeParameters( clientParams, currentParameters );
connection.queueMessage( new AccountStepMessage( clientParams ) );
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To parse the result data and move to the next step.
*/
public void setStepResultData( JWizardStepParameters resultParameters ) {
try{
// A - we retrieve the data properties
String resultPropsKey[] = resultParameters.getStepPropertiesKey();
if(resultPropsKey==null)
resultPropsKey = new String[0];
// B - we call the associated methods of the data properties
String next = null;
for( int i=0; i<resultPropsKey.length; i++ )
if( resultPropsKey[i].startsWith("data.") ) {
// 1 - we get the suffix
String suffix = resultPropsKey[i].substring(
resultPropsKey[i].indexOf('.')+1,
resultPropsKey[i].length() );
// 2 - we get the data
String data = resultParameters.getStepPropertiesValue()[i];
if( suffix.equals("choice") ) {
int ind = -1;
try{
ind = Integer.parseInt(data);
}
catch(Exception ex) {
sendStepError("Selection not valid !");
return;
}
suffix = "choice"+ind;
data = currentParameters.getProperty("init."+suffix);
if(data==null) {
sendStepError("Selection not valid !");
return;
}
}
// 3 - Check for a method to call on this data
String method = currentParameters.getProperty("server."+suffix+".method");
if(method!=null && !invokeMethod(method, data) )
return;
// 4 - Check for default method to call on this data
method = currentParameters.getProperty("server.method");
if(method!=null && !invokeMethod(method, data) )
return;
// 5 - Check for link "next" step
next = currentParameters.getProperty("server."+suffix+".next");
}
// C - Do we have a next step to call ?
if(next==null && !currentParameters.getIsLastStep()) {
// we search for default
next = currentParameters.getProperty("server.next");
if(next==null) {
sendStepError("Internal Error. This server was badly configurated.\nPlease mail this server's administrator ! (code: #nexStpNon)");
return;
}
}
else if( currentParameters.getIsLastStep() ) {
// we create the account and return
try{
createAccount();
}catch( Exception ex ) {
sendStepError("Failed to create account : "+ex.getMessage());
}
return;
}
// D - We load the next step and send it to the client
currentParameters = accountServer.getStepFactory().getStep( next );
if(currentParameters==null) {
sendStepError("Internal Error. This server was badly configurated.\nPlease mail this server's administrator ! (code: #nexStpFai)");
return;
}
JWizardStepParameters clientParams = currentParameters.getCopyWithNoServerProps();
personalizeParameters( clientParams, currentParameters );
connection.queueMessage( new AccountStepMessage( clientParams ) );
}
catch( Exception ex2 ) {
Debug.signal(Debug.ERROR,this,ex2);
sendStepError("Internal Error : "+ex2);
}
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To invoke a method of the 'void XXXX(String data)' type.
* @return true if the method call succeeded, false if it failed and an error msg was
* sent.
*/
private boolean invokeMethod( String method, String data ) {
try{
Class cparams[] = new Class[1];
cparams[0] = String.class;
Method m = getClass().getMethod(method, cparams);
if(m==null) {
sendStepError("Internal Error. This server was badly configurated.\nPlease mail this server's administrator ! (code: #metNofou)");
return false;
}
Object params[] = new Object[1];
params[0] = data;
m.invoke(this,params);
return true;
}
catch( InvocationTargetException ite ) {
sendStepError("Error : "+ite.getTargetException().getMessage());
return false;
}
catch( Exception ex ) {
Debug.signal(Debug.ERROR,this,ex);
sendStepError("Internal Error : ("+ex.getMessage()+") Please report the bug.");
return false;
}
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To invoke a method of the 'String XXXX()' type.
* @return a String if the method call succeeded, null if it fails. In case of
* errors no error message is sent.
*/
private String invokeMethod( String method ) {
try{
Class cparams[] = new Class[0];
Method m = getClass().getMethod(method, cparams);
if(m==null)
return null; // method not found
Object params[] = new Object[0];
return (String) m.invoke(this,params);
}
catch( InvocationTargetException ite ) {
Debug.signal(Debug.ERROR,this,ite.getTargetException().getMessage());
return null;
}
catch( Exception ex ) {
Debug.signal(Debug.ERROR,this,ex);
return null;
}
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To personalize eventual init properties ( we replace $PATTERN$ if there are any
* declared) of parameters that are going to be sent to a client.
* @param clientParameters params to personalize
* @param serverParameters server params to use to personalize client params.
*/
void personalizeParameters( JWizardStepParameters clientParameters,
JWizardStepParameters serverParameters ) {
// A - we retrieve the keys
String propsKey[] = serverParameters.getStepPropertiesKey();
if(propsKey==null)
return; // none
// B - we personalize the init properties
for( int i=0; i<propsKey.length; i++ )
if( propsKey[i].startsWith("server.") && propsKey[i].endsWith("$")) {
// 1 - we get the suffix & pattern
String suffix = propsKey[i].substring(
propsKey[i].indexOf('.')+1,
propsKey[i].indexOf('$')-1 );
String pattern = propsKey[i].substring(
propsKey[i].indexOf('$'),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -