Skip to content

Commit 55694fc

Browse files
author
Ray Tsang
committed
1 parent cf6a5c2 commit 55694fc

File tree

12 files changed

+944
-0
lines changed

12 files changed

+944
-0
lines changed

appengine/channel/pom.xml

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<!--
2+
Copyright 2015 Google Inc. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<project>
17+
<modelVersion>4.0.0</modelVersion>
18+
<packaging>war</packaging>
19+
<version>1.0-SNAPSHOT</version>
20+
<groupId>com.example.appengine</groupId>
21+
<artifactId>appengine-channel</artifactId>
22+
<parent>
23+
<groupId>com.google.cloud</groupId>
24+
<artifactId>doc-samples</artifactId>
25+
<version>1.0.0</version>
26+
<relativePath>../..</relativePath>
27+
</parent>
28+
<properties>
29+
<objectify.version>5.1.5</objectify.version>
30+
</properties>
31+
<!-- [START set_versions] -->
32+
<prerequisites>
33+
<maven>3.3.9</maven>
34+
</prerequisites>
35+
<!-- [END set_versions] -->
36+
<dependencies>
37+
<dependency>
38+
<groupId>com.google.appengine</groupId>
39+
<artifactId>appengine-api-1.0-sdk</artifactId>
40+
<version>${appengine.sdk.version}</version>
41+
</dependency>
42+
<dependency>
43+
<groupId>javax.servlet</groupId>
44+
<artifactId>servlet-api</artifactId>
45+
<version>2.5</version>
46+
<type>jar</type>
47+
<scope>provided</scope>
48+
</dependency>
49+
<dependency>
50+
<groupId>org.json</groupId>
51+
<artifactId>json</artifactId>
52+
<version>20160212</version>
53+
</dependency>
54+
<dependency>
55+
<groupId>com.googlecode.objectify</groupId>
56+
<artifactId>objectify</artifactId>
57+
<version>${objectify.version}</version>
58+
</dependency>
59+
60+
<!-- Test Dependencies -->
61+
<dependency>
62+
<groupId>junit</groupId>
63+
<artifactId>junit</artifactId>
64+
<version>4.10</version>
65+
<scope>test</scope>
66+
</dependency>
67+
<dependency>
68+
<groupId>org.mockito</groupId>
69+
<artifactId>mockito-all</artifactId>
70+
<version>1.10.19</version>
71+
<scope>test</scope>
72+
</dependency>
73+
<dependency>
74+
<groupId>com.google.appengine</groupId>
75+
<artifactId>appengine-testing</artifactId>
76+
<version>${appengine.sdk.version}</version>
77+
<scope>test</scope>
78+
</dependency>
79+
<dependency>
80+
<groupId>com.google.appengine</groupId>
81+
<artifactId>appengine-api-stubs</artifactId>
82+
<version>${appengine.sdk.version}</version>
83+
<scope>test</scope>
84+
</dependency>
85+
<dependency>
86+
<groupId>com.google.appengine</groupId>
87+
<artifactId>appengine-tools-sdk</artifactId>
88+
<version>${appengine.sdk.version}</version>
89+
<scope>test</scope>
90+
</dependency>
91+
<dependency>
92+
<groupId>com.google.truth</groupId>
93+
<artifactId>truth</artifactId>
94+
<version>0.28</version>
95+
<scope>test</scope>
96+
</dependency>
97+
</dependencies>
98+
<build>
99+
<!-- for hot reload of the web application -->
100+
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
101+
<plugins>
102+
<!-- Parent POM defines ${appengine.sdk.version} (updates frequently). -->
103+
<plugin>
104+
<groupId>com.google.appengine</groupId>
105+
<artifactId>appengine-maven-plugin</artifactId>
106+
<version>${appengine.sdk.version}</version>
107+
</plugin>
108+
</plugins>
109+
</build>
110+
</project>
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.appengine.channel;
18+
19+
import com.google.appengine.api.channel.ChannelMessage;
20+
import com.google.appengine.api.channel.ChannelService;
21+
import com.google.appengine.api.channel.ChannelServiceFactory;
22+
import com.googlecode.objectify.annotation.Entity;
23+
import com.googlecode.objectify.annotation.Id;
24+
import org.json.JSONObject;
25+
26+
import java.util.HashMap;
27+
import java.util.Map;
28+
import java.util.UUID;
29+
import java.util.regex.Pattern;
30+
31+
@Entity
32+
public class Game {
33+
static final Pattern[] XWins = {
34+
Pattern.compile("XXX......"),
35+
Pattern.compile("...XXX..."),
36+
Pattern.compile("......XXX"),
37+
Pattern.compile("X..X..X.."),
38+
Pattern.compile(".X..X..X."),
39+
Pattern.compile("..X..X..X"),
40+
Pattern.compile("X...X...X"),
41+
Pattern.compile("..X.X.X..")
42+
};
43+
static final Pattern[] OWins = {
44+
Pattern.compile("OOO......"),
45+
Pattern.compile("...OOO..."),
46+
Pattern.compile("......OOO"),
47+
Pattern.compile("O..O..O.."),
48+
Pattern.compile(".O..O..O."),
49+
Pattern.compile("..O..O..O"),
50+
Pattern.compile("O...O...O"),
51+
Pattern.compile("..O.O.O..")
52+
};
53+
54+
@Id
55+
public String id;
56+
private String userX;
57+
private String userO;
58+
private String board;
59+
private Boolean moveX;
60+
private String winner;
61+
private String winningBoard;
62+
63+
Game() {
64+
}
65+
66+
Game(String userX, String userO, String board, boolean moveX) {
67+
this.id = UUID.randomUUID().toString();
68+
this.userX = userX;
69+
this.userO = userO;
70+
this.board = board;
71+
this.moveX = moveX;
72+
}
73+
74+
public String getId() {
75+
return id;
76+
}
77+
78+
public void setId(String id) {
79+
this.id = id;
80+
}
81+
82+
public String getUserX() {
83+
return userX;
84+
}
85+
86+
public String getUserO() {
87+
return userO;
88+
}
89+
90+
public void setUserO(String userO) {
91+
this.userO = userO;
92+
}
93+
94+
public String getBoard() {
95+
return board;
96+
}
97+
98+
public void setBoard(String board) {
99+
this.board = board;
100+
}
101+
102+
public boolean getMoveX() {
103+
return moveX;
104+
}
105+
106+
public void setMoveX(boolean moveX) {
107+
this.moveX = moveX;
108+
}
109+
110+
public String getMessageString() {
111+
Map<String, String> state = new HashMap<String, String>();
112+
state.put("userX", userX);
113+
if (userO == null) {
114+
state.put("userO", "");
115+
} else {
116+
state.put("userO", userO);
117+
}
118+
state.put("board", board);
119+
state.put("moveX", moveX.toString());
120+
state.put("winner", winner);
121+
if (winner != null && winner != "") {
122+
state.put("winningBoard", winningBoard);
123+
}
124+
JSONObject message = new JSONObject(state);
125+
return message.toString();
126+
}
127+
128+
public String getChannelKey(String user) {
129+
return user + id;
130+
}
131+
132+
private void sendUpdateToUser(String user) {
133+
if (user != null) {
134+
ChannelService channelService = ChannelServiceFactory.getChannelService();
135+
String channelKey = getChannelKey(user);
136+
channelService.sendMessage(new ChannelMessage(channelKey, getMessageString()));
137+
}
138+
}
139+
140+
public void sendUpdateToClients() {
141+
sendUpdateToUser(userX);
142+
sendUpdateToUser(userO);
143+
}
144+
145+
public void checkWin() {
146+
final Pattern[] wins;
147+
if (moveX) {
148+
wins = XWins;
149+
} else {
150+
wins = OWins;
151+
}
152+
153+
for (Pattern winPattern : wins) {
154+
if (winPattern.matcher(board).matches()) {
155+
if (moveX) {
156+
winner = userX;
157+
} else {
158+
winner = userO;
159+
}
160+
winningBoard = winPattern.toString();
161+
}
162+
}
163+
}
164+
165+
public boolean makeMove(int position, String user) {
166+
String currentMovePlayer;
167+
char value;
168+
if (getMoveX()) {
169+
value = 'X';
170+
currentMovePlayer = getUserX();
171+
} else {
172+
value = 'O';
173+
currentMovePlayer = getUserO();
174+
}
175+
176+
if (currentMovePlayer.equals(user)) {
177+
char[] boardBytes = getBoard().toCharArray();
178+
boardBytes[position] = value;
179+
setBoard(new String(boardBytes));
180+
checkWin();
181+
setMoveX(!getMoveX());
182+
sendUpdateToClients();
183+
return true;
184+
}
185+
186+
return false;
187+
}
188+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.appengine.channel;
18+
19+
import com.google.appengine.api.channel.ChannelService;
20+
import com.google.appengine.api.channel.ChannelServiceFactory;
21+
import com.google.appengine.api.users.UserService;
22+
import com.google.appengine.api.users.UserServiceFactory;
23+
import com.googlecode.objectify.Objectify;
24+
import com.googlecode.objectify.ObjectifyService;
25+
26+
import javax.servlet.http.HttpServlet;
27+
import javax.servlet.http.HttpServletRequest;
28+
import javax.servlet.http.HttpServletResponse;
29+
import java.io.IOException;
30+
31+
public class GetTokenServlet extends HttpServlet {
32+
@Override
33+
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
34+
UserService userService = UserServiceFactory.getUserService();
35+
String gameId = req.getParameter("gamekey");
36+
Objectify ofy = ObjectifyService.ofy();
37+
Game game = ofy.load().type(Game.class).id(gameId).safe();
38+
39+
String currentUserId = userService.getCurrentUser().getUserId();
40+
if (currentUserId.equals(game.getUserX()) ||
41+
currentUserId.equals(game.getUserO())) {
42+
String channelKey = game.getChannelKey(currentUserId);
43+
ChannelService channelService = ChannelServiceFactory.getChannelService();
44+
resp.setContentType("text/plain");
45+
resp.getWriter().println(channelService.createChannel(channelKey));
46+
return;
47+
}
48+
resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
49+
}
50+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.appengine.channel;
18+
19+
import com.google.appengine.api.users.UserService;
20+
import com.google.appengine.api.users.UserServiceFactory;
21+
import com.googlecode.objectify.Objectify;
22+
import com.googlecode.objectify.ObjectifyService;
23+
24+
import javax.servlet.http.HttpServlet;
25+
import javax.servlet.http.HttpServletRequest;
26+
import javax.servlet.http.HttpServletResponse;
27+
import java.io.IOException;
28+
29+
public class MoveServlet extends HttpServlet {
30+
@Override
31+
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
32+
UserService userService = UserServiceFactory.getUserService();
33+
String gameId = req.getParameter("gamekey");
34+
int piece = new Integer(req.getParameter("i"));
35+
Objectify ofy = ObjectifyService.ofy();
36+
Game game = ofy.load().type(Game.class).id(gameId).safe();
37+
38+
String currentUserId = userService.getCurrentUser().getUserId();
39+
if (!game.makeMove(piece, currentUserId)) {
40+
resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
41+
} else {
42+
ofy.save().entity(game).now();
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)