mirror of
https://github.com/correl/mage.git
synced 2024-11-28 11:09:54 +00:00
Set SocketWriteTimeout to 10 seconds.
This commit is contained in:
parent
ed341528d9
commit
35791ac6b7
9 changed files with 164 additions and 154 deletions
|
@ -27,6 +27,21 @@
|
|||
*/
|
||||
package mage.client;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.repository.CardCriteria;
|
||||
import mage.cards.repository.CardInfo;
|
||||
|
@ -77,22 +92,6 @@ import org.mage.plugins.card.images.DownloadPictures;
|
|||
import org.mage.plugins.card.info.CardInfoPaneImpl;
|
||||
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -1056,7 +1055,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
// use already open editor
|
||||
Component[] windows = desktopPane.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER);
|
||||
for (Component window : windows) {
|
||||
if (window instanceof DeckEditorPane && ((MagePane)window).getTitle().equals(name)) {
|
||||
if (window instanceof DeckEditorPane && ((MagePane) window).getTitle().equals(name)) {
|
||||
setActive((MagePane) window);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ public class Connection {
|
|||
private int clientCardDatabaseVersion;
|
||||
private boolean forceDBComparison;
|
||||
private String userIdStr;
|
||||
private int socketWriteTimeout;
|
||||
|
||||
private UserData userData;
|
||||
|
||||
|
@ -76,6 +77,7 @@ public class Connection {
|
|||
|
||||
public Connection(String parameter) {
|
||||
this.parameter = parameter;
|
||||
socketWriteTimeout = 10000;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -276,7 +278,6 @@ public class Connection {
|
|||
return allMACs.toString();
|
||||
}
|
||||
|
||||
|
||||
public void setUserData(UserData userData) {
|
||||
this.userData = userData;
|
||||
}
|
||||
|
@ -292,4 +293,8 @@ public class Connection {
|
|||
public void setForceDBComparison(boolean forceDBComparison) {
|
||||
this.forceDBComparison = forceDBComparison;
|
||||
}
|
||||
|
||||
public int getSocketWriteTimeout() {
|
||||
return socketWriteTimeout;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
*/
|
||||
package mage.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.swing.*;
|
||||
import mage.MageException;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.cards.decks.InvalidDeckException;
|
||||
|
@ -56,13 +62,6 @@ import org.jboss.remoting.transport.bisocket.Bisocket;
|
|||
import org.jboss.remoting.transport.socket.SocketWrapper;
|
||||
import org.jboss.remoting.transporter.TransporterClient;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -220,34 +219,35 @@ public class SessionImpl implements Session {
|
|||
public synchronized boolean connect(final Connection connection) {
|
||||
return establishJBossRemotingConnection(connection)
|
||||
&& handleRemotingTaskExceptions(new RemotingTask() {
|
||||
@Override
|
||||
public boolean run() throws Throwable {
|
||||
logger.info("Trying to log-in as " + getUserName() + " to XMAGE server at " + connection.getHost() + ':' + connection.getPort());
|
||||
boolean registerResult;
|
||||
if (connection.getAdminPassword() == null) {
|
||||
// for backward compatibility. don't remove twice call - first one does nothing but for version checking
|
||||
registerResult = server.connectUser(connection.getUsername(), connection.getPassword(), sessionId, client.getVersion(), connection.getUserIdStr());
|
||||
if (registerResult) {
|
||||
server.setUserData(connection.getUsername(), sessionId, connection.getUserData(), client.getVersion().toString(), connection.getUserIdStr());
|
||||
@Override
|
||||
public boolean run() throws Throwable {
|
||||
logger.info("Trying to log-in as " + getUserName() + " to XMAGE server at " + connection.getHost() + ':' + connection.getPort());
|
||||
boolean registerResult;
|
||||
if (connection.getAdminPassword() == null) {
|
||||
// for backward compatibility. don't remove twice call - first one does nothing but for version checking
|
||||
registerResult = server.connectUser(connection.getUsername(), connection.getPassword(), sessionId, client.getVersion(), connection.getUserIdStr());
|
||||
if (registerResult) {
|
||||
server.setUserData(connection.getUsername(), sessionId, connection.getUserData(), client.getVersion().toString(), connection.getUserIdStr());
|
||||
}
|
||||
} else {
|
||||
registerResult = server.connectAdmin(connection.getAdminPassword(), sessionId, client.getVersion());
|
||||
}
|
||||
if (registerResult) {
|
||||
serverState = server.getServerState();
|
||||
if (!connection.getUsername().equals("Admin")) {
|
||||
updateDatabase(connection.isForceDBComparison(), serverState);
|
||||
}
|
||||
logger.info("Logged-in as " + getUserName() + " to MAGE server at " + connection.getHost() + ':' + connection.getPort());
|
||||
client.connected(getUserName() + '@' + connection.getHost() + ':' + connection.getPort() + ' ');
|
||||
return true;
|
||||
}
|
||||
disconnect(false);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
registerResult = server.connectAdmin(connection.getAdminPassword(), sessionId, client.getVersion());
|
||||
}
|
||||
if (registerResult) {
|
||||
serverState = server.getServerState();
|
||||
if (!connection.getUsername().equals("Admin")) {
|
||||
updateDatabase(connection.isForceDBComparison(), serverState);
|
||||
}
|
||||
logger.info("Logged-in as " + getUserName() + " to MAGE server at " + connection.getHost() + ':' + connection.getPort());
|
||||
client.connected(getUserName() + '@' + connection.getHost() + ':' + connection.getPort() + ' ');
|
||||
return true;
|
||||
}
|
||||
disconnect(false);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getServerHostname() {
|
||||
return isConnected() ? Optional.of(connection.getHost()) : Optional.<String>empty();
|
||||
}
|
||||
|
@ -305,14 +305,14 @@ public class SessionImpl implements Session {
|
|||
to a value greater than 1, an invocation interrupted by a write timeout can be retried.
|
||||
Note. The write timeout facility applies to writing of both invocations and responses. It applies to push callbacks as well.
|
||||
*/
|
||||
metadata.put(SocketWrapper.WRITE_TIMEOUT, "2000");
|
||||
metadata.put(SocketWrapper.WRITE_TIMEOUT, String.valueOf(connection.getSocketWriteTimeout()));
|
||||
metadata.put("generalizeSocketException", "true");
|
||||
server = (MageServer) TransporterClient.createTransporterClient(clientLocator.getLocatorURI(), MageServer.class, metadata);
|
||||
|
||||
// http://docs.jboss.org/jbossremoting/docs/guide/2.5/html_single/#d0e1057
|
||||
Map<String, String> clientMetadata = new HashMap<>();
|
||||
|
||||
clientMetadata.put(SocketWrapper.WRITE_TIMEOUT, "2000");
|
||||
clientMetadata.put(SocketWrapper.WRITE_TIMEOUT, String.valueOf(connection.getSocketWriteTimeout()));
|
||||
/* generalizeSocketException
|
||||
* If set to false, a failed invocation will be retried in the case of
|
||||
* SocketExceptions. If set to true, a failed invocation will be retried in the case of
|
||||
|
@ -473,7 +473,7 @@ public class SessionImpl implements Session {
|
|||
|
||||
/**
|
||||
* @param askForReconnect - true = connection was lost because of error and
|
||||
* ask the user if he want to try to reconnect
|
||||
* ask the user if he want to try to reconnect
|
||||
*/
|
||||
@Override
|
||||
public synchronized void disconnect(boolean askForReconnect) {
|
||||
|
@ -967,7 +967,6 @@ public class SessionImpl implements Session {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean joinGame(UUID gameId) {
|
||||
try {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
leasePeriod - To turn on server side connection failure detection of remoting clients, it is necessary to satisfy two criteria.
|
||||
The first is that the client lease period is set and is a value greater than 0. The value is represented in milliseconds.
|
||||
The client lease period can be set by either the 'clientLeasePeriod' attribute within the Connector configuration or by calling the Connector method
|
||||
socketWriteTimeout - All write operations will time out if they do not complete within the configured period.
|
||||
maxGameThreads - Number of games that can be started simultanously on the server
|
||||
maxSecondsIdle - Number of seconds after that a game is auto conceded by the player that was idle for such a time
|
||||
minUserNameLength - minmal allowed length of a user name to connect to the server
|
||||
|
@ -40,6 +41,7 @@
|
|||
numAcceptThreads="2"
|
||||
maxPoolSize="300"
|
||||
leasePeriod="5000"
|
||||
socketWriteTimeout="10000"
|
||||
maxGameThreads="10"
|
||||
maxSecondsIdle="600"
|
||||
minUserNameLength="3"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
leasePeriod - To turn on server side connection failure detection of remoting clients, it is necessary to satisfy two criteria.
|
||||
The first is that the client lease period is set and is a value greater than 0. The value is represented in milliseconds.
|
||||
The client lease period can be set by either the 'clientLeasePeriod' attribute within the Connector configuration or by calling the Connector method
|
||||
socketWriteTimeout - All write operations will time out if they do not complete within the configured period.
|
||||
maxGameThreads - Number of games that can be started simultanously on the server
|
||||
maxSecondsIdle - Number of seconds after that a game is auto conceded by the player that was idle for such a time
|
||||
minUserNameLength - minmal allowed length of a user name to connect to the server
|
||||
|
@ -39,6 +40,7 @@
|
|||
numAcceptThreads="2"
|
||||
maxPoolSize="300"
|
||||
leasePeriod="5000"
|
||||
socketWriteTimeout="10000"
|
||||
maxGameThreads="10"
|
||||
maxSecondsIdle="600"
|
||||
minUserNameLength="3"
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
*/
|
||||
package mage.server;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.*;
|
||||
import javax.management.MBeanServer;
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.repository.CardScanner;
|
||||
|
@ -59,13 +65,6 @@ import org.jboss.remoting.transporter.TransporterClient;
|
|||
import org.jboss.remoting.transporter.TransporterServer;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -202,6 +201,7 @@ public final class Main {
|
|||
logger.info("Config - save game active: " + (config.isSaveGameActivated() ? "true" : "false"));
|
||||
logger.info("Config - backlog size : " + config.getBacklogSize());
|
||||
logger.info("Config - lease period : " + config.getLeasePeriod());
|
||||
logger.info("Config - sock wrt timeout: " + config.getSocketWriteTimeout());
|
||||
logger.info("Config - max pool size : " + config.getMaxPoolSize());
|
||||
logger.info("Config - num accp.threads: " + config.getNumAcceptThreads());
|
||||
logger.info("Config - second.bind port: " + config.getSecondaryBindPort());
|
||||
|
@ -244,7 +244,7 @@ public final class Main {
|
|||
|
||||
static boolean isAlreadyRunning(InvokerLocator serverLocator) {
|
||||
Map<String, String> metadata = new HashMap<>();
|
||||
metadata.put(SocketWrapper.WRITE_TIMEOUT, "2000");
|
||||
metadata.put(SocketWrapper.WRITE_TIMEOUT, String.valueOf(ConfigSettings.instance.getSocketWriteTimeout()));
|
||||
metadata.put("generalizeSocketException", "true");
|
||||
try {
|
||||
MageServer testServer = (MageServer) TransporterClient.createTransporterClient(serverLocator.getLocatorURI(), MageServer.class, metadata);
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
*/
|
||||
package mage.server.util;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -33,7 +32,6 @@ import java.util.List;
|
|||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
|
||||
import mage.server.util.config.Config;
|
||||
import mage.server.util.config.GamePlugin;
|
||||
import mage.server.util.config.Plugin;
|
||||
|
@ -48,7 +46,6 @@ public enum ConfigSettings {
|
|||
|
||||
private Config config;
|
||||
|
||||
|
||||
ConfigSettings() {
|
||||
try {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance("mage.server.util.config");
|
||||
|
@ -79,6 +76,10 @@ public enum ConfigSettings {
|
|||
return config.getServer().getLeasePeriod().intValue();
|
||||
}
|
||||
|
||||
public int getSocketWriteTimeout() {
|
||||
return config.getServer().getSocketWriteTimeout().intValue();
|
||||
}
|
||||
|
||||
public int getMaxPoolSize() {
|
||||
return config.getServer().getMaxPoolSize().intValue();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
numAcceptThreads="2"
|
||||
maxPoolSize="300"
|
||||
leasePeriod="5000"
|
||||
socketWriteTimeout="10000"
|
||||
maxGameThreads="10"
|
||||
maxSecondsIdle="600"
|
||||
minUserNameLength="3"
|
||||
|
|
|
@ -2,102 +2,103 @@
|
|||
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<xs:element name="config">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="server"/>
|
||||
<xs:element ref="playerTypes"/>
|
||||
<xs:element ref="gameTypes"/>
|
||||
<xs:element ref="tournamentTypes"/>
|
||||
<xs:element ref="draftCubes"/>
|
||||
<xs:element ref="deckTypes"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="config">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="server"/>
|
||||
<xs:element ref="playerTypes"/>
|
||||
<xs:element ref="gameTypes"/>
|
||||
<xs:element ref="tournamentTypes"/>
|
||||
<xs:element ref="draftCubes"/>
|
||||
<xs:element ref="deckTypes"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="server">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="serverAddress" type="xs:string" use="required"/>
|
||||
<xs:attribute name="serverName" type="xs:string" use="required"/>
|
||||
<xs:attribute name="port" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxGameThreads" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxSecondsIdle" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="secondaryBindPort" type="xs:integer" use="required"/>
|
||||
<xs:attribute name="backlogSize" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="numAcceptThreads" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxPoolSize" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="leasePeriod" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="minUserNameLength" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxUserNameLength" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="invalidUserNamePattern" type="xs:string" use="required"/>
|
||||
<xs:attribute name="minPasswordLength" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxPasswordLength" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxAiOpponents" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="saveGameActivated" type="xs:boolean" use="optional"/>
|
||||
<xs:attribute name="authenticationActivated" type="xs:boolean" use="optional"/>
|
||||
<xs:attribute name="googleAccount" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailgunApiKey" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailgunDomain" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailSmtpHost" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailSmtpPort" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailUser" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailPassword" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailFromAddress" type="xs:string" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="server">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="serverAddress" type="xs:string" use="required"/>
|
||||
<xs:attribute name="serverName" type="xs:string" use="required"/>
|
||||
<xs:attribute name="port" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxGameThreads" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxSecondsIdle" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="secondaryBindPort" type="xs:integer" use="required"/>
|
||||
<xs:attribute name="backlogSize" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="numAcceptThreads" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxPoolSize" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="leasePeriod" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="socketWriteTimeout" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="minUserNameLength" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxUserNameLength" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="invalidUserNamePattern" type="xs:string" use="required"/>
|
||||
<xs:attribute name="minPasswordLength" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxPasswordLength" type="xs:positiveInteger" use="required"/>
|
||||
<xs:attribute name="maxAiOpponents" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="saveGameActivated" type="xs:boolean" use="optional"/>
|
||||
<xs:attribute name="authenticationActivated" type="xs:boolean" use="optional"/>
|
||||
<xs:attribute name="googleAccount" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailgunApiKey" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailgunDomain" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailSmtpHost" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailSmtpPort" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailUser" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailPassword" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="mailFromAddress" type="xs:string" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:complexType name="plugin">
|
||||
<xs:attribute name="name" type="xs:string"/>
|
||||
<xs:attribute name="jar" type="xs:string"/>
|
||||
<xs:attribute name="className" type="xs:string"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="plugin">
|
||||
<xs:attribute name="name" type="xs:string"/>
|
||||
<xs:attribute name="jar" type="xs:string"/>
|
||||
<xs:attribute name="className" type="xs:string"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="gamePlugin">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="plugin">
|
||||
<xs:attribute name="typeName" type="xs:string"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="gamePlugin">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="plugin">
|
||||
<xs:attribute name="typeName" type="xs:string"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="playerTypes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="playerType" type="plugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="playerTypes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="playerType" type="plugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="gameTypes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="gameType" type="gamePlugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="gameTypes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="gameType" type="gamePlugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="tournamentTypes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="tournamentType" type="gamePlugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="tournamentTypes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="tournamentType" type="gamePlugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="draftCubes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="draftCube" type="plugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="draftCube" type="plugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="deckTypes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="deckType" type="plugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="deckTypes">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="deckType" type="plugin" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:schema>
|
||||
|
|
Loading…
Reference in a new issue