Registration, login and so on...

This commit is contained in:
marcins78@gmail.com
2011-09-17 19:41:20 +00:00
parent fe12db4bfb
commit 545d28abf9
10 changed files with 379 additions and 74 deletions

View File

@@ -2,6 +2,7 @@ package com.gempukku.lotro.db;
import com.gempukku.lotro.db.vo.Player;
import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -10,6 +11,8 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class PlayerDAO {
private final String validLoginChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
private DbAccess _dbAccess;
private Map<String, Player> _players = new ConcurrentHashMap<String, Player>();
@@ -34,6 +37,111 @@ public class PlayerDAO {
}
}
public Player loginUser(String login, String password) throws SQLException {
Connection conn = _dbAccess.getDataSource().getConnection();
try {
PreparedStatement statement = conn.prepareStatement("select id, name from player where name=? and password=?");
try {
statement.setString(1, login);
statement.setString(2, encodePassword(password));
ResultSet rs = statement.executeQuery();
try {
if (rs.next()) {
int id = rs.getInt(1);
String name = rs.getString(2);
return new Player(id, name);
} else
return null;
} finally {
rs.close();
}
} finally {
statement.close();
}
} finally {
conn.close();
}
}
public synchronized boolean registerUser(String login, String password) throws SQLException {
boolean result = validateLogin(login);
if (!result)
return false;
Connection conn = _dbAccess.getDataSource().getConnection();
try {
PreparedStatement statement = conn.prepareStatement("insert into player (name, password, type) values (?, ?, ?)");
try {
statement.setString(1, login);
statement.setString(2, encodePassword(password));
statement.setString(3, "u");
statement.execute();
return true;
} finally {
statement.close();
}
} finally {
conn.close();
}
}
private boolean validateLogin(String login) throws SQLException {
if (login.length() < 2 || login.length() > 10)
return false;
for (int i = 0; i < login.length(); i++) {
char c = login.charAt(i);
if (!validLoginChars.contains("" + c))
return false;
}
String lowerCase = login.toLowerCase();
if (lowerCase.startsWith("admin") || lowerCase.startsWith("guest"))
return false;
Connection conn = _dbAccess.getDataSource().getConnection();
try {
PreparedStatement statement = conn.prepareStatement("select id, name from player where LOWER(name)=?");
try {
statement.setString(1, lowerCase);
ResultSet rs = statement.executeQuery();
try {
if (rs.next()) {
return false;
} else
return true;
} finally {
rs.close();
}
} finally {
statement.close();
}
} finally {
conn.close();
}
}
private String encodePassword(String password) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
return convertToHexString(digest.digest(password.getBytes("UTF-8")));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private String convertToHexString(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1)
hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
private Player getPlayerFromDB(String playerName) throws SQLException {
Connection conn = _dbAccess.getDataSource().getConnection();
try {

View File

@@ -38,6 +38,10 @@ public class HallServer extends AbstractServer {
_supportedFormats.put("Modified FotR block", new ModifiedFotRBlockFormat(_lotroServer.getLotroCardBlueprintLibrary()));
}
public int getTablesCount() {
return _awaitingTables.size() + _runningTables.size();
}
public Set<String> getSupportedFormats() {
return new TreeSet<String>(_supportedFormats.keySet());
}

View File

@@ -35,7 +35,7 @@ import java.util.Set;
@Path("/")
public class ServerResource {
private static final Logger _logger = Logger.getLogger(ServerResource.class);
private boolean _test = true;
private boolean _test = false;
private HallServer _hallServer;
private LotroServer _lotroServer;
@@ -62,15 +62,44 @@ public class ServerResource {
@Path("/login")
@POST
public void login(
@Produces("text/html")
public String login(
@FormParam("login") String login,
@FormParam("password") String password,
@Context HttpServletRequest request) {
_logger.debug("/server/login " + login + ", " + password);
if (login == null)
sendError(Response.Status.NOT_FOUND);
if (password != null && password.equals("test"))
@Context HttpServletRequest request) throws Exception {
if (_lotroServer.getPlayerDao().loginUser(login, password) != null) {
logUser(request, login);
return "<script>location.href='hall.html';</script>";
} else {
return "Invalid login or password. Please try again.<br/>" + getLoginHTML();
}
}
@Path("/register")
@POST
@Produces("text/html")
public String register(
@FormParam("login") String login,
@FormParam("password") String password,
@Context HttpServletRequest request) throws Exception {
if (_lotroServer.getPlayerDao().registerUser(login, password)) {
logUser(request, login);
return "<script>location.href='hall.html';</script>";
} else {
StringBuilder sb = new StringBuilder();
sb.append("User with this name already exists or your login is invalid.<br/>");
sb.append("Login must be between 2-10 characters long, contain only<br/>english letters, numbers or _ (underscore) and - (dash) characters.<br/>");
sb.append("Try to <button id='clickToRegister'>register</button> again.");
return sb.toString();
}
}
private String getLoginHTML() {
StringBuilder sb = new StringBuilder();
sb.append("Login: <input id='login' type='text'><br/>");
sb.append("Password: <input id='password' type='password'><br/>");
sb.append("<button id='loginButton'>Login</button>");
return sb.toString();
}
@Path("/game/{gameId}")
@@ -419,6 +448,24 @@ public class ServerResource {
_hallServer.leaveAwaitingTables(participantId);
}
@GET
@Produces("text/html")
public String getStatus(
@QueryParam("participantId") String participantId,
@Context HttpServletRequest request) throws ParserConfigurationException {
StringBuilder sb = new StringBuilder();
participantId = getUserNameIfLogged(request);
if (participantId != null) {
sb.append("<script>location.href='hall.html';</script>");
} else {
sb.append("You are not logged in, log in below or <button id='clickToRegister'>register</button>.");
sb.append("<div class='status'>There are currently ").append(_hallServer.getTablesCount()).append(" tables in the Game Hall</div>");
sb.append(getLoginHTML());
}
return sb.toString();
}
private Document marshalException(HallException e) throws ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
@@ -611,6 +658,10 @@ public class ServerResource {
request.getSession().setAttribute("logged", login);
}
private String getUserNameIfLogged(HttpServletRequest request) {
return (String) request.getSession().getAttribute("logged");
}
private String getLoggedUser(HttpServletRequest request) {
String loggedUser = (String) request.getSession().getAttribute("logged");
if (loggedUser == null)

View File

@@ -0,0 +1,82 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Gemp-LotR</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="pragma" content="no-cache"/>
<style type="text/css">
body {
font-size: 12px;
}
.tableStatus {
text-align: center;
font-style: italic;
font-size: 120%;
}
.tablePlayer {
text-align: center;
}
.chatMessage {
color: #ffffff;
}
.warningMessage {
color: #ff0000;
}
.chatUser {
color: #ffffff;
}
</style>
<link rel="stylesheet" type="text/css" href="css/dark-hive/jquery-ui-1.8.16.custom.css">
<link rel="stylesheet" type="text/css" href="js/jquery/styles/jquery.spinnercontrol.css">
<script type="text/javascript" src="js/jquery/jquery-1.6.2.js"></script>
<script type="text/javascript" src="js/jquery/jquery-ui-1.8.16.custom.min.js"></script>
<script type="text/javascript" src="js/inheritance.js"></script>
<script type="text/javascript" src="js/logging.js"></script>
<script type="text/javascript" src="js/chat.js"></script>
<script type="text/javascript" src="js/hallUi.js"></script>
<script type="text/javascript" src="js/communication.js"></script>
<script type="text/javascript">
function getUrlParam(param) {
var search = window.location.search.substring(1);
if (search.indexOf('&') > -1) {
var params = search.split('&');
for (var i = 0; i < params.length; i++) {
var key_value = params[i].split('=');
if (key_value[0] == param) return key_value[1];
}
} else {
var params = search.split('=');
if (params[0] == param) return params[1];
}
return null;
}
$(document).ready(
function() {
$("#user").append("Create a table or join one where other player is waiting to start a game.");
var chat = new ChatBoxUI("Game Hall", $("#chat"), "/gemp-lotr/server", true);
chat.setBounds(2, 2, 780 - 4, 200 - 4);
var hall = new GempLotrHallUI($("#hall"), "/gemp-lotr/server", chat);
});
</script>
</head>
<body bgcolor="#00000">
<div id="user" style="position:absolute;left:0px;top:0px;width:780px;height:60px;color:#ffffff;"></div>
<div id="hall" class="ui-widget-content" style="position:absolute;left:0px;top:60px;width:780px;height:260px;"></div>
<div id="chat" class="ui-widget-content" style="position:absolute;left:0px;top:320px;width:780px;height:200px;"></div>
</body>
</html>
17

View File

@@ -11,38 +11,18 @@
font-size: 12px;
}
.tableStatus {
text-align: center;
font-style: italic;
font-size: 120%;
}
.tablePlayer {
text-align: center;
}
.chatMessage {
color: #ffffff;
}
.warningMessage {
color: #ff0000;
}
.chatUser {
color: #ffffff;
.ui-button-text-only .ui-button-text {
font-size: 70%;
padding: .2em .5em;
}
</style>
<link rel="stylesheet" type="text/css" href="css/dark-hive/jquery-ui-1.8.16.custom.css">
<link rel="stylesheet" type="text/css" href="js/jquery/styles/jquery.spinnercontrol.css">
<script type="text/javascript" src="js/jquery/jquery-1.6.2.js"></script>
<script type="text/javascript" src="js/jquery/jquery-ui-1.8.16.custom.min.js"></script>
<script type="text/javascript" src="js/inheritance.js"></script>
<script type="text/javascript" src="js/logging.js"></script>
<script type="text/javascript" src="js/chat.js"></script>
<script type="text/javascript" src="js/hallUi.js"></script>
<script type="text/javascript" src="js/communication.js"></script>
<script type="text/javascript">
@@ -61,36 +41,68 @@
return null;
}
jQuery.fn.center = function () {
this.css("position", "absolute");
this.css("top", (($(window).height() - this.outerHeight()) / 2) + $(window).scrollTop() + "px");
this.css("left", (($(window).width() - this.outerWidth()) / 2) + $(window).scrollLeft() + "px");
return this;
};
var comm = new GempLotrCommunication("/gemp-lotr/server", function() {
alert("Unable to contact the server");
});
function processResponse(html) {
$("#message").append(html).center();
attachEvents();
}
$(document).ready(
function() {
if (getUrlParam("participantId") == null) {
$("#hall").append("Enter your assigned name and press DONE, you have to open one page for each user you want to use now.<br/>");
$("#hall").append("<input id='name' type='text'> ");
var but = $("<button>DONE</button>");
$("#hall").append(but);
but.click(
function() {
location.href = "/gemp-lotr/index.html?participantId=" + $("#name").val();
});
} else {
var participantId = getUrlParam("participantId");
$("#user").append("You are logged in as <b>" + participantId + "</b>.<br/>");
$("#user").append("You may <a href='deckBuild.html?participantId=" + participantId + "'>edit your deck</a>.<br/>");
$("#user").append("Create a table or join one where other player is waiting to start a game.");
var chat = new ChatBoxUI("Game Hall", $("#chat"), "/gemp-lotr/server", true);
chat.setBounds(2, 2, 780 - 4, 200 - 4);
var hall = new GempLotrHallUI($("#hall"), "/gemp-lotr/server", chat);
}
comm.getStatus(processResponse);
});
function attachEvents() {
var loginButton = $("#loginButton");
if (loginButton != null) {
loginButton.button().click(
function() {
var login = $("#login").val();
var password = $("#password").val();
$("#message").html("");
comm.login(login, password, processResponse);
});
}
var registerButton = $("#registerButton");
if (registerButton != null) {
registerButton.button().click(
function() {
var login = $("#login").val();
var password = $("#password").val();
var password2 = $("#password2").val();
if (password != password2) {
alert("Password and Password repeated are different!");
} else {
$("#message").html("");
comm.register(login, password, processResponse);
}
});
}
var clickToRegisterButton = $("#clickToRegister");
if (clickToRegisterButton != null) {
clickToRegisterButton.button().click(
function() {
$("#message").html("");
comm.getRegistrationForm(processResponse);
});
}
}
</script>
</head>
<body bgcolor="#00000">
<div id="user" style="position:absolute;left:0px;top:0px;width:780px;height:60px;color:#ffffff;"></div>
<div id="hall" class="ui-widget-content" style="position:absolute;left:0px;top:60px;width:780px;height:260px;"></div>
<div id="chat" class="ui-widget-content" style="position:absolute;left:0px;top:320px;width:780px;height:200px;"></div>
<div id="message" style="color:#ffffff;"></div>
</body>
</html>
17

View File

@@ -1,16 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>LotR-Online</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="pragma" content="no-cache"/>
</head>
<body>
<form action="/lotro/server/login" method="POST">
<input name="login" type="text"/>
<input name="password" type="password"/>
<input type="submit"/>
</form>
</body>
</html>

View File

@@ -179,5 +179,57 @@ var GempLotrCommunication = Class.extend({
error: this.failure,
dataType: "xml"
});
},
getStatus: function(callback) {
$.ajax({
type: "GET",
url: this.url + "/",
cache: false,
data: {
participantId: getUrlParam("participantId")},
success: callback,
error: this.failure,
dataType: "html"
});
},
login: function(login, password, callback) {
$.ajax({
type: "POST",
url: this.url + "/login",
cache: false,
data: {
login: login,
password: password,
participantId: getUrlParam("participantId")},
success: callback,
error: this.failure,
dataType: "html"
});
},
register: function(login, password, callback) {
$.ajax({
type: "POST",
url: this.url + "/register",
cache: false,
data: {
login: login,
password: password,
participantId: getUrlParam("participantId")},
success: callback,
error: this.failure,
dataType: "html"
});
},
getRegistrationForm: function(callback) {
$.ajax({
type: "POST",
url: "/gemp-lotr/registrationForm.html",
cache: false,
data: {
participantId: getUrlParam("participantId")},
success: callback,
error: this.failure,
dataType: "html"
});
}
});

View File

@@ -453,7 +453,7 @@ var GempLotrGameUI = Class.extend({
var minutes = Math.floor(value / 60);
var seconds = value % 60;
$("#clock" + index).text(sign + minutes + ":" + (seconds < 10) ? ("0" + seconds) : seconds);
$("#clock" + index).text(sign + minutes + ":" + ((seconds < 10) ? ("0" + seconds) : seconds));
}
}

View File

@@ -29,6 +29,14 @@ var GempLotrHallUI = Class.extend({
var that = this;
var editDeck = $("<button>Edit deck</button>");
editDeck.button().click(
function() {
location.href = 'deckBuild.html';
});
buttonsDiv.append(editDeck);
this.supportedFormatsSelect = $("<select></select>");
this.supportedFormatsSelect.hide();
@@ -123,10 +131,10 @@ var GempLotrHallUI = Class.extend({
if (waiting) {
this.supportedFormatsSelect.hide();
this.createTableButton.hide();
this.leaveTableButton.show();
this.leaveTableButton.css("display", "");
} else {
this.supportedFormatsSelect.show();
this.createTableButton.show();
this.supportedFormatsSelect.css("display", "");
this.createTableButton.css("display", "");
this.leaveTableButton.hide();
}

View File

@@ -0,0 +1,4 @@
Login: <input id='login' type='text'><br/>
Password: <input id='password' type='password'><br/>
Password repeated: <input id='password2' type='password'><br/>
<button id='registerButton'>Register</button>