├── CardsAgaisntHumanity ├── WebRoot │ ├── WEB-INF │ │ ├── classes │ │ │ ├── .gitignore │ │ │ └── cc │ │ │ │ └── cafebabe │ │ │ │ └── cardagainsthumanity │ │ │ │ ├── test │ │ │ │ └── Main.class │ │ │ │ ├── dao │ │ │ │ ├── CardsDAO.class │ │ │ │ ├── PlayerDAO.class │ │ │ │ └── GameDataDAO.class │ │ │ │ ├── server │ │ │ │ └── Server.class │ │ │ │ ├── util │ │ │ │ ├── Json2Map.class │ │ │ │ ├── MessageType.class │ │ │ │ └── HashMapArray.class │ │ │ │ ├── entities │ │ │ │ ├── Player.class │ │ │ │ └── GameData.class │ │ │ │ └── service │ │ │ │ └── PlayerService.class │ │ ├── lib │ │ │ ├── javax.json-1.0.4.jar │ │ │ └── sqlitejdbc-v056.jar │ │ └── web.xml │ ├── META-INF │ │ └── MANIFEST.MF │ └── index.jsp ├── .settings │ ├── org.eclipse.wst.jsdt.ui.superType.name │ ├── org.eclipse.wst.jsdt.ui.superType.container │ ├── org.eclipse.jdt.core.prefs │ ├── org.eclipse.wst.common.project.facet.core.xml │ ├── org.eclipse.wst.common.component │ └── .jsdtscope ├── src │ └── cc │ │ └── cafebabe │ │ └── cardagainsthumanity │ │ ├── consts │ │ ├── RoomState.java │ │ ├── PlayerState.java │ │ └── TaskType.java │ │ ├── dao │ │ ├── SugDAO.java │ │ ├── CardsDAO.java │ │ ├── DAOIniter.java │ │ ├── GameDataDAO.java │ │ ├── PlayerDAO.java │ │ └── BaseDAO.java │ │ ├── game │ │ ├── Room.java │ │ ├── Round.java │ │ ├── GameWorld.java │ │ ├── SpectateArea.java │ │ ├── PlayerContainer.java │ │ ├── Lobby.java │ │ └── Deck.java │ │ ├── test │ │ └── Main.java │ │ ├── entities │ │ ├── Card.java │ │ ├── WhiteCard.java │ │ ├── BlackCard.java │ │ ├── CardPack.java │ │ ├── GameData.java │ │ └── Player.java │ │ ├── util │ │ ├── TaskHandler.java │ │ ├── MessageType.java │ │ ├── Misc.java │ │ ├── HashMapArray.java │ │ ├── Task.java │ │ └── Json2Map.java │ │ ├── service │ │ ├── PlayerService.java │ │ ├── SugService.java │ │ ├── GameDataService.java │ │ └── CardsService.java │ │ └── server │ │ └── Server.java ├── .classpath └── .project ├── readme(必读).txt ├── CAH2Data ├── cards.db ├── sug.db └── players.db ├── CardsAgainstHumanityClient └── CardsAgainstHumanityClient │ ├── wingProperties.json │ ├── web.config │ ├── CardsAgainstHumanityClient.sln │ ├── web.Debug.config │ ├── web.Release.config │ ├── src │ ├── script │ │ ├── lib │ │ │ └── touch.js │ │ ├── hla3n233.4lz │ │ └── zmcawnbi.kzr │ └── css │ │ └── app.css │ ├── CardsAgainstHumanityClient.csproj │ └── index.html ├── .gitattributes └── .gitignore /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/.gitignore: -------------------------------------------------------------------------------- 1 | /cc 2 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/.settings/org.eclipse.wst.jsdt.ui.superType.name: -------------------------------------------------------------------------------- 1 | Window -------------------------------------------------------------------------------- /readme(必读).txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/readme(必读).txt -------------------------------------------------------------------------------- /CAH2Data/cards.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CAH2Data/cards.db -------------------------------------------------------------------------------- /CAH2Data/sug.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CAH2Data/sug.db -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /CAH2Data/players.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CAH2Data/players.db -------------------------------------------------------------------------------- /CardsAgaisntHumanity/.settings/org.eclipse.wst.jsdt.ui.superType.container: -------------------------------------------------------------------------------- 1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/lib/javax.json-1.0.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/lib/javax.json-1.0.4.jar -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/lib/sqlitejdbc-v056.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/lib/sqlitejdbc-v056.jar -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/consts/RoomState.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.consts; 2 | 3 | public enum RoomState { 4 | WAITING, 5 | PLAYING 6 | } 7 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/SugDAO.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/SugDAO.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/Room.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/Room.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/Round.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/Round.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/test/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/test/Main.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/CardsDAO.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/CardsDAO.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/consts/PlayerState.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.consts; 2 | 3 | public enum PlayerState 4 | { 5 | LOBBY, 6 | ROOM, 7 | SPECTATING 8 | } 9 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/consts/TaskType.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.consts; 2 | 3 | public enum TaskType { 4 | MESSAGE, 5 | OPEN, 6 | CLOSE, 7 | TIMER 8 | } 9 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/DAOIniter.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/DAOIniter.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/GameDataDAO.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/GameDataDAO.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/PlayerDAO.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/PlayerDAO.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/entities/Card.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/entities/Card.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/GameWorld.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/GameWorld.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/util/TaskHandler.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/util/TaskHandler.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/service/PlayerService.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/service/PlayerService.java -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/test/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/test/Main.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/dao/CardsDAO.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/dao/CardsDAO.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/dao/PlayerDAO.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/dao/PlayerDAO.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/server/Server.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/server/Server.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/util/Json2Map.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/util/Json2Map.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/dao/GameDataDAO.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/dao/GameDataDAO.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/entities/Player.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/entities/Player.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/util/MessageType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/util/MessageType.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/entities/GameData.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/entities/GameData.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/util/HashMapArray.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/util/HashMapArray.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/service/PlayerService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheatup/cardsagaintshumanity/HEAD/CardsAgaisntHumanity/WebRoot/WEB-INF/classes/cc/cafebabe/cardagainsthumanity/service/PlayerService.class -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/service/SugService.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.service; 2 | 3 | import cc.cafebabe.cardagainsthumanity.dao.SugDAO; 4 | 5 | public class SugService { 6 | public static void AddSug(long pid, String sug){ 7 | SugDAO.AddSug(pid, sug); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/wingProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "close":true, 3 | "resourcePlugin": 4 | { 5 | "configs":[ 6 | { 7 | "configPath":"resource/resource.json", 8 | "relativePath":"resource/" 9 | }], 10 | "id":"org.egret-labs.resource", 11 | "library": 12 | { 13 | 14 | } 15 | }, 16 | "theme":"resource/theme.thm" 17 | } -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/web.config: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.compliance=1.7 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.source=1.7 8 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/util/MessageType.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.util; 2 | 3 | public enum MessageType 4 | { 5 | FLAG, 6 | KV, 7 | TEXT, 8 | ROOMINFO, 9 | GAMEINFO, 10 | SERVERINFO, 11 | LOBBYINFO, 12 | MYINFO, 13 | PLAYERLEAVE, 14 | PLAYERENTER, 15 | INFO, 16 | ADDNEWROOM, 17 | SWITCHPLACE, 18 | CARDSENDED, 19 | PEND, 20 | BLACKCARD, 21 | WHITECARD 22 | } 23 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/entities/WhiteCard.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.entities; 2 | 3 | import java.sql.Date; 4 | 5 | public class WhiteCard extends Card 6 | { 7 | 8 | public WhiteCard(long cid, String text, int packid, 9 | String packname, long pid, String pname, int state, Date subdate) 10 | { 11 | super(cid, text, Card.TYPE_WHITE, packid, packname, pid, pname, state, subdate); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/.settings/org.eclipse.wst.common.component: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/entities/BlackCard.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.entities; 2 | 3 | import java.sql.Date; 4 | 5 | import cc.cafebabe.cardagainsthumanity.util.Misc; 6 | 7 | public class BlackCard extends Card 8 | { 9 | public BlackCard(long cid, String text, int packid, 10 | String packname, long pid, String pname, int state, Date subdate) 11 | { 12 | super(cid, text, Card.TYPE_BLACK, packid, packname, pid, pname, state, subdate); 13 | } 14 | 15 | public static final String BLANK_SUP = "%b"; 16 | public int getBlankCount() 17 | { 18 | return Misc.getSubstringCount(getText(), BLANK_SUP); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/SpectateArea.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.game; 2 | 3 | import cc.cafebabe.cardagainsthumanity.entities.Player; 4 | 5 | 6 | public class SpectateArea extends PlayerContainer{ 7 | private Room room; 8 | public SpectateArea(Room room){ 9 | this.room = room; 10 | } 11 | public Room getRoom() { 12 | return room; 13 | } 14 | public void setRoom(Room room) { 15 | this.room = room; 16 | } 17 | 18 | public void sendPlayerInSpectator(Player player){ 19 | addPlayer(player); 20 | } 21 | 22 | public void removePlayerFromSpectator(Player player){ 23 | removePlayer(player); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | CardsAgaisntHumanity 4 | 5 | index.html 6 | index.htm 7 | index.jsp 8 | default.html 9 | default.htm 10 | default.jsp 11 | 12 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/util/Misc.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.util; 2 | 3 | 4 | public class Misc 5 | { 6 | public static int getSubstringCount(String text, String sub) 7 | { 8 | int o = 0; 9 | int index=-1; 10 | while((index = text.indexOf(sub, index)) > -1){ 11 | index++; 12 | o++; 13 | } 14 | return o; 15 | } 16 | 17 | public static int getStringLen(String text){ 18 | int len = 0; 19 | if (text == null || text.length() == 0) return 0; 20 | len = text.length(); 21 | for (int i = 0; i < text.length(); i++) { 22 | char c = text.charAt(i); 23 | if (c > 255) 24 | len++; 25 | } 26 | return len; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/util/HashMapArray.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | public class HashMapArray 8 | { 9 | private List> maps; 10 | public List> getMaps() 11 | { 12 | return maps; 13 | } 14 | public void setMaps(List> maps) 15 | { 16 | this.maps = maps; 17 | } 18 | 19 | public HashMapArray(){ 20 | maps = new ArrayList>(); 21 | } 22 | 23 | public void addMap(Map map){ 24 | maps.add(map); 25 | } 26 | 27 | public void removeMap(Map map){ 28 | maps.remove(map); 29 | } 30 | 31 | public boolean containsMap(Map map){ 32 | return maps.contains(map); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/service/GameDataService.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.service; 2 | 3 | import cc.cafebabe.cardagainsthumanity.dao.GameDataDAO; 4 | import cc.cafebabe.cardagainsthumanity.entities.GameData; 5 | import cc.cafebabe.cardagainsthumanity.entities.Player; 6 | 7 | public class GameDataService 8 | { 9 | public static GameData getGameData(long pid){ 10 | return GameDataDAO.getGameData(pid); 11 | } 12 | 13 | public static GameData getGameData(Player player){ 14 | if(player == null) return null; 15 | return getGameData(player.getPid()); 16 | } 17 | 18 | public static void saveGameData(GameData gameData){ 19 | if(gameData == null) return; 20 | GameDataDAO.saveGameData(gameData); 21 | } 22 | 23 | public static GameData createGameData(long pid){ 24 | return GameDataDAO.createGameData(pid); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/WebRoot/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> 2 | <% 3 | String path = request.getContextPath(); 4 | String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 | %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | My JSP 'index.jsp' starting page 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | This is my JSP page.
25 | 26 | 27 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/util/Task.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.util; 2 | 3 | import javax.websocket.Session; 4 | 5 | import cc.cafebabe.cardagainsthumanity.consts.TaskType; 6 | 7 | public class Task { 8 | private Session session; 9 | private TaskType taskType; 10 | private String message; 11 | public Session getSession() { 12 | return session; 13 | } 14 | public void setSession(Session session) { 15 | this.session = session; 16 | } 17 | public TaskType getTaskType() { 18 | return taskType; 19 | } 20 | public void setTaskType(TaskType taskType) { 21 | this.taskType = taskType; 22 | } 23 | public String getMessage() { 24 | return message; 25 | } 26 | public void setMessage(String message) { 27 | this.message = message; 28 | } 29 | public Task(Session session, TaskType taskType, String message) { 30 | super(); 31 | this.session = session; 32 | this.taskType = taskType; 33 | this.message = message; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/CardsAgainstHumanityClient.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardsAgainstHumanityClient", "CardsAgainstHumanityClient.csproj", "{BED3B049-D18E-4DBF-A5F2-3FBF9BB6E805}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BED3B049-D18E-4DBF-A5F2-3FBF9BB6E805}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {BED3B049-D18E-4DBF-A5F2-3FBF9BB6E805}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {BED3B049-D18E-4DBF-A5F2-3FBF9BB6E805}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {BED3B049-D18E-4DBF-A5F2-3FBF9BB6E805}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 30 | 31 | -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 31 | 32 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/entities/CardPack.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.entities; 2 | 3 | import java.util.Set; 4 | 5 | public class CardPack 6 | { 7 | private int packid; 8 | private String packname; 9 | private int needLevel; 10 | private Set blackCards; 11 | private Set whiteCards; 12 | 13 | public int getPackid() 14 | { 15 | return packid; 16 | } 17 | public void setPackid(int packid) 18 | { 19 | this.packid = packid; 20 | } 21 | public String getPackname() 22 | { 23 | return packname; 24 | } 25 | public void setPackname(String packname) 26 | { 27 | this.packname = packname; 28 | } 29 | public int getNeedLevel() 30 | { 31 | return needLevel; 32 | } 33 | public void setNeedLevel(int needLevel) 34 | { 35 | this.needLevel = needLevel; 36 | } 37 | 38 | public Set getBlackCards() 39 | { 40 | return blackCards; 41 | } 42 | public void setBlackCards(Set blackCards) 43 | { 44 | this.blackCards = blackCards; 45 | } 46 | public Set getWhiteCards() 47 | { 48 | return whiteCards; 49 | } 50 | public void setWhiteCards(Set whiteCards) 51 | { 52 | this.whiteCards = whiteCards; 53 | } 54 | public CardPack(int packid, String packname, int needLevel) 55 | { 56 | super(); 57 | this.packid = packid; 58 | this.packname = packname; 59 | this.needLevel = needLevel; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | CardsAgaisntHumanity 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.jsdt.core.javascriptValidator 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.common.project.facet.core.builder 20 | 21 | 22 | 23 | 24 | org.eclipse.wst.validation.validationbuilder 25 | 26 | 27 | 28 | 29 | com.genuitec.eclipse.j2eedt.core.DeploymentDescriptorValidator 30 | 31 | 32 | 33 | 34 | com.genuitec.eclipse.ast.deploy.core.DeploymentBuilder 35 | 36 | 37 | 38 | 39 | 40 | org.eclipse.jem.workbench.JavaEMFNature 41 | org.eclipse.wst.common.modulecore.ModuleCoreNature 42 | org.eclipse.wst.common.project.facet.core.nature 43 | org.eclipse.jdt.core.javanature 44 | org.eclipse.wst.jsdt.core.jsNature 45 | 46 | 47 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/server/Server.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.server; 2 | 3 | import javax.websocket.OnClose; 4 | import javax.websocket.OnError; 5 | import javax.websocket.OnMessage; 6 | import javax.websocket.OnOpen; 7 | import javax.websocket.Session; 8 | import javax.websocket.server.ServerEndpoint; 9 | 10 | import cc.cafebabe.cardagainsthumanity.consts.TaskType; 11 | import cc.cafebabe.cardagainsthumanity.dao.DAOIniter; 12 | import cc.cafebabe.cardagainsthumanity.game.GameWorld; 13 | import cc.cafebabe.cardagainsthumanity.util.Task; 14 | import cc.cafebabe.cardagainsthumanity.util.TaskHandler; 15 | 16 | @ServerEndpoint("/server") 17 | public class Server 18 | { 19 | public static TaskHandler handler; 20 | private static Thread handlerThread; 21 | public static GameWorld gameWorld; 22 | public static String version = "5"; 23 | static 24 | { 25 | gameWorld = new GameWorld(); 26 | DAOIniter.init(); 27 | handler = new TaskHandler(); 28 | handlerThread = new Thread(handler); 29 | handlerThread.start(); 30 | } 31 | 32 | @OnOpen 33 | public void onOpen(Session session) 34 | { 35 | handler.addTask(new Task(session, TaskType.OPEN, null)); 36 | } 37 | 38 | @OnError 39 | public void onError(Throwable e) 40 | { 41 | e.printStackTrace(); 42 | } 43 | 44 | @OnClose 45 | public void onClose(Session session) 46 | { 47 | handler.addTask(new Task(session, TaskType.CLOSE, null)); 48 | } 49 | 50 | @OnMessage 51 | public void onMessage(String message, Session session) 52 | { 53 | handler.addTask(new Task(session, TaskType.MESSAGE, message)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/entities/GameData.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.entities; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class GameData 7 | { 8 | public GameData(long pid, int credit, int fish, int exp) 9 | { 10 | super(); 11 | this.pid = pid; 12 | this.credit = credit; 13 | this.fish = fish; 14 | this.exp = exp; 15 | this.datas = new HashMap(); 16 | } 17 | private long pid; 18 | private int credit; 19 | private int fish; 20 | private int exp; 21 | private int combo; 22 | public int getCombo() 23 | { 24 | return combo; 25 | } 26 | public void setCombo(int combo) 27 | { 28 | this.combo = combo; 29 | } 30 | private Map datas; 31 | @SuppressWarnings("unchecked") 32 | public T getExtData(String key){ 33 | 34 | T item = null; 35 | try{ 36 | item = (T) datas.get(key); 37 | }catch(Exception e){ 38 | e.printStackTrace(); 39 | } 40 | return item; 41 | } 42 | public Map getDataMap(){ 43 | return datas; 44 | } 45 | public void setExtData(String key, Object value){ 46 | datas.put(key, value); 47 | } 48 | public void removeExtData(String key){ 49 | datas.remove(key); 50 | } 51 | public long getPid() 52 | { 53 | return pid; 54 | } 55 | public void setPid(long pid) 56 | { 57 | this.pid = pid; 58 | } 59 | public int getCredit() 60 | { 61 | return credit; 62 | } 63 | public void setCredit(int credit) 64 | { 65 | this.credit = credit; 66 | } 67 | public int getFish() 68 | { 69 | return fish; 70 | } 71 | public void setFish(int fish) 72 | { 73 | this.fish = fish; 74 | } 75 | public Map getData() 76 | { 77 | return datas; 78 | } 79 | public void setData(Map data) 80 | { 81 | this.datas = data; 82 | } 83 | public int getExp() { 84 | return exp; 85 | } 86 | public void setExp(int exp) { 87 | this.exp = exp; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/dao/BaseDAO.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.dao; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | 7 | public class BaseDAO { 8 | public static Connection playersDB; 9 | public static Connection cardsDB; 10 | public static Connection sugDB; 11 | public static boolean resetMode = false; 12 | public static void init(){ 13 | try { 14 | Class.forName("org.sqlite.JDBC"); 15 | playersDB = DriverManager.getConnection("jdbc:sqlite://c:/CAH2Data/players.db"); 16 | cardsDB = DriverManager.getConnection("jdbc:sqlite://c:/CAH2Data/cards.db"); 17 | sugDB = DriverManager.getConnection("jdbc:sqlite://c:/CAH2Data/sug.db"); 18 | BaseDAO.playersDB.setAutoCommit(false); 19 | BaseDAO.cardsDB.setAutoCommit(false); 20 | BaseDAO.sugDB.setAutoCommit(false); 21 | } catch (SQLException e) { 22 | e.printStackTrace(); 23 | } catch (ClassNotFoundException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | 28 | public static void close(){ 29 | synchronized (playersDB) { 30 | if(playersDB != null){ 31 | try { 32 | playersDB.close(); 33 | } catch (SQLException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | } 38 | 39 | synchronized (cardsDB) { 40 | if(cardsDB != null){ 41 | try { 42 | cardsDB.close(); 43 | } catch (SQLException e) { 44 | e.printStackTrace(); 45 | } 46 | } 47 | } 48 | 49 | synchronized (sugDB) { 50 | if(sugDB != null){ 51 | try { 52 | sugDB.close(); 53 | } catch (SQLException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | } 58 | } 59 | 60 | public static void commit(){ 61 | synchronized (playersDB) { 62 | if(playersDB != null){ 63 | try { 64 | playersDB.commit(); 65 | } catch (SQLException e) { 66 | e.printStackTrace(); 67 | } 68 | } 69 | } 70 | 71 | synchronized (cardsDB) { 72 | if(cardsDB != null){ 73 | try { 74 | cardsDB.commit(); 75 | } catch (SQLException e) { 76 | e.printStackTrace(); 77 | } 78 | } 79 | } 80 | 81 | synchronized (sugDB) { 82 | if(sugDB != null){ 83 | try { 84 | sugDB.commit(); 85 | } catch (SQLException e) { 86 | e.printStackTrace(); 87 | } 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/PlayerContainer.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.game; 2 | 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import javax.websocket.Session; 8 | 9 | import cc.cafebabe.cardagainsthumanity.entities.Player; 10 | import cc.cafebabe.cardagainsthumanity.util.HashMapArray; 11 | import cc.cafebabe.cardagainsthumanity.util.Json2Map; 12 | 13 | public abstract class PlayerContainer { 14 | protected Map players; 15 | public PlayerContainer(){ 16 | players = Collections.synchronizedMap(new HashMap()); 17 | } 18 | 19 | public Map getPlayers(){ 20 | return players; 21 | } 22 | 23 | public void broadcastMessage(Map message){ 24 | broadcastMessage(Json2Map.toJSONString(message)); 25 | } 26 | 27 | public void broadcastMessageExceptSomeone(Map message, Player player){ 28 | broadcastMessageExceptSomeone(Json2Map.toJSONString(message), player); 29 | } 30 | 31 | public void broadcastMessage(String message){ 32 | for(Player p : players.values()){ 33 | p.sendMessage(message); 34 | } 35 | } 36 | 37 | public void broadcastMessageExceptSomeone(String message, Player player){ 38 | for(Player p : players.values()){ 39 | if(p != player) 40 | p.sendMessage(message); 41 | } 42 | } 43 | 44 | public Player getPlayer(Session session){ 45 | return players.get(session); 46 | } 47 | 48 | public Player getPlayer(long pid){ 49 | Player player = null; 50 | for(Player p : players.values()){ 51 | if(p.getPid() == pid){ 52 | player = p; 53 | } 54 | } 55 | return player; 56 | } 57 | 58 | public Player getPlayer(String name){ 59 | Player player = null; 60 | for(Player p : players.values()){ 61 | if(p.getName().equals(name)){ 62 | player = p; 63 | } 64 | } 65 | return player; 66 | } 67 | 68 | protected void addPlayer(Player player){ 69 | players.put(player.getSession(), player); 70 | player.setContainer(this); 71 | } 72 | 73 | protected void removePlayer(Player player){ 74 | players.remove(player.getSession()); 75 | } 76 | 77 | public HashMapArray buildPlayersInfo(){ 78 | HashMapArray arr = new HashMapArray(); 79 | for(Player p : players.values()){ 80 | arr.addMap(p.buildPlayerInfo()); 81 | } 82 | return arr; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/Lobby.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.game; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import cc.cafebabe.cardagainsthumanity.entities.Player; 7 | import cc.cafebabe.cardagainsthumanity.server.Server; 8 | import cc.cafebabe.cardagainsthumanity.util.HashMapArray; 9 | import cc.cafebabe.cardagainsthumanity.util.Json2Map; 10 | 11 | public class Lobby extends PlayerContainer{ 12 | public static final int MAX_ROOM_COUNT = 20; 13 | public boolean dirtyRoom = true; 14 | 15 | private Map rooms; 16 | public Lobby(){ 17 | rooms = new HashMap(); 18 | } 19 | public Map getRooms() { 20 | return rooms; 21 | } 22 | 23 | public int createRoom(){ 24 | for(int i = 1; i <= MAX_ROOM_COUNT; i++){ 25 | if(!rooms.containsKey(i)){ 26 | Room r = new Room(i); 27 | rooms.put(i, r); 28 | Server.gameWorld.getLobby().broadcastMessage(Json2Map.buildAddNewRoomInfo(r)); 29 | return i; 30 | } 31 | } 32 | return -1; 33 | } 34 | 35 | public int createRoom(String name, String password, int[] cardpacks){ 36 | for(int i = 1; i <= MAX_ROOM_COUNT; i++){ 37 | if(!rooms.containsKey(i)){ 38 | Room r = new Room(i, name, password, cardpacks); 39 | rooms.put(i, r); 40 | Server.gameWorld.getLobby().broadcastMessage(Json2Map.buildAddNewRoomInfo(r)); 41 | return i; 42 | } 43 | } 44 | return -1; 45 | } 46 | 47 | public Room getRoom(int id){ 48 | return rooms.get(id); 49 | } 50 | 51 | public void sendPlayerInLobby(Player player){ 52 | addPlayer(player); 53 | player.setContainer(this); 54 | player.setRoomNumber(0); 55 | player.sendMessage(Json2Map.buildLobbyInfo(this)); 56 | broadcastMessage(Json2Map.buildPlayerEnterInfo(player)); 57 | } 58 | 59 | public void removePlayerFromLobby(Player player){ 60 | removePlayer(player); 61 | broadcastMessage(Json2Map.buildPlayerLeaveInfo(player.getPid())); 62 | } 63 | 64 | public void destroyRoom(int id){ 65 | rooms.remove(id); 66 | broadcastMessage(Json2Map.BuildKVMessage("destroyroom", id)); 67 | } 68 | 69 | 70 | public HashMapArray buildRoomsInfo(){ 71 | HashMapArray arr = new HashMapArray(); 72 | for(int i = 1; i <= MAX_ROOM_COUNT; i++){ 73 | Room room = rooms.get(i); 74 | if(room != null) 75 | arr.addMap(room.buildRoomShortInfo()); 76 | } 77 | return arr; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/game/Deck.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.game; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | import cc.cafebabe.cardagainsthumanity.entities.BlackCard; 10 | import cc.cafebabe.cardagainsthumanity.entities.WhiteCard; 11 | import cc.cafebabe.cardagainsthumanity.service.CardsService; 12 | 13 | public class Deck 14 | { 15 | private List blackCards; 16 | private List whiteCards; 17 | 18 | private Set blackCardsPlayed; 19 | private Set whiteCardsPlayed; 20 | public Deck(int[] packids){ 21 | Set tempBlackCards = CardsService.getBlackCardsByPacks(packids); 22 | Set tempWhiteCards = CardsService.getWhiteCardsByPacks(packids); 23 | 24 | blackCards = new ArrayList(); 25 | whiteCards = new ArrayList(); 26 | 27 | blackCards.addAll(tempBlackCards); 28 | whiteCards.addAll(tempWhiteCards); 29 | 30 | Collections.shuffle(blackCards); 31 | Collections.shuffle(whiteCards); 32 | 33 | blackCardsPlayed = new HashSet(); 34 | whiteCardsPlayed = new HashSet(); 35 | } 36 | 37 | public BlackCard getBlackCard(){ 38 | if(blackCards.isEmpty()){ 39 | refillBlackCard(); 40 | } 41 | BlackCard card = null; 42 | for(BlackCard c: blackCards){ 43 | card = c; 44 | break; 45 | } 46 | 47 | blackCards.remove(card); 48 | blackCardsPlayed.add(card); 49 | 50 | return card; 51 | } 52 | 53 | public void refillBlackCard(){ 54 | blackCards.addAll(blackCardsPlayed); 55 | blackCardsPlayed.clear(); 56 | Collections.shuffle(blackCards); 57 | } 58 | 59 | 60 | public WhiteCard getWhiteCard(){ 61 | if(whiteCards.isEmpty()){ 62 | refillWhiteCard(); 63 | } 64 | WhiteCard card = null; 65 | for(WhiteCard c: whiteCards){ 66 | card = c; 67 | break; 68 | } 69 | 70 | whiteCards.remove(card); 71 | whiteCardsPlayed.add(card); 72 | 73 | return card; 74 | } 75 | 76 | public void refillWhiteCard(){ 77 | whiteCards.addAll(whiteCardsPlayed); 78 | whiteCardsPlayed.clear(); 79 | Collections.shuffle(whiteCards); 80 | } 81 | 82 | public WhiteCard getWhiteCardById(long id){ 83 | WhiteCard wc = null; 84 | for(WhiteCard c : whiteCardsPlayed){ 85 | if(c.getCid() == id){ 86 | wc = c; 87 | break; 88 | } 89 | } 90 | if(wc == null){ 91 | for(WhiteCard c : whiteCards){ 92 | if(c.getCid() == id){ 93 | wc = c; 94 | break; 95 | } 96 | } 97 | } 98 | 99 | return wc; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | 18 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 19 | !packages/*/build/ 20 | 21 | # MSTest test Results 22 | [Tt]est[Rr]esult*/ 23 | [Bb]uild[Ll]og.* 24 | 25 | *_i.c 26 | *_p.c 27 | *.ilk 28 | *.meta 29 | *.obj 30 | *.pch 31 | *.pdb 32 | *.pgc 33 | *.pgd 34 | *.rsp 35 | *.sbr 36 | *.tlb 37 | *.tli 38 | *.tlh 39 | *.tmp 40 | *.tmp_proj 41 | *.log 42 | *.vspscc 43 | *.vssscc 44 | .builds 45 | *.pidb 46 | *.log 47 | *.scc 48 | 49 | # Visual C++ cache files 50 | ipch/ 51 | *.aps 52 | *.ncb 53 | *.opensdf 54 | *.sdf 55 | *.cachefile 56 | 57 | # Visual Studio profiler 58 | *.psess 59 | *.vsp 60 | *.vspx 61 | 62 | # Guidance Automation Toolkit 63 | *.gpState 64 | 65 | # ReSharper is a .NET coding add-in 66 | _ReSharper*/ 67 | *.[Rr]e[Ss]harper 68 | 69 | # TeamCity is a build add-in 70 | _TeamCity* 71 | 72 | # DotCover is a Code Coverage Tool 73 | *.dotCover 74 | 75 | # NCrunch 76 | *.ncrunch* 77 | .*crunch*.local.xml 78 | 79 | # Installshield output folder 80 | [Ee]xpress/ 81 | 82 | # DocProject is a documentation generator add-in 83 | DocProject/buildhelp/ 84 | DocProject/Help/*.HxT 85 | DocProject/Help/*.HxC 86 | DocProject/Help/*.hhc 87 | DocProject/Help/*.hhk 88 | DocProject/Help/*.hhp 89 | DocProject/Help/Html2 90 | DocProject/Help/html 91 | 92 | # Click-Once directory 93 | publish/ 94 | 95 | # Publish Web Output 96 | *.Publish.xml 97 | 98 | # NuGet Packages Directory 99 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 100 | #packages/ 101 | 102 | # Windows Azure Build Output 103 | csx 104 | *.build.csdef 105 | 106 | # Windows Store app package directory 107 | AppPackages/ 108 | 109 | # Others 110 | sql/ 111 | *.Cache 112 | ClientBin/ 113 | [Ss]tyle[Cc]op.* 114 | ~$* 115 | *~ 116 | *.dbmdl 117 | *.[Pp]ublish.xml 118 | *.pfx 119 | *.publishsettings 120 | 121 | # RIA/Silverlight projects 122 | Generated_Code/ 123 | 124 | # Backup & report files from converting an old project file to a newer 125 | # Visual Studio version. Backup files are not needed, because we have git ;-) 126 | _UpgradeReport_Files/ 127 | Backup*/ 128 | UpgradeLog*.XML 129 | UpgradeLog*.htm 130 | 131 | # SQL Server files 132 | App_Data/*.mdf 133 | App_Data/*.ldf 134 | 135 | 136 | #LightSwitch generated files 137 | GeneratedArtifacts/ 138 | _Pvt_Extensions/ 139 | ModelManifest.xml 140 | 141 | # ========================= 142 | # Windows detritus 143 | # ========================= 144 | 145 | # Windows image file caches 146 | Thumbs.db 147 | ehthumbs.db 148 | 149 | # Folder config file 150 | Desktop.ini 151 | 152 | # Recycle Bin used on file shares 153 | $RECYCLE.BIN/ 154 | 155 | # Mac desktop service store files 156 | .DS_Store 157 | -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/src/script/lib/touch.js: -------------------------------------------------------------------------------- 1 | !function ($) { 2 | window.indream = window.indream || {}; 3 | $.indream = indream; 4 | //Define events 5 | indream.touch = { 6 | evenList: { 7 | touchStart: { 8 | htmlEvent: 'touchstart' 9 | }, 10 | touchMove: { 11 | htmlEvent: 'touchmove' 12 | }, 13 | touchEnd: { 14 | htmlEvent: 'touchend' 15 | }, 16 | tapOrClick: { 17 | eventFunction: function (action) { 18 | $(this).each(function () { 19 | (function (hasTouched) { 20 | $(this).touchEnd(function (e) { 21 | hasTouched = true; 22 | action.call(this, e); 23 | }); 24 | $(this).click(function (e) { 25 | if (!hasTouched) { 26 | action.call(this, e); 27 | } 28 | }); 29 | }).call(this, false); 30 | }); 31 | return this; 32 | } 33 | }, 34 | moveOrScroll: { 35 | eventFunction: function (action) { 36 | $(this).each(function () { 37 | (function (hasTouched) { 38 | $(this).touchMove(function (e) { 39 | hasTouched = true; 40 | action.call(this, e); 41 | }); 42 | $(this).scroll(function (e) { 43 | if (!hasTouched) { 44 | action.call(this, e); 45 | } 46 | }); 47 | }).call(this, false); 48 | }); 49 | return this; 50 | } 51 | } 52 | } 53 | } 54 | 55 | //Add events into jquery 56 | for (var eventName in indream.touch.evenList) { 57 | var event = indream.touch.evenList[eventName]; 58 | $.fn[eventName] = event.eventFunction || (function (eventName, htmlEvent) { 59 | return function (action) { 60 | $(this).each(function () { 61 | $(this).bind(htmlEvent, action); 62 | //Add event listener method for IE or others 63 | if (this.attachEvent) { 64 | this.attachEvent('on' + htmlEvent, function (e) { 65 | $(this).on(eventName); 66 | }); 67 | } else { 68 | this.addEventListener(htmlEvent, function (e) { 69 | $(this).on(eventName); 70 | }); 71 | } 72 | }); 73 | return this; 74 | } 75 | })(eventName, event.htmlEvent); 76 | } 77 | }(window.jQuery); -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/CardsAgainstHumanityClient.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | {BED3B049-D18E-4DBF-A5F2-3FBF9BB6E805} 7 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 8 | Library 9 | bin 10 | v4.5 11 | full 12 | true 13 | 1.5 14 | true 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | web.config 33 | 34 | 35 | web.config 36 | 37 | 38 | 39 | 12.0 40 | 41 | 42 | CardsAgainstHumanityClient 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | True 51 | True 52 | 3836 53 | / 54 | http://localhost:3836/ 55 | False 56 | False 57 | 58 | 59 | False 60 | 61 | 62 | 63 | 64 | 65 | false 66 | true 67 | 68 | 69 | true 70 | false 71 | 72 | 73 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/entities/Player.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.entities; 2 | 3 | import java.io.IOException; 4 | import java.sql.Date; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import javax.websocket.Session; 9 | 10 | import cc.cafebabe.cardagainsthumanity.game.PlayerContainer; 11 | import cc.cafebabe.cardagainsthumanity.server.Server; 12 | import cc.cafebabe.cardagainsthumanity.service.GameDataService; 13 | import cc.cafebabe.cardagainsthumanity.service.PlayerService; 14 | import cc.cafebabe.cardagainsthumanity.util.Json2Map; 15 | 16 | public class Player 17 | { 18 | private long pid; 19 | private String name; 20 | private String password; 21 | private Date regtime; 22 | private int state; 23 | private GameData gameData; 24 | private Session session; 25 | private PlayerContainer container; 26 | public int afk; 27 | public PlayerContainer getContainer() 28 | { 29 | return container; 30 | } 31 | public void setContainer(PlayerContainer container) 32 | { 33 | this.container = container; 34 | } 35 | 36 | private boolean isFirstLogin = false; 37 | private int roomNumber = -1; 38 | private long lastMessageTime = 0; 39 | public long getLastMessageTime() 40 | { 41 | return lastMessageTime; 42 | } 43 | 44 | public void setLastMessageTime(long lastMessageTime) 45 | { 46 | this.lastMessageTime = lastMessageTime; 47 | } 48 | 49 | public boolean isFirstLogin() 50 | { 51 | return isFirstLogin; 52 | } 53 | 54 | public void setFirstLogin(boolean isFirstLogin) 55 | { 56 | this.isFirstLogin = isFirstLogin; 57 | } 58 | 59 | public int getRoomNumber() 60 | { 61 | return roomNumber; 62 | } 63 | 64 | public void setRoomNumber(int roomNumber) 65 | { 66 | this.roomNumber = roomNumber; 67 | } 68 | 69 | public Player(long uid, String name, String password, Date regDate, int state, GameData gameData) 70 | { 71 | this.pid = uid; 72 | this.name = name; 73 | this.password = password; 74 | this.regtime = regDate; 75 | this.state = state; 76 | this.gameData = gameData; 77 | } 78 | 79 | public Session getSession() { 80 | return session; 81 | } 82 | 83 | public void setSession(Session session) { 84 | this.session = session; 85 | } 86 | 87 | public GameData getGameData() 88 | { 89 | return gameData; 90 | } 91 | public void setGameData(GameData gameData) 92 | { 93 | this.gameData = gameData; 94 | } 95 | public long getPid() 96 | { 97 | return pid; 98 | } 99 | public void setPid(long uid) 100 | { 101 | this.pid = uid; 102 | } 103 | public String getName() 104 | { 105 | return name; 106 | } 107 | public void setName(String name) 108 | { 109 | this.name = name; 110 | } 111 | public String getPassword() 112 | { 113 | return password; 114 | } 115 | public void setPassword(String password) 116 | { 117 | this.password = password; 118 | } 119 | public Date getRegtime() 120 | { 121 | return regtime; 122 | } 123 | public void setRegtime(Date regtime) 124 | { 125 | this.regtime = regtime; 126 | } 127 | public int getState() 128 | { 129 | return state; 130 | } 131 | public void setState(int state) 132 | { 133 | this.state = state; 134 | } 135 | 136 | public void sendMessage(Map map){ 137 | if(session != null && session.isOpen()){ 138 | try { 139 | session.getBasicRemote().sendText(Json2Map.toJSONString(map)); 140 | } catch (IOException e) { 141 | e.printStackTrace(); 142 | } 143 | } 144 | } 145 | 146 | public void sendMessage(String message){ 147 | //System.out.println("> " + message); 148 | if(session != null && session.isOpen()){ 149 | try { 150 | session.getBasicRemote().sendText(message); 151 | } catch (IOException e) { 152 | e.printStackTrace(); 153 | } 154 | } 155 | } 156 | 157 | public void saveGameData(){ 158 | GameDataService.saveGameData(this.gameData); 159 | } 160 | public void savePlayerData(){ 161 | PlayerService.savePlayer(this); 162 | } 163 | 164 | public Map buildPlayerInfo(){ 165 | Map map = new HashMap(); 166 | map.put("pid", this.getPid()); 167 | map.put("name", this.getName()); 168 | map.put("exp", this.getGameData().getExp()); 169 | map.put("credit", this.getGameData().getCredit()); 170 | map.put("fish", this.getGameData().getFish()); 171 | map.put("state", this.getState()); 172 | return map; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/service/CardsService.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.service; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import cc.cafebabe.cardagainsthumanity.dao.CardsDAO; 9 | import cc.cafebabe.cardagainsthumanity.entities.BlackCard; 10 | import cc.cafebabe.cardagainsthumanity.entities.Card; 11 | import cc.cafebabe.cardagainsthumanity.entities.CardPack; 12 | import cc.cafebabe.cardagainsthumanity.entities.WhiteCard; 13 | import cc.cafebabe.cardagainsthumanity.server.Server; 14 | import cc.cafebabe.cardagainsthumanity.util.HashMapArray; 15 | import cc.cafebabe.cardagainsthumanity.util.Json2Map; 16 | import cc.cafebabe.cardagainsthumanity.util.Misc; 17 | 18 | public class CardsService 19 | { 20 | public static Map cardpacks; 21 | 22 | public static void loadAllCards(){ 23 | cardpacks = CardsDAO.getCardsPacks(); 24 | Server.gameWorld.broadcastMessage(Json2Map.buildCardPacksInfo()); 25 | } 26 | 27 | public static Set getWhiteCardsByPacks(int[] packids){ 28 | Set cards = new HashSet(); 29 | for(int i : packids){ 30 | Set tempSet = cardpacks.get(i).getWhiteCards(); 31 | if(tempSet != null) 32 | cards.addAll(tempSet); 33 | } 34 | return cards; 35 | } 36 | 37 | public static Set getBlackCardsByPacks(int[] packids){ 38 | Set cards = new HashSet(); 39 | for(int i : packids){ 40 | Set tempSet = cardpacks.get(i).getBlackCards(); 41 | if(tempSet != null) 42 | cards.addAll(tempSet); 43 | } 44 | return cards; 45 | } 46 | 47 | public static Set getWhiteCardsByPacks(String[] packids){ 48 | Set cards = new HashSet(); 49 | for(String name : packids){ 50 | int packid = CardsDAO.getCardPackId(name); 51 | if(packid != -1){ 52 | Set tempSet = cardpacks.get(packid).getWhiteCards(); 53 | if(tempSet != null) 54 | cards.addAll(tempSet); 55 | } 56 | } 57 | return cards; 58 | } 59 | 60 | public static Set getBlackCardsByPacks(String[] packids){ 61 | Set cards = new HashSet(); 62 | for(String name : packids){ 63 | int packid = CardsDAO.getCardPackId(name); 64 | if(packid != -1){ 65 | Set tempSet = cardpacks.get(packid).getBlackCards(); 66 | if(tempSet != null) 67 | cards.addAll(tempSet); 68 | } 69 | } 70 | return cards; 71 | } 72 | 73 | public static boolean addWhiteCard(long pid, String text, String cardpack){ 74 | int packid = CardsDAO.getCardPackId(cardpack); 75 | if(packid == -1){ 76 | return false; 77 | } 78 | if(packid != -1) 79 | return addWhiteCard(pid, text, packid); 80 | return false; 81 | } 82 | 83 | public static boolean addWhiteCard(long pid, String text, int cardpack){ 84 | if(text == null || text.length() > 200 || text.length() == 0){ 85 | return false; 86 | } 87 | 88 | if(CardsDAO.isCardExist(text)){ 89 | return false; 90 | } 91 | CardsDAO.createCard(Card.TYPE_WHITE, cardpack, pid, text, Card.STATE_PENDING); 92 | 93 | return true; 94 | } 95 | 96 | public static boolean addBlackCard(long pid, String text, String cardpack){ 97 | int packid = CardsDAO.getCardPackId(cardpack); 98 | if(packid != -1) 99 | return addBlackCard(pid, text, packid); 100 | return false; 101 | } 102 | 103 | public static boolean addBlackCard(long pid, String text, int cardpack){ 104 | if(text == null || text.length() > 200 || text.length() == 0){ 105 | return false; 106 | } 107 | int blanks = Misc.getSubstringCount(text, BlackCard.BLANK_SUP); 108 | if(blanks < 1 || blanks > 3){ 109 | return false; 110 | } 111 | if(CardsDAO.isCardExist(text)){ 112 | return false; 113 | } 114 | CardsDAO.createCard(Card.TYPE_BLACK, cardpack, pid, text, Card.STATE_PENDING); 115 | return true; 116 | } 117 | 118 | public static void addCardPack(String packname, int level){ 119 | CardsDAO.createCardPack(packname, level); 120 | } 121 | 122 | public static void delCardPack(String packname){ 123 | CardsDAO.deleteCardPack(packname); 124 | } 125 | 126 | public static void approveAllCards(){ 127 | CardsDAO.approveAllCards(); 128 | } 129 | 130 | public static void approveCards(int[] cids){ 131 | for(int i: cids){ 132 | CardsDAO.setCardState(i, Card.STATE_APPROVED); 133 | } 134 | } 135 | 136 | public static void rejectCards(int[] cids){ 137 | for(int i: cids){ 138 | CardsDAO.deleteCard(i); 139 | } 140 | } 141 | 142 | public static HashMapArray buildCardPacksInfo(){ 143 | HashMapArray hma = new HashMapArray(); 144 | for(int i : cardpacks.keySet()){ 145 | Map map = new HashMap(); 146 | map.put("id", cardpacks.get(i).getPackid()); 147 | map.put("name", cardpacks.get(i).getPackname()); 148 | map.put("lv", cardpacks.get(i).getNeedLevel()); 149 | map.put("bc", cardpacks.get(i).getBlackCards().size()); 150 | map.put("wc", cardpacks.get(i).getWhiteCards().size()); 151 | hma.addMap(map); 152 | } 153 | 154 | return hma; 155 | } 156 | 157 | public static Set getAllPendingCards(){ 158 | return CardsDAO.getPendingCards(); 159 | } 160 | 161 | public static HashMapArray buildAllPendingCardsInfo(){ 162 | HashMapArray hma = new HashMapArray(); 163 | Set cards = getAllPendingCards(); 164 | if(cards != null) 165 | for(Card c : cards){ 166 | Map map = new HashMap(); 167 | map.put("id", c.getCid()); 168 | map.put("pl", c.getPname()); 169 | map.put("pa", c.getPackname()); 170 | map.put("ty", c.getTypeid()); 171 | map.put("cp", c.getPackid()); 172 | map.put("te", c.getText()); 173 | hma.addMap(map); 174 | } 175 | return hma; 176 | } 177 | 178 | public static void pickCard(long cid){ 179 | CardsDAO.pickCard(cid); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /CardsAgaisntHumanity/src/cc/cafebabe/cardagainsthumanity/util/Json2Map.java: -------------------------------------------------------------------------------- 1 | package cc.cafebabe.cardagainsthumanity.util; 2 | 3 | import java.io.StringReader; 4 | import java.io.StringWriter; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Set; 8 | 9 | import javax.json.Json; 10 | import javax.json.JsonArrayBuilder; 11 | import javax.json.JsonNumber; 12 | import javax.json.JsonObject; 13 | import javax.json.JsonObjectBuilder; 14 | import javax.json.JsonReader; 15 | import javax.json.JsonString; 16 | import javax.json.JsonValue; 17 | import javax.json.JsonValue.ValueType; 18 | import javax.json.JsonWriter; 19 | 20 | import cc.cafebabe.cardagainsthumanity.entities.BlackCard; 21 | import cc.cafebabe.cardagainsthumanity.entities.Player; 22 | import cc.cafebabe.cardagainsthumanity.entities.WhiteCard; 23 | import cc.cafebabe.cardagainsthumanity.game.GameWorld; 24 | import cc.cafebabe.cardagainsthumanity.game.Lobby; 25 | import cc.cafebabe.cardagainsthumanity.game.Room; 26 | import cc.cafebabe.cardagainsthumanity.server.Server; 27 | import cc.cafebabe.cardagainsthumanity.service.CardsService; 28 | 29 | public class Json2Map 30 | { 31 | public static String toJSONString(Map map) 32 | { 33 | if(map == null){ 34 | return ""; 35 | } 36 | 37 | JsonObjectBuilder job = Json.createObjectBuilder(); 38 | for(String key : map.keySet()) 39 | { 40 | if(map.get(key) instanceof HashMapArray){ 41 | JsonArrayBuilder jab = Json.createArrayBuilder(); 42 | JsonObjectBuilder job2 = Json.createObjectBuilder(); 43 | HashMapArray hma = (HashMapArray) map.get(key); 44 | int len = hma.getMaps().size(); 45 | for(int i = 0; i < len; i++){ 46 | Map m = hma.getMaps().get(i); 47 | for(String k : m.keySet()){ 48 | job2.add(k, m.get(k) == null ? "null" : m.get(k).toString()); 49 | } 50 | jab.add(job2.build()); 51 | } 52 | job.add(key, jab.build()); 53 | }else{ 54 | job.add(key, map.get(key) == null ? "null" : map.get(key).toString()); 55 | } 56 | } 57 | JsonObject jo = job.build(); 58 | StringWriter sw = new StringWriter(); 59 | try(JsonWriter jw = Json.createWriter(sw)) 60 | { 61 | jw.writeObject(jo); 62 | } 63 | return sw.toString(); 64 | } 65 | 66 | public static Map readFromJson(String JsonString) 67 | { 68 | Map map = new HashMap(); 69 | try 70 | { 71 | JsonReader reader = Json.createReader(new StringReader(JsonString)); 72 | JsonObject jo = reader.readObject(); 73 | for(String s : jo.keySet()) 74 | { 75 | JsonValue value = jo.get(s); 76 | if(value.getValueType() == ValueType.NULL) 77 | { 78 | map.put(s, null); 79 | } 80 | else if(value.getValueType() == ValueType.TRUE) 81 | { 82 | map.put(s, true); 83 | } 84 | else if(value.getValueType() == ValueType.FALSE) 85 | { 86 | map.put(s, false); 87 | } 88 | else if(value.getValueType() == ValueType.NUMBER) 89 | { 90 | if(((JsonNumber)value).isIntegral()) 91 | map.put(s, ((JsonNumber)value).intValue()); 92 | else 93 | map.put(s, ((JsonNumber)value).doubleValue()); 94 | } 95 | else if(value.getValueType() == ValueType.STRING) 96 | { 97 | map.put(s, ((JsonString)value).getString()); 98 | } 99 | else if(value.getValueType() == ValueType.ARRAY || value.getValueType() == ValueType.OBJECT) 100 | { 101 | map.put(s, readFromJson(value.toString())); 102 | } 103 | else 104 | { 105 | map.put(s, value.toString()); 106 | } 107 | } 108 | } 109 | catch(Exception e) 110 | { 111 | 112 | } 113 | return map; 114 | } 115 | 116 | public static Map BuildFlagMessage(String k) 117 | { 118 | Map map = BuildMapByType(MessageType.FLAG); 119 | map.put("k", k); 120 | return map; 121 | } 122 | 123 | public static Map BuildKVMessage(String k, Object v) 124 | { 125 | Map map = BuildMapByType(MessageType.KV); 126 | map.put("k", k); 127 | map.put("v", v); 128 | return map; 129 | } 130 | 131 | public static Map BuildTextMessage(String msg) 132 | { 133 | return BuildTextMessage(0, msg); 134 | } 135 | 136 | public static Map BuildTextMessage(long pid, String msg) 137 | { 138 | Map map = BuildMapByType(MessageType.TEXT); 139 | map.put("pid", pid); 140 | map.put("text", msg); 141 | return map; 142 | } 143 | 144 | private static Map BuildMapByType(MessageType type) 145 | { 146 | Map map = new HashMap(); 147 | switch(type) 148 | { 149 | case FLAG: 150 | map.put("t", "flag"); 151 | break; 152 | case KV: 153 | map.put("t", "kv"); 154 | break; 155 | case TEXT: 156 | map.put("t", "text"); 157 | break; 158 | case ROOMINFO: 159 | map.put("t", "roominfo"); 160 | break; 161 | case GAMEINFO: 162 | map.put("t", "gameinfo"); 163 | break; 164 | case SERVERINFO: 165 | map.put("t", "serverinfo"); 166 | break; 167 | case LOBBYINFO: 168 | map.put("t", "lobbyinfo"); 169 | break; 170 | case MYINFO: 171 | map.put("t", "myinfo"); 172 | break; 173 | case PLAYERLEAVE: 174 | map.put("t", "playerleave"); 175 | break; 176 | case PLAYERENTER: 177 | map.put("t", "playerenter"); 178 | break; 179 | case INFO: 180 | map.put("t", "info"); 181 | break; 182 | case ADDNEWROOM: 183 | map.put("t", "addroom"); 184 | break; 185 | case SWITCHPLACE: 186 | map.put("t", "onswitch"); 187 | break; 188 | case CARDSENDED: 189 | map.put("t", "cardsended"); 190 | break; 191 | case PEND: 192 | map.put("t", "pend"); 193 | break; 194 | case BLACKCARD: 195 | map.put("t", "blackcard"); 196 | break; 197 | case WHITECARD: 198 | map.put("t", "whitecard"); 199 | break; 200 | default: 201 | map.put("t", "d"); 202 | break; 203 | } 204 | return map; 205 | } 206 | 207 | public static Map BuildServerInfo(){ 208 | Map map = BuildMapByType(MessageType.SERVERINFO); 209 | map.put("version", Server.version); 210 | map.put("players", Server.gameWorld.getPlayerCount()); 211 | map.put("max", GameWorld.MAX_PLAYER); 212 | return map; 213 | } 214 | 215 | public static Map buildMyInfo(Player player){ 216 | Map map = BuildMapByType(MessageType.MYINFO); 217 | HashMapArray arr = new HashMapArray(); 218 | arr.addMap(player.buildPlayerInfo()); 219 | map.put("info", arr); 220 | return map; 221 | } 222 | 223 | public static Map buildLobbyInfo(Lobby lobby){ 224 | Map map = BuildMapByType(MessageType.LOBBYINFO); 225 | map.put("players", lobby.buildPlayersInfo()); 226 | map.put("rooms", lobby.buildRoomsInfo()); 227 | return map; 228 | } 229 | 230 | public static Map buildPlayerLeaveInfo(long pid){ 231 | Map map = BuildMapByType(MessageType.PLAYERLEAVE); 232 | map.put("pid", pid); 233 | return map; 234 | } 235 | 236 | public static Map buildPlayerEnterInfo(Player player){ 237 | Map map = BuildMapByType(MessageType.PLAYERENTER); 238 | HashMapArray hma = new HashMapArray(); 239 | hma.addMap(player.buildPlayerInfo()); 240 | map.put("player", hma); 241 | return map; 242 | } 243 | 244 | public static Map buildPlayerEnterInfo(Player player, boolean spectate){ 245 | Map map = BuildMapByType(MessageType.PLAYERENTER); 246 | HashMapArray hma = new HashMapArray(); 247 | hma.addMap(player.buildPlayerInfo()); 248 | map.put("player", hma); 249 | map.put("spectate", spectate); 250 | return map; 251 | } 252 | 253 | public static Map buildRoomInfo(Room room){ 254 | Map map = BuildMapByType(MessageType.ROOMINFO); 255 | map.put("players", room.buildPlayersInfo()); 256 | map.put("spectators", room.buildSpectatorsInfo()); 257 | map.put("id", room.getId()); 258 | map.put("pw", room.getPassword()); 259 | map.put("name", room.getName()); 260 | map.put("state", room.getRound() == null ? 0 : room.getRound().getState()); 261 | if(room.getCardpacks() != null){ 262 | String cardpacks = ""; 263 | for(int i : room.getCardpacks()){ 264 | cardpacks+=CardsService.cardpacks.get(i).getPackid() + ","; 265 | } 266 | cardpacks = cardpacks.substring(0, cardpacks.length() - 1); 267 | map.put("cp", cardpacks); 268 | } 269 | return map; 270 | } 271 | 272 | public static Map buildCardPacksInfo(){ 273 | Map map = BuildMapByType(MessageType.INFO); 274 | map.put("k", "cp"); 275 | map.put("cp", CardsService.buildCardPacksInfo()); 276 | return map; 277 | } 278 | 279 | public static Map buildAddNewRoomInfo(Room room){ 280 | Map map = BuildMapByType(MessageType.ADDNEWROOM); 281 | HashMapArray hma = new HashMapArray(); 282 | hma.addMap(room.buildRoomShortInfo()); 283 | map.put("room", hma); 284 | return map; 285 | } 286 | 287 | public static Map buildPlayerSwitchInfo(long id, int place){ 288 | Map map = BuildMapByType(MessageType.SWITCHPLACE); 289 | map.put("pid", id); 290 | map.put("place", place); 291 | return map; 292 | } 293 | 294 | public static Map buildCardSendedInfo(int total, int success, int repeat, int illegal){ 295 | Map map = BuildMapByType(MessageType.CARDSENDED); 296 | map.put("to", total); 297 | map.put("su", success); 298 | map.put("re", repeat); 299 | map.put("il", illegal); 300 | return map; 301 | } 302 | 303 | public static Map buildPendingInfo(){ 304 | Map map = BuildMapByType(MessageType.PEND); 305 | map.put("c", CardsService.buildAllPendingCardsInfo()); 306 | return map; 307 | } 308 | 309 | public static Map buildBlackCardInfo(BlackCard card, int roundId, long czar){ 310 | Map map = BuildMapByType(MessageType.BLACKCARD); 311 | map.put("text", card.getText()); 312 | map.put("cp", card.getPackid()); 313 | map.put("au", card.getPname()); 314 | map.put("bl", card.getBlankCount()); 315 | map.put("id", roundId); 316 | map.put("czar", czar); 317 | return map; 318 | } 319 | 320 | public static Map buildWhiteCardInfo(Set cards){ 321 | Map map = BuildMapByType(MessageType.WHITECARD); 322 | HashMapArray hma = new HashMapArray(); 323 | for(WhiteCard c : cards){ 324 | Map m = new HashMap(); 325 | m.put("text", c.getText()); 326 | m.put("cp", c.getPackid()); 327 | m.put("au", c.getPname()); 328 | m.put("id", c.getCid()); 329 | hma.addMap(m); 330 | } 331 | map.put("c", hma); 332 | return map; 333 | } 334 | 335 | public static Map buildJudgingInfo(int combo, Set cards){ 336 | Map map = new HashMap(); 337 | map.put("t", "judge"); 338 | int i = 0; 339 | for(WhiteCard[] wcs : cards){ 340 | HashMapArray hma = new HashMapArray(); 341 | for(WhiteCard wc : wcs){ 342 | Map ccc = new HashMap(); 343 | if(wc == null){ 344 | ccc.put("text", "???"); 345 | ccc.put("au", "???"); 346 | ccc.put("cp", 0); 347 | ccc.put("id", 0); 348 | }else{ 349 | ccc.put("text", wc.getText()); 350 | ccc.put("au", wc.getPname()); 351 | ccc.put("cp", wc.getPackid()); 352 | ccc.put("id", wc.getCid()); 353 | } 354 | hma.addMap(ccc); 355 | } 356 | map.put("c" + i, hma); 357 | i++; 358 | } 359 | map.put("bl", combo); 360 | return map; 361 | } 362 | 363 | public static Map buildWinnerInfo(String cidsraw, long pid, int combo, int add){ 364 | Map map = new HashMap(); 365 | map.put("t", "winner"); 366 | map.put("cid", cidsraw); 367 | map.put("pid", pid); 368 | map.put("combo", combo); 369 | map.put("add", add); 370 | return map; 371 | } 372 | 373 | public static Map buildWinnerBroadCast(String text){ 374 | Map map = new HashMap(); 375 | map.put("t", "br"); 376 | map.put("text", text); 377 | return map; 378 | } 379 | } 380 | -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/src/css/app.css: -------------------------------------------------------------------------------- 1 | body {padding:0; margin:0; font-family:"微软雅黑"; background-color:#555;} 2 | .button {position:relative; text-align:center; background-color:#555; color:#ccc; border:solid 2px #888; padding:5px;} 3 | .button:hover {position:relative; cursor:pointer; background-color:#bbb; color:#555; border:solid 2px #888;} 4 | #wrapper {width:100%; color:#eee3e3;} 5 | .page {display:none; width:1024px; height:640px; margin:0px auto; background-color:#444;} 6 | #loginPage .title {padding:50px; text-align:center;} 7 | #loginPage .title .titleText{font-size:40px;} 8 | #loginPage .title .titleSubtext{font-size:25px;} 9 | #loginPage .title .info {margin-top:50px;} 10 | #loginPage .title .info .infocard{vertical-align:middle; margin:10px; text-align:left; padding:10px; width:200px; height:120px; background-color:#333; color:#fff; display:inline-block; box-shadow:#333 3px 3px; border:solid 2px #777;} 11 | #loginPage .title .info .infocardwhite{vertical-align:middle; margin:10px; text-align:left; padding:10px; width:200px; height:120px; background-color:#fff; color:#333; display:inline-block; box-shadow:#333 3px 3px; border:solid 2px #333;} 12 | #loginPage .loginArea {width:100%; text-align:center;} 13 | #loginPage .loginArea #logintip {} 14 | #loginPage .loginArea #serverinfo {text-align:center;} 15 | #loginPage .loginArea #submit {height:30px; line-height:30px;} 16 | #loginPage .loginArea table {text-align:right; margin:20px auto;} 17 | #loginPage .loginArea table #submit {height:30px;} 18 | #loginPage .loginArea #onlineBar {display:block; float:left; background-color:#222; width:0%; height:24px; text-align:center;} 19 | #loginPage .loginArea #serverinfo {display:block; float:left; line-height:20px; border:solid 2px #aaa; position:absolute; z-index:1; width:150px; height:20px; text-align:center;} 20 | 21 | #lobbyPage #leftArea {float:left; width:700px; height:616px; margin:10px 0px 10px 10px;} 22 | #lobbyPage #roomArea {width:696px; height:420px; background-color:#888; border:solid 2px #555; overflow-x:hidden; overflow-y:scroll;} 23 | #lobbyPage #roomArea .room {display:block; width: 630px; height: 68px; margin:10px auto; background-color:#ddd; border:solid 2px #555; color:#333; padding:10px; padding-top:8px; vertical-align:middle;} 24 | #lobbyPage #roomArea .room:hover{background-color:#bbb; cursor:pointer;} 25 | #lobbyPage #roomArea .room .left {vertical-align:middle; display:inline-block; width:120px; height:70px;} 26 | #lobbyPage #roomArea .room .left #roomnum {font-size:20px; font-weight:bold;} 27 | #lobbyPage #roomArea .room .left #desc {} 28 | 29 | #lobbyPage #roomArea .room .middle {vertical-align:middle; display:inline-block; width:120px; height:70px; text-align:center;} 30 | #lobbyPage #roomArea .room .middle #players {} 31 | #lobbyPage #roomArea .room .middle #spectors {} 32 | #lobbyPage #roomArea .room .middle #stat {} 33 | #lobbyPage #roomArea .room #packsArea {vertical-align:middle; display:inline-block; width:380px; height:70px; margin-top:2px; overflow:auto;} 34 | #lobbyPage #roomArea .room #packsArea .cardpack {display:inline-block; background-color:#aaa; padding:2px; margin:2px;} 35 | 36 | #lobbyPage #leftBottomArea {width:700px; height:182px; margin-top:10px;} 37 | #lobbyPage #leftBottomArea #statArea{float:left; width:250px; height:182px; background-color:#888; border:solid 2px #555; color:#222;} 38 | 39 | #lobbyPage #leftBottomArea #statArea #nameTag{height:32px; background-color:#555; font-weight:bold; text-align:center; font-size:22px; line-height:32px; color:#fff; overflow:hidden;} 40 | #lobbyPage #leftBottomArea #statArea #levelinfo{height:30px; padding:10px; overflow:visible;} 41 | #lobbyPage #leftBottomArea #statArea #levelinfo #level{font-size:20px; margin-bottom:5px; font-weight:bold; text-align:center;} 42 | #lobbyPage #leftBottomArea #statArea #levelinfo #levelBarArea{width:226px; margin-top:0px;} 43 | #lobbyPage #leftBottomArea #statArea #levelinfo #levelBarArea #levelBarBack{display:block; float:left; background-color:#333; width:90%; height:24px; text-align:center;} 44 | #lobbyPage #leftBottomArea #statArea #levelinfo #levelBarArea #levelBarExp{color:white; display:block; float:left; line-height:20px; border:solid 2px #aaa; position:absolute; z-index:1; width:224px; height:20px; text-align:center;} 45 | #lobbyPage #leftBottomArea #statArea #credit{margin:5px 10px; margin-top:30px;} 46 | #lobbyPage #leftBottomArea #statArea #fish{margin:5px 10px; margin-top:5px;} 47 | #lobbyPage #leftBottomArea #statArea #title{height: 30px; display:inline-block; width:60px; vertical-align:top; text-align:right;} 48 | #lobbyPage #leftBottomArea #statArea #content{height: 30px; color:#222; font-weight:bold; margin-left:10px; vertical-align:top;} 49 | 50 | #lobbyPage #leftBottomArea #chatArea{float:right; width:432px; height:182px;} 51 | #lobbyPage #leftBottomArea #chatArea #messages{float:right; width:422px; height:138px; background-color:#888; border:solid 2px #555; overflow-x:hidden; overflow-y:scroll; padding:5px;} 52 | #lobbyPage #leftBottomArea #chatArea #messages #server{color:#444; font-weight:bold;} 53 | #lobbyPage #leftBottomArea #chatArea #messages #br{color:#333; font-weight:bold;} 54 | #lobbyPage #leftBottomArea #chatArea #messages #br span{color:#eee; font-weight:bold;} 55 | #lobbyPage #leftBottomArea #chatArea #messages #name{color:#ccc; font-weight:bold;} 56 | #lobbyPage #leftBottomArea #chatArea #messages #content{color:#fff;} 57 | #lobbyPage #leftBottomArea #chatArea #inputArea{float:right; width:432px; height:24px; background-color:#888; border:solid 2px #555; margin-top:6px;} 58 | #lobbyPage #leftBottomArea #chatArea #inputArea #inputbox{float:left; width:340px; height:20px; background-color:#888; border:0; margin:1px;} 59 | #lobbyPage #leftBottomArea #chatArea #inputArea #submit{float:right; width:80px; height:20px; border:solid 2px #555; padding:0px;} 60 | 61 | #lobbyPage #rightArea {float:right; width:290px; height:616px; margin:10px 10px 10px 0px;} 62 | #lobbyPage #rightArea #playersArea {width:286px; height:480px; background-color:#888; border:solid 2px #555; overflow-x:hidden; overflow-y:scroll;} 63 | #lobbyPage #rightArea #playersArea .player{ overflow:hidden; height:26px; background-color:#ddd; margin:5px; padding:5px; line-height:26px; color:#333; font-weight:bold; border:solid 2px #444;} 64 | #lobbyPage #rightArea #playersArea .player #level{display:inline-block; width:50px; } 65 | #lobbyPage #rightArea #playersArea .player #name{display:inline-block; width:190px; text-align:center;} 66 | 67 | #lobbyPage #rightArea #settingsArea {width:286px; height:122px; background-color:#888; border:solid 2px #555; margin-top:10px;} 68 | #lobbyPage #rightArea #settingsArea .button {display:inline-block; width:118px; margin:4px 0px 0px 5px; border:solid 2px #444;} 69 | 70 | #gamePage{} 71 | #gamePage #leftArea{float:left; width:230px; height:620px; padding:10px;} 72 | #gamePage #leftArea #roominfo{width:246px; height:30px; background-color:#888; border:solid 2px #555;} 73 | #gamePage #leftArea #roominfo #roomnum{display:inline-block; line-height:30px; font-weight:bold; width:50px; height:30px; text-align:center; vertical-align:top;} 74 | #gamePage #leftArea #roominfo #roomname{display:inline-block; line-height:30px; font-weight:bold; width:190px; height:30px; text-align:left; overflow:hidden; word-break:keep-all;} 75 | 76 | #gamePage #leftArea #blackCardArea{width: 240px; height:144px;} 77 | #gamePage #leftArea #blackCardArea #blackCard{width: 236px; height:130px; background-color:#111; padding:5px; border:solid 2px #555; margin-top:10px; font-size:18px; word-break:break-all;} 78 | #gamePage #leftArea #blackCardArea img{max-width:100%; height:auto;} 79 | #gamePage #leftArea #blackCardArea #blackCard .blank{display:inline; word-break:break-all;} 80 | #gamePage #leftArea #blackCardArea #blackCard #info{position:absolute; float:left; top:178px; color:#666; font-size:12px;} 81 | #gamePage #leftArea #blackCardArea #hostSettings #startGame{margin-top:5px; width:236px; } 82 | 83 | #gamePage #leftArea #timerArea{width: 240px; height:20px; margin-top:5px; } 84 | #gamePage #leftArea #timerArea #timerBack{width: 246px; height:20px; background-color:#999; border:solid 2px #555;} 85 | #gamePage #leftArea #timerArea #timerBack #timerFill{width:32%; height:20px; background-color:#111;} 86 | 87 | #gamePage #leftArea #statArea{width:246px; height:122px; margin-top:10px; background-color:#888; border:solid 2px #555; color:#222;} 88 | #gamePage #leftArea #statArea #nameTag{height:24px; background-color:#555; font-weight:bold; text-align:center; font-size:18px; line-height:24px; color:#fff; overflow:hidden;} 89 | #gamePage #leftArea #statArea #levelinfo{height:50px; overflow:visible;} 90 | #gamePage #leftArea #statArea #levelinfo #level{font-size:16px; font-weight:bold; text-align:center;} 91 | #gamePage #leftArea #statArea #levelinfo #levelBarArea{width:226px; margin-left:10px;} 92 | #gamePage #leftArea #statArea #levelinfo #levelBarArea #levelBarBack{display:block; float:left; background-color:#333; width:90%; height:24px; text-align:center; margin-bottom:3px;} 93 | #gamePage #leftArea #statArea #levelinfo #levelBarArea #levelBarExp{color:white; display:block; line-height:20px; border:solid 2px #aaa; position:absolute; z-index:1; width:224px; height:20px; text-align:center;} 94 | #gamePage #leftArea #statArea #title{height: 22px; display:inline-block; width:60px; vertical-align:top; text-align:right;} 95 | #gamePage #leftArea #statArea #content{height: 22px; color:#222; font-weight:bold; margin-left:10px; vertical-align:top;} 96 | 97 | #gamePage #leftArea #chatArea{width:250px; height:261px; margin-top:10px;} 98 | #gamePage #leftArea #chatArea #messages{width:236px; height:213px; background-color:#888; border:solid 2px #555; overflow-x:hidden; overflow-y:scroll; padding:5px;} 99 | #gamePage #leftArea #chatArea #messages #server{color:#444; font-weight:bold;} 100 | #gamePage #leftArea #chatArea #messages #br{color:#333; font-weight:bold;} 101 | #gamePage #leftArea #chatArea #messages #br span{color:#eee; font-weight:bold;} 102 | #gamePage #leftArea #chatArea #messages #name{color:#ccc; font-weight:bold;} 103 | #gamePage #leftArea #chatArea #messages #content{color:#fff;} 104 | #gamePage #leftArea #chatArea #messages #content img{max-width:100%; height:auto;} 105 | #gamePage #leftArea #chatArea #inputArea{width:246px; height:24px; background-color:#888; border:solid 2px #555; margin-top:6px;} 106 | #gamePage #leftArea #chatArea #inputArea #inputbox{float:left; width:180px; height:20px; background-color:#888; border:0; margin:1px;} 107 | #gamePage #leftArea #chatArea #inputArea #submit{float:right; width:60px; height:24px; padding:0px; border:0;} 108 | 109 | #gamePage #tableArea{float:left; width:230px; height:620px; padding:10px; margin-left:10px;} 110 | #gamePage #tableArea #tableTitle{width:246px; height:30px; background-color:#888; border:solid 2px #555; text-align:center; line-height:30px; font-weight:bold;} 111 | #gamePage #tableArea #table{width:246px; height:572px; margin-top:10px; border:solid 2px #555; background-color:#888;} 112 | #gamePage #tableArea #table .cards{width:236px; height:76px; overflow:hidden; margin:5px;} 113 | #gamePage #tableArea #table .cards img{max-height:100%; width:auto;} 114 | #gamePage #tableArea #table #whitecard{float:left; height:72px; color:#111; background-color:#eee; border:solid 2px #555; overflow:hidden; text-align:center;} 115 | #gamePage #tableArea #table #pack3 #whitecard{width:71px; margin-left:5px;} 116 | #gamePage #tableArea #table #pack3 #whitecard:first-child{margin-left:0px;} 117 | #gamePage #tableArea #table #pack2 #whitecard{width:111px; margin-left:5px;} 118 | #gamePage #tableArea #table #pack2 #whitecard:first-child{margin-left:0px;} 119 | #gamePage #tableArea #table #pack1 #whitecard{width:232px;} 120 | 121 | .winnercard {background-color:#555; color:white;} 122 | .winner {background-color:white; color:#555;} 123 | 124 | #gamePage #tableArea #table .cards:hover #whitecard{cursor:pointer; border:solid 2px #ddd;} 125 | 126 | #gamePage #handArea{float:left; width:230px; height:620px; padding:10px; margin-left:10px;} 127 | #gamePage #handArea #handTitle{width:246px; height:30px; background-color:#888; border:solid 2px #555; text-align:center; line-height:30px; font-weight:bold;} 128 | #gamePage #handArea #hand{width:246px; height:572px; margin-top:10px; border:solid 2px #555; background-color:#888;} 129 | #gamePage #handArea #hand .cards{width:236px; height:51.5px; overflow:hidden; margin:5px;} 130 | #gamePage #handArea #hand .cards img{max-height:100%; width:auto;} 131 | #gamePage #handArea #hand .cards #whitecard{float:left; height:47.5px; width:232px; color:#111; background-color:#eee; border:solid 2px #555; overflow:hidden; text-align:center;} 132 | #gamePage #handArea #hand .cards:hover #whitecard{cursor:pointer; border:solid 2px #ddd;} 133 | 134 | #gamePage #rightArea{float:left; width:218px; height:620px; padding:10px; margin-left:10px;} 135 | #gamePage #rightArea #playerArea{width:208px; height:442px; background-color:#888; border:solid 2px #555; text-align:center; padding:5px;} 136 | #gamePage #rightArea #playerArea .player{width:201px; height:43px; background-color:#555; border:solid 2px #333; padding:2px; margin-top:5px; text-align:left;} 137 | #gamePage #rightArea #playerArea .player:first-child{margin-top:0px;} 138 | #gamePage #rightArea #playerArea .player:hover {background-color:#777; border:solid 2px #555; color:#fff; cursor:pointer;} 139 | #gamePage #rightArea #playerArea .player #name{clear:both; margin-left:5px;} 140 | #gamePage #rightArea #playerArea .player #level{float:left; width:80px; margin-left:5px;} 141 | #gamePage #rightArea #playerArea .player #score{float:left; width:30px; margin-left:5px;} 142 | #gamePage #rightArea #playerArea .player #title{float:right; width:50px; background-color:#333; text-align:center;} 143 | 144 | #gamePage #rightArea #spectateArea{width:208px; height:100px; background-color:#888; border:solid 2px #555; text-align:center; padding:5px; overflow-y:scroll; overflow-x:hidden; margin-top:5px;} 145 | #gamePage #rightArea #spectateArea .player{width:180px; height:23px; background-color:#555; border:solid 2px #333; padding:2px; margin-top:5px; text-align:left; overflow:hidden;} 146 | #gamePage #rightArea #spectateArea .player:first-child{margin-top:0px;} 147 | #gamePage #rightArea #spectateArea .player:hover {background-color:#777; border:solid 2px #555; color:#fff; cursor:pointer;} 148 | #gamePage #rightArea #spectateArea .player #name{float:left; margin-left:5px;} 149 | 150 | #gamePage #rightArea #settingsArea{width:222px; height:39px; text-align:center; margin-top:5px;} 151 | #gamePage #rightArea #settingsArea div{float:left; height:26px; line-height:26px; width:56px; margin-left:5px;} 152 | #gamePage #rightArea #settingsArea div:first-child{margin-left:0px;} 153 | 154 | #mask {display: none; z-index:500; position:fixed; float:left; left:0px; top:0px; height:0px; background-color:black; width:100%; height:100%; filter:alpha(Opacity=70);-moz-opacity:0.7;opacity: 0.7; } 155 | .mask{-webkit-filter: blur(5px); -moz-filter: blur(5px); filter: blur(5px);} 156 | 157 | .settingsPage{display:none; position:absolute; z-index:999; background-color:#888; border:solid 2px #333; margin:auto; left:0px; top:0px; right:0px; bottom:0px; color:black;} 158 | .settingsPage .title{height:40px; background-color:#333; color:white; text-align:center; font-weight:bold; line-height:40px; font-size:20px;} 159 | .settingsPage .closeButton{float:right; width:40px; height:40px; text-align:center; background-color:#555;} 160 | .settingsPage .closeButton:hover{background-color:#aaa; color:#111; cursor:pointer;} 161 | .settingsPage .content .desc{text-align:center; margin:10px 0px;} 162 | 163 | #createcard{width:500px; height:350px;} 164 | #createcard .options{text-align:center;} 165 | #createcard #text{resize:none; width:480px; height:150px; margin:10px 8px;} 166 | #createcard #submit{width:200px;margin:0px auto; border:solid 2px #333;} 167 | 168 | #createroom{width:300px; height:350px;} 169 | #createroom .option{padding:10px; margin:10px;} 170 | #createroom .option input{margin-left:10px;} 171 | #createroom #cardpacks {margin-bottom:30px;} 172 | #createroom #cardpacks div{display:inline-block;} 173 | #createroom #submit{width:200px;margin:0px auto; border:solid 2px #333;} 174 | 175 | #setroom{width:300px; height:420px;} 176 | #setroom .option{padding:10px; margin:10px;} 177 | #setroom .option input{margin-left:10px;} 178 | #setroom #cardpacks {margin-bottom:30px;} 179 | #setroom #cardpacks div{display:inline-block;} 180 | #setroom #submit{width:200px;margin:0px auto; border:solid 2px #333;} 181 | 182 | #sug{width:500px; height:310px;} 183 | #sug #text{resize:none; width:480px; height:150px; margin:10px 8px;} 184 | #sug #submit{width:200px;margin:0px auto; border:solid 2px #333;} 185 | 186 | #pend{width:900px; height:610px;} 187 | #pend #tablecontainer{width:880px; height:495px; margin:10px 8px; overflow:auto; text-align:center; background-color:#ddd; border:solid 2px #666;} 188 | #pend #table{display:block; margin:0px auto;} 189 | #pend #table td{min-width:80px; padding:5px;} 190 | #pend #submit{width:200px;margin:0px auto; border:solid 2px #333;} 191 | 192 | #gamestart{width:500px; height:300px;} 193 | .preview {color:#fff; font-weight:bold; text-decoration:underline; margin-left:3px; margin-right:3px;} 194 | 195 | #czarmask {position:absolute; float:left; width:246px; height:572px; background-color:#000; margin-top:10px; line-height:572px; font-size:30px; color:#aaa; font-weight:bold; word-spacing:20px; text-align:center; border:solid 2px #555; filter:alpha(Opacity=70);-moz-opacity:0.7;opacity: 0.7;} 196 | 197 | #table .cover{float:left; position:relative; z-index:10;} 198 | #messages{word-break: break-all;} -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/src/script/hla3n233.4lz: -------------------------------------------------------------------------------- 1 | declare var jQuery; 2 | 3 | class GameSettings { 4 | public static Server: string = "ws://localhost:4849/CardsAgaisntHumanity/server"; 5 | public static AllowMulti: boolean = true; 6 | public static debugMode: boolean = true; 7 | } 8 | 9 | class MyEvent { 10 | 11 | public static arr: Array; 12 | 13 | /** 14 | * 绑定事件到指定信号 15 | */ 16 | public static bind(triggerName: string, target: Function, thisObject: any): void { 17 | if (!MyEvent.arr) { 18 | MyEvent.arr = []; 19 | } 20 | var eo = new EventObject(triggerName, target, thisObject); 21 | MyEvent.arr.push(eo); 22 | } 23 | 24 | /** 25 | * 解绑事件 26 | */ 27 | public static unbind(triggerName: string, target: Function = null): void { 28 | if (!MyEvent.arr) { 29 | return; 30 | } 31 | if (target) { 32 | for (var i = 0; i < MyEvent.arr.length; i++) { 33 | if (MyEvent.arr[i].triggerName == triggerName && MyEvent.arr[i].target == target) { 34 | MyEvent.arr.splice(i, 1); 35 | break; 36 | } 37 | } 38 | } else { 39 | for (var i = 0; i < MyEvent.arr.length; i++) { 40 | if (MyEvent.arr[i].triggerName == triggerName) { 41 | MyEvent.arr.splice(i, 1); 42 | break; 43 | } 44 | } 45 | } 46 | } 47 | 48 | /** 49 | * 解绑信号所有事件 50 | */ 51 | public static unbindAll(triggerName: string, target: Function = null): void { 52 | if (!MyEvent.arr) { 53 | return; 54 | } 55 | 56 | if (target) { 57 | for (var i = 0; i < MyEvent.arr.length; i++) { 58 | if (MyEvent.arr[i].triggerName == triggerName && MyEvent.arr[i].target == target) { 59 | MyEvent.arr.splice(i, 1); 60 | i--; 61 | } 62 | } 63 | } else { 64 | for (var i = 0; i < MyEvent.arr.length; i++) { 65 | if (MyEvent.arr[i].triggerName == triggerName) { 66 | MyEvent.arr.splice(i, 1); 67 | i--; 68 | } 69 | } 70 | } 71 | } 72 | 73 | /** 74 | * 调用事件 75 | */ 76 | public static call(triggerName: string, data: any = null): void { 77 | for (var i = 0; i < MyEvent.arr.length; i++) { 78 | if (MyEvent.arr[i].triggerName == triggerName) { 79 | MyEvent.arr[i].target(data, MyEvent.arr[i].thisObject); 80 | } 81 | } 82 | } 83 | } 84 | 85 | class EventObject { 86 | public triggerName: string; 87 | public target: Function; 88 | public thisObject: any; 89 | 90 | constructor(triggerName: string, target: Function, thisObject: any) { 91 | this.triggerName = triggerName; 92 | this.target = target; 93 | this.thisObject = thisObject; 94 | } 95 | } 96 | 97 | class Player { 98 | public pid: number; 99 | public name: string; 100 | public exp: number; 101 | public credit: number; 102 | public state: number; 103 | public fish: number; 104 | 105 | public getLevel(): number { 106 | var lvl: number = 1; 107 | while (this.getLevelExp(lvl) < this.exp) { 108 | lvl++; 109 | } 110 | return lvl; 111 | } 112 | 113 | public getNeedExp(): number { 114 | return Math.max(this.getLevelExp(this.getLevel()) - this.getLevelExp(this.getLevel() - 1), 0); 115 | } 116 | 117 | public getRemainExp(): number { 118 | return Math.max(this.exp - this.getLevelExp(this.getLevel() - 1), 0); 119 | } 120 | 121 | public getLevelExp(lvl: number): number { 122 | if (lvl == 0) 123 | return 0; 124 | return 10 + Math.round(Math.pow((lvl - 1) * 1.3, 1.9) * 5); 125 | } 126 | } 127 | 128 | class Util { 129 | public static replaceAll(org:string, findStr:string, repStr:string) { 130 | var str: string = org; 131 | var index: number = 0; 132 | while (index <= str.length) { 133 | index = str.indexOf(findStr, index); 134 | if (index == -1) { 135 | break; 136 | } 137 | str = str.replace(findStr, repStr); 138 | index += repStr.length; 139 | } 140 | return str; 141 | } 142 | 143 | public static getStringLen(str: string): number { 144 | var i, len, code; 145 | if (str == null || str == "") return 0; 146 | len = str.length; 147 | for (i = 0; i < str.length; i++) { 148 | code = str.charCodeAt(i); 149 | if (code > 255) { len++; } 150 | } 151 | return len; 152 | } 153 | 154 | public static convertPlayerData(data: any): Player { 155 | var p: Player = new Player(); 156 | p.pid = data.pid; 157 | p.name = data.name; 158 | p.exp = data.exp; 159 | p.state = data.state; 160 | p.credit = data.credit; 161 | p.fish = data.fish; 162 | return p; 163 | } 164 | } 165 | 166 | class Server { 167 | public static instance: Server; 168 | public socket: WebSocket; 169 | 170 | constructor() { 171 | Server.instance = this; 172 | this.socket = new WebSocket(GameSettings.Server); 173 | this.socket.onopen = (evt) => { this.onOpen(evt) }; 174 | this.socket.onclose = (evt) => { this.onClose(evt) }; 175 | this.socket.onmessage = (evt) => { this.onMessage(evt) }; 176 | this.socket.onerror = (evt) => { this.onError(evt) }; 177 | } 178 | 179 | /** 180 | * 成功连接到服务器事件 181 | */ 182 | onOpen(evt): void { 183 | if (GameSettings.debugMode) 184 | console.log("成功连接到服务器."); 185 | } 186 | 187 | /** 188 | * 从服务器断开事件 189 | */ 190 | onClose(evt): void { 191 | if (GameSettings.debugMode) 192 | console.log("已从服务器断开:" + evt.data); 193 | MyEvent.call('connectionclose', evt.data); 194 | } 195 | 196 | /** 197 | * 收到服务器信息事件 198 | */ 199 | onMessage(evt): void { 200 | if (GameSettings.debugMode) 201 | console.log('接收到消息: ' + evt.data); 202 | 203 | Main.unfreezeMe(); 204 | var data = MessageAnalysis.parseMessage(evt.data); 205 | switch (data.t) { 206 | case "flag": 207 | MyEvent.call(data.k); 208 | break; 209 | case "kv": 210 | MyEvent.call(data.k, data.v); 211 | break; 212 | default: 213 | MyEvent.call(data.t, data); 214 | break; 215 | } 216 | } 217 | 218 | /** 219 | * 发生错误事件 220 | */ 221 | onError(evt): void { 222 | console.log('发生错误: ' + evt.data); 223 | MyEvent.call('connectionerror', evt.data); 224 | } 225 | 226 | /** 227 | * 发送信息至服务器事件 228 | */ 229 | send(data, isVital): void { 230 | if (isVital && Main.isFrozen()) { 231 | console.log('网络被堵塞,请稍后再试!'); 232 | MyEvent.call("msg", "网络被堵塞,请稍后再试!"); 233 | return; 234 | } 235 | 236 | if (GameSettings.debugMode) 237 | console.log('发送消息: ' + data); 238 | 239 | this.socket.send(data); 240 | 241 | if (isVital) 242 | Main.freezeMe(); 243 | } 244 | } 245 | 246 | class PackageBuilder { 247 | public static buildLoginPackage(username: string, password: string): string { 248 | username = username.replace(/"/g, "\\\""); 249 | username = username.replace(/'/g, "\\'"); 250 | username = username.replace(/\\/g, "\\\\"); 251 | password = password.replace(/"/g, "\\\""); 252 | password = password.replace(/'/g, "\\'"); 253 | password = password.replace(/\\/g, "\\\\"); 254 | var pack = '{"t":"login", "username":"' + username + '", "password":"' + password + '"}'; 255 | return pack; 256 | } 257 | } 258 | 259 | class MessageAnalysis { 260 | public static parseMessage(data): any { 261 | return JSON.parse(data); 262 | } 263 | } 264 | 265 | enum State { 266 | CONNECTING, 267 | CONNECTED, 268 | LOBBY, 269 | PLAYING 270 | } 271 | 272 | class Signal { 273 | public static ServerInfo: string = "serverinfo"; 274 | public static OnClickLogin: string = "OnClickLogin"; 275 | public static LoginErr: string = "logerr"; 276 | public static MyInfo: string = "myinfo"; 277 | public static LobbyInfo: string = "lobbyinfo"; 278 | public static PLAYERENTER: string = "playerenter"; 279 | public static PLAYERLEAVE: string = "playerleave"; 280 | public static TEXT: string = "text"; 281 | } 282 | 283 | class Main { 284 | public static server: Server; 285 | public static state: State; 286 | public static me: Player; 287 | 288 | private static loginState: LoginState; 289 | private static lobbyState: LobbyState; 290 | 291 | private static freeze: boolean = false; 292 | public static isFrozen(): boolean { 293 | return Main.freeze; 294 | } 295 | 296 | public static freezeMe(): void { 297 | Main.freeze = true; 298 | } 299 | 300 | public static unfreezeMe(): void { 301 | Main.freeze = false; 302 | } 303 | 304 | public start(): void { 305 | Main.me = new Player(); 306 | Main.loginState = new LoginState(); 307 | Main.lobbyState = new LobbyState(); 308 | Main.loginState.start(); 309 | } 310 | } 311 | 312 | class LoginState { 313 | private ass: string = "ass"; 314 | private loginable: boolean = false; 315 | public start(): void { 316 | this.bindEvents(); 317 | Main.server = new Server(); 318 | Main.state = State.CONNECTING; 319 | this.showLoginPage(); 320 | } 321 | 322 | public bindEvents(): void { 323 | MyEvent.bind(Signal.ServerInfo, this.onCanLogin, this); 324 | MyEvent.bind(Signal.OnClickLogin, this.onLogin, this); 325 | MyEvent.bind(Signal.LoginErr, this.onLoginErr, this); 326 | MyEvent.bind(Signal.MyInfo, this.onShowLobbyPage, this); 327 | jQuery(".loginArea #submit").tapOrClick(this.onClickLogin); 328 | } 329 | 330 | public showLoginPage(): void { 331 | jQuery("#loginPage").show(); 332 | LoginState.setLoginTip("正在连接服务器..."); 333 | this.activateLoginArea(false); 334 | } 335 | 336 | public static setLoginTip(tip: string): void { 337 | jQuery("#logintip").html(tip); 338 | } 339 | 340 | public activateLoginArea(activate: boolean): void { 341 | if (activate) { 342 | jQuery("#username").attr("disabled", false); 343 | jQuery("#password").attr("disabled", false); 344 | } else { 345 | jQuery("#username").attr("disabled", true); 346 | jQuery("#password").attr("disabled", true); 347 | } 348 | } 349 | 350 | public onCanLogin(data: any, thisObject: LoginState): void { 351 | Main.state = State.CONNECTED; 352 | var par = parseInt(data.players) / parseInt(data.max) * 100; 353 | jQuery("#onlineBar").css("width", par + "%"); 354 | jQuery("#serverinfo").html(data.players + "/" + data.max); 355 | if (parseInt(data.players) < parseInt(data.max)) { 356 | LoginState.setLoginTip("请登录,如果该用户名没有注册过,则将自动为您注册。"); 357 | thisObject.activateLoginArea(true); 358 | thisObject.loginable = true; 359 | } 360 | } 361 | 362 | public onClickLogin(): void { 363 | MyEvent.call(Signal.OnClickLogin); 364 | } 365 | 366 | public onLogin(data: any, thisObject: LoginState): void { 367 | if (!thisObject.loginable) return; 368 | var $username: any = document.getElementById("username"); 369 | var $password: any = document.getElementById("password"); 370 | var username: string = $username.value.trim(); 371 | var password: string = $password.value.trim(); 372 | 373 | if (Util.getStringLen(username) < 2) { 374 | LoginState.setLoginTip('您的用户名太短!请至少超过6cm2个字符!'); 375 | return; 376 | } else if (Util.getStringLen(username) > 20) { 377 | LoginState.setLoginTip('您的用户名太长!请确保用户名小于20个字符(中文算2个)'); 378 | return; 379 | } else if (password.length < 4) { 380 | LoginState.setLoginTip('您的密码太短!请至少超过4个字符!'); 381 | return; 382 | } else if (password.length > 20) { 383 | LoginState.setLoginTip('您的密码太长!'); 384 | return; 385 | } else if (!LoginState.isUsernameLegal(username)) { 386 | LoginState.setLoginTip('您的用户名不合法!'); 387 | return; 388 | } 389 | 390 | thisObject.sendLogin(username, password ); 391 | } 392 | 393 | public sendLogin(username: string, password: string): void { 394 | if (Main.state != State.CONNECTED) return; 395 | LoginState.setLoginTip('正在登录...'); 396 | Server.instance.send(PackageBuilder.buildLoginPackage(username, password), true); 397 | } 398 | 399 | public static isUsernameLegal(name: string): boolean { 400 | return true; 401 | } 402 | 403 | private onLoginErr(data: any, _this: LoginState): void{ 404 | if (data == 101) { 405 | LoginState.setLoginTip('用户名密码验证不通过,请检查输入。'); 406 | } else if (data == 102) { 407 | LoginState.setLoginTip('密码错误,该用户已被注册!'); 408 | } else if (data == 103) { 409 | LoginState.setLoginTip('无法登录,该用户已经在线了!'); 410 | } 411 | } 412 | 413 | private onShowLobbyPage(data:any, thisObject: LoginState): void { 414 | MyEvent.unbind(Signal.ServerInfo, this.onCanLogin); 415 | MyEvent.unbind(Signal.OnClickLogin, this.onLogin); 416 | MyEvent.unbind(Signal.LoginErr, this.onLoginErr); 417 | MyEvent.unbind(Signal.MyInfo, this.onShowLobbyPage); 418 | jQuery("#loginPage").hide(); 419 | } 420 | } 421 | 422 | class LobbyState { 423 | private players: Array; 424 | 425 | public constructor() { 426 | this.bindEvents(); 427 | } 428 | 429 | public getPlayerByPid(pid: number): Player { 430 | var p: Player = null; 431 | for (var i = 0; i < this.players.length; i++) { 432 | if (this.players[i].pid == pid) { 433 | p = this.players[i]; 434 | break; 435 | } 436 | } 437 | return p; 438 | } 439 | 440 | public showLobbyPage(): void { 441 | jQuery("#lobbyPage").show(); 442 | this.clearChatArea(); 443 | } 444 | 445 | private bindEvents(): void { 446 | MyEvent.bind(Signal.MyInfo, this.OnGetMyInfo, this); 447 | MyEvent.bind(Signal.LobbyInfo, this.OnGetLobbyInfo, this); 448 | MyEvent.bind(Signal.PLAYERENTER, this.onPlayerEnter, this); 449 | MyEvent.bind(Signal.PLAYERLEAVE, this.onPlayerLeave, this); 450 | MyEvent.bind(Signal.TEXT, this.onReceiveText, this); 451 | } 452 | 453 | private OnGetMyInfo(data: any, _this: LobbyState): void { 454 | _this.showLobbyPage(); 455 | _this.updateMyInfo(data); 456 | } 457 | 458 | private OnGetLobbyInfo(data: any, _this: LobbyState): void { 459 | _this.players = new Array(); 460 | Main.state = State.LOBBY; 461 | for (var i = 0; i < data.players.length; i++) { 462 | _this.addOnePlayer(Util.convertPlayerData(data.players[i])); 463 | } 464 | _this.updatePlayerList(); 465 | } 466 | 467 | public onReceiveText(data: any, _this: LobbyState): void { 468 | var speaker: number = parseInt(data.speaker); 469 | var speakerName: string = "Unknow"; 470 | if (speaker == 0) 471 | speakerName = "系统"; 472 | else { 473 | var p: Player = _this.getPlayerByPid(speaker); 474 | if (p != null) 475 | speakerName = p.name; 476 | } 477 | 478 | var text: string = data.text; 479 | if(speaker == 0) 480 | jQuery("#chatArea #messages").append('
'); 481 | else 482 | jQuery("#chatArea #messages").append('
'); 483 | } 484 | 485 | public clearChatArea(): void { 486 | jQuery("#chatArea #messages").empty(); 487 | } 488 | 489 | public updateMyInfo(data: any): void{ 490 | Main.me = Util.convertPlayerData(data.info[0]); 491 | 492 | var level: number = Main.me.getLevel(); 493 | var remainExp: number = Main.me.getRemainExp(); 494 | var needExp: number = Main.me.getNeedExp(); 495 | 496 | jQuery("#statArea #nameTag").html(Main.me.name); 497 | jQuery("#statArea #nameTag").attr("title", "pid:" + Main.me.pid); 498 | jQuery("#statArea #level").html("Lv." + level); 499 | jQuery("#statArea #levelBarExp").html(remainExp + "/" + needExp); 500 | jQuery("#statArea #credit #content").html(Main.me.credit); 501 | jQuery("#statArea #fish #content").html(Main.me.fish); 502 | jQuery("#statArea #levelBarBack").css("width", (remainExp / needExp * 100) + "%"); 503 | } 504 | 505 | public onPlayerEnter(data: any, _this: LobbyState): void{ 506 | 507 | var p: Player = Util.convertPlayerData(data.player[0]); 508 | MyEvent.call(Signal.TEXT, {text:p.name + " 进入了大厅", speaker:0}); 509 | if (data.player[0].pid == Main.me.pid) 510 | return; 511 | _this.addOnePlayer(p); 512 | } 513 | 514 | public onPlayerLeave(data: any, _this: LobbyState): void { 515 | var p: Player = this.getPlayerByPid(data.pid); 516 | if(p != null) 517 | MyEvent.call(Signal.TEXT, { text: p.name + " 离开了大厅", speaker: 0}); 518 | } 519 | 520 | public addOnePlayer(player: Player): void { 521 | this.players.push(player); 522 | } 523 | 524 | public removeOnePlayer(pid: number): void { 525 | 526 | var index:number = -1; 527 | for (var i = 0; i < this.players.length; i++) { 528 | if (this.players[i].pid == pid) { 529 | index = i; 530 | break; 531 | } 532 | } 533 | 534 | if(index != -1) 535 | this.players.slice(index, index + 1); 536 | } 537 | 538 | public updatePlayerList(): void { 539 | var ele: any = jQuery("#playersArea"); 540 | ele.html(""); 541 | for (var i = 0; i < this.players.length; i++) { 542 | ele.append('
Lv.' + this.players[i].getLevel() + '' + this.players[i].name + '
'); 543 | } 544 | } 545 | } 546 | 547 | window.onload = () => { 548 | new Main().start(); 549 | }; -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 反人类卡牌游戏 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |
23 |
24 |
反人类卡牌游戏
25 |
Cards Against Humanity
26 |
- 重生 : ver beta 1.0 -
27 |
28 |
游戏分为黑卡与白卡,黑卡包含一段缺少1-3个词语的句子,白卡包含一条短语。
29 |
每轮游戏依次选择一名玩家作为裁判,玩家手中有10张白卡,用于回答黑卡所提出的问题,所有玩家选择完卡牌之后亮出自己的白卡。
30 |
裁判选择一张最满(wu)意(jie)的(cao)答案,并与该玩家同时获得一分,连续胜出者将获得额外奖励。
31 |
32 |
33 |
34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
登录/注册
52 |
53 |
54 | 55 |
56 |
57 |
58 |
59 |
60 |
001
61 |
默认房间
62 |
63 |
64 |
玩家:9/10
65 |
观众:1/16
66 |
游戏中
67 |
68 |
69 |
基本
70 |
基本EX
71 |
Bilibili
72 |
Acfun
73 |
74 |
75 | 76 | 77 |
78 |
79 |
002
80 |
中华人民膜蛤共和国
81 |
82 |
83 |
玩家:10/10
84 |
观众:7/16
85 |
游戏中
86 |
87 |
88 |
基本
89 |
基本EX
90 |
Bilibili
91 |
Acfun
92 |
动漫综合
93 |
英文
94 |
作死
95 |
东方Project
96 |
舰娘
97 |
A岛
98 |
CCTV
99 |
游戏综合
100 |
超恶俗
101 |
102 |
103 | 104 |
105 |
106 |
004
107 |
卡牌起源
108 |
109 |
110 |
玩家:3/10
111 |
观众:0/16
112 |
等待中
113 |
114 |
115 |
基本
116 |
117 |
118 | 119 |
120 |
121 |
005
122 |
默认房间
123 |
124 |
125 |
玩家:9/10
126 |
观众:1/16
127 |
游戏中
128 |
129 |
130 |
基本
131 |
基本EX
132 |
Bilibili
133 |
Acfun
134 |
动漫综合
135 |
英文
136 |
作死
137 |
东方Project
138 |
舰娘
139 |
A岛
140 |
CCTV
141 |
游戏综合
142 |
超恶俗
143 |
144 |
145 |
146 | 147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | 166 |
167 |
168 | 169 |
送信
170 |
171 |
172 |
173 |
174 |
175 |
176 | 183 |
184 |
185 |
创建房间
186 |
游戏设置
187 |
我的好友
188 |
制作卡牌
189 |
建议意见
190 |
退出登录
191 |
192 |
193 |
194 | 195 |
196 | 197 |
198 |
199 |
001
200 |
中华人民膜蛤共和国
201 |
202 | 203 |
204 |
205 | 您知道吗,下雨的时候,更配哦! 206 |
基本 作者:admin
207 |
208 |
209 |
开始游戏
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
admin
219 |
220 |
Lv.999
221 |
222 |
223 |
9999/9999
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 | 236 |
送信
237 |
238 |
239 |
240 | 241 |
242 |
出牌区域
243 |
244 |
245 |
不是每根JJ都梦想着喝嗨了吐在姨妈探亲的路口,也许人家只想在菊花园中翻滚着醉生梦死
246 |
什么鬼
247 |
啦啦啦啦啦啦啦啦啦啦啦啦
248 |
249 |
250 |
不是每根JJ都梦想着喝嗨了吐在姨妈探亲的路口,也许人家只想在菊花园中翻滚着醉生梦死
251 |
什么鬼
252 |
253 |
254 |
不是每根JJ都梦想着喝嗨了吐在姨妈探亲的路口,也许人家只想在菊花园中翻滚着醉生梦死
255 |
256 |
257 |
啦啦啦啦啦啦啦啦啦啦啦啦
258 |
259 |
260 |
你妈炸了
261 |
262 |
263 |
264 |
265 |
266 |
么么哒
267 |
268 |
269 |
270 | 271 |
272 |
我的手牌
273 |
裁判
274 |
275 |
276 |
不是每根JJ都梦想着喝嗨了吐在姨妈探亲的路口,也许人家只想在菊花园中翻滚着醉生梦死
277 |
278 |
279 |
什么鬼
280 |
281 |
282 |
不是每根JJ都梦想着喝嗨了吐在姨妈探亲的路口,也许人家只想在菊花园中翻滚着醉生梦死
283 |
284 |
285 |
啦啦啦啦啦啦啦啦啦啦啦啦
286 |
287 |
288 |
你妈炸了
289 |
290 |
291 |
292 |
293 |
294 |
么么哒
295 |
296 |
297 |
么么哒
298 |
299 |
300 |
么么哒
301 |
302 |
303 |
么么哒
304 |
305 |
306 |
307 | 308 |
309 |
310 |
311 |
啊啊啊啊啊啊啊啊啊啊
312 |
Lv.123
313 |
999
314 |
裁判
315 |
316 |
317 |
啊啊啊啊啊啊啊啊啊啊
318 |
Lv.123
319 |
999
320 |
出牌
321 |
322 |
323 |
啊啊啊啊啊啊啊啊啊啊
324 |
Lv.123
325 |
999
326 |
出牌
327 |
328 |
329 |
啊啊啊啊啊啊啊啊啊啊
330 |
Lv.123
331 |
999
332 |
出牌
333 |
334 |
335 |
啊啊啊啊啊啊啊啊啊啊
336 |
Lv.123
337 |
999
338 |
339 |
340 |
啊啊啊啊啊啊啊啊啊啊
341 |
Lv.123
342 |
999
343 |
344 |
345 |
小白
346 |
Lv.123
347 |
999
348 |
349 |
350 |
兔美酱
351 |
Lv.123
352 |
999
353 |
354 |
355 | 356 |
357 |
358 |
啊啊啊啊啊啊啊啊啊啊
359 |
360 |
361 |
啊啊啊啊啊啊啊啊啊啊
362 |
363 |
364 |
啊啊啊啊啊啊啊啊啊啊
365 |
366 |
367 |
啊啊啊啊啊啊啊啊啊啊
368 |
369 |
370 |
啊啊啊啊啊啊啊啊啊啊
371 |
372 |
373 |
啊啊啊啊啊啊啊啊啊啊
374 |
375 |
376 |
小白
377 |
378 |
379 |
兔美酱
380 |
381 |
382 | 383 |
384 |
旁观
385 |
设置
386 |
离开
387 |
388 |
389 |
390 |
391 | 392 |
393 |
创建房间
X
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
创建
412 |
413 |
414 | 415 |
416 |
房间设置
X
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |

436 |
437 |
确定
438 |
439 |
440 | 441 |
442 |
制作卡牌
X
443 |
444 |
请输入卡牌内容,多张卡牌请用 "|"(竖线) 分割
黑卡的下划线用 %b 代替,只能填写1-3个
445 |
446 | 447 |     448 | 449 | 452 |
453 | 454 |
提交
455 |
456 |
457 | 458 |
459 |
建议意见
X
460 |
461 |
请输入您的建议或者意见,或者是您想对作者说的话。
462 | 463 |
提交
464 |
465 |
466 | 467 |
468 |
审核卡牌
X
469 |
470 |
471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 |
全选作者类型卡包内容
admin白卡基本卡牌包EX你爸
487 |
488 |
提交
489 |
490 |
491 | 492 | 493 | -------------------------------------------------------------------------------- /CardsAgainstHumanityClient/CardsAgainstHumanityClient/src/script/zmcawnbi.kzr: -------------------------------------------------------------------------------- 1 | declare var jQuery; 2 | declare var returnCitySN; 3 | 4 | class GameSettings { 5 | public static Server: string = "ws://localhost:4849/CardsAgaisntHumanity/server"; 6 | public static AllowMulti: boolean = true; 7 | public static debugMode: boolean = true; 8 | 9 | public static help: string = "
/changepassword 更改密码
/where 查询玩家位置"; 10 | } 11 | 12 | class MyEvent { 13 | 14 | public static arr: Array; 15 | 16 | /** 17 | * 绑定事件到指定信号 18 | */ 19 | public static bind(triggerName: string, target: Function, thisObject: any): void { 20 | if (!MyEvent.arr) { 21 | MyEvent.arr = []; 22 | } 23 | var eo = new EventObject(triggerName, target, thisObject); 24 | MyEvent.arr.push(eo); 25 | } 26 | 27 | /** 28 | * 解绑事件 29 | */ 30 | public static unbind(triggerName: string, target: Function = null): void { 31 | if (!MyEvent.arr) { 32 | return; 33 | } 34 | if (target) { 35 | for (var i = 0; i < MyEvent.arr.length; i++) { 36 | if (MyEvent.arr[i].triggerName == triggerName && MyEvent.arr[i].target == target) { 37 | MyEvent.arr.splice(i, 1); 38 | break; 39 | } 40 | } 41 | } else { 42 | for (var i = 0; i < MyEvent.arr.length; i++) { 43 | if (MyEvent.arr[i].triggerName == triggerName) { 44 | MyEvent.arr.splice(i, 1); 45 | break; 46 | } 47 | } 48 | } 49 | } 50 | 51 | /** 52 | * 解绑信号所有事件 53 | */ 54 | public static unbindAll(triggerName: string, target: Function = null): void { 55 | if (!MyEvent.arr) { 56 | return; 57 | } 58 | 59 | if (target) { 60 | for (var i = 0; i < MyEvent.arr.length; i++) { 61 | if (MyEvent.arr[i].triggerName == triggerName && MyEvent.arr[i].target == target) { 62 | MyEvent.arr.splice(i, 1); 63 | i--; 64 | } 65 | } 66 | } else { 67 | for (var i = 0; i < MyEvent.arr.length; i++) { 68 | if (MyEvent.arr[i].triggerName == triggerName) { 69 | MyEvent.arr.splice(i, 1); 70 | i--; 71 | } 72 | } 73 | } 74 | } 75 | 76 | /** 77 | * 调用事件 78 | */ 79 | public static call(triggerName: string, data: any = null): void { 80 | for (var i = 0; i < MyEvent.arr.length; i++) { 81 | if (MyEvent.arr[i].triggerName == triggerName) { 82 | MyEvent.arr[i].target(data, MyEvent.arr[i].thisObject); 83 | } 84 | } 85 | } 86 | } 87 | 88 | class EventObject { 89 | public triggerName: string; 90 | public target: Function; 91 | public thisObject: any; 92 | 93 | constructor(triggerName: string, target: Function, thisObject: any) { 94 | this.triggerName = triggerName; 95 | this.target = target; 96 | this.thisObject = thisObject; 97 | } 98 | } 99 | 100 | class Player { 101 | public pid: number; 102 | public name: string; 103 | public exp: number; 104 | public credit: number; 105 | public state: number; 106 | public fish: number; 107 | 108 | public getLevel(): number { 109 | var lvl: number = 1; 110 | while (this.getLevelExp(lvl) < this.exp) { 111 | lvl++; 112 | } 113 | return lvl; 114 | } 115 | 116 | public getNeedExp(): number { 117 | return Math.max(this.getLevelExp(this.getLevel()) - this.getLevelExp(this.getLevel() - 1), 0); 118 | } 119 | 120 | public getRemainExp(): number { 121 | return Math.max(this.exp - this.getLevelExp(this.getLevel() - 1), 0); 122 | } 123 | 124 | public getLevelExp(lvl: number): number { 125 | if (lvl == 0) 126 | return 0; 127 | return 5 + Math.round(Math.pow(lvl * 2.4, 1.7)); 128 | } 129 | } 130 | 131 | class Room { 132 | public id: number; 133 | public roomname: string; 134 | public password: string; 135 | public playerCount: number; 136 | public spectatorCount: number; 137 | public state: number; 138 | public cardPacks: Array; 139 | } 140 | 141 | class CardPack { 142 | public id: number; 143 | public name: string; 144 | public level: number; 145 | public whitecount: number; 146 | public blackcount: number; 147 | } 148 | 149 | class Util { 150 | public static replaceAll(org:string, findStr:string, repStr:string) { 151 | var str: string = org; 152 | var index: number = 0; 153 | while (index <= str.length) { 154 | index = str.indexOf(findStr, index); 155 | if (index == -1) { 156 | break; 157 | } 158 | str = str.replace(findStr, repStr); 159 | index += repStr.length; 160 | } 161 | return str; 162 | } 163 | 164 | public static getStringLen(str: string): number { 165 | var i, len, code; 166 | if (str == null || str == "") return 0; 167 | len = str.length; 168 | for (i = 0; i < str.length; i++) { 169 | code = str.charCodeAt(i); 170 | if (code > 255) { len++; } 171 | } 172 | return len; 173 | } 174 | 175 | public static convertPlayerData(data: any): Player { 176 | var p: Player = new Player(); 177 | p.pid = data.pid; 178 | p.name = data.name; 179 | p.exp = data.exp; 180 | p.state = data.state; 181 | p.credit = data.credit; 182 | p.fish = data.fish; 183 | return p; 184 | } 185 | 186 | public static convertRoomData(data: any): Room { 187 | var r: Room = new Room(); 188 | r.id = data.id; 189 | r.roomname = data.name; 190 | r.playerCount = data.pc; 191 | r.spectatorCount = data.sc; 192 | r.password = data.pw; 193 | r.state = data.state; 194 | r.cardPacks = new Array(); 195 | if (data.cp != null && data.cp != '') { 196 | var strs = data.cp.split(","); 197 | for (var i: number = 0; i < strs.length; i++) { 198 | var id: number = strs[i]; 199 | for (var j: number = 0; j < Main.cardpacks.length; j++) { 200 | if (Main.cardpacks[j].id == id) { 201 | r.cardPacks.push(Main.cardpacks[j]); 202 | //alert(Main.cardpacks[j].name); 203 | } 204 | } 205 | } 206 | } 207 | return r; 208 | } 209 | 210 | public static safeString(text: string): string { 211 | while (text.indexOf("\"") != -1) { 212 | text = text.replace('\"', """); 213 | } 214 | while (text.indexOf("<") != -1) { 215 | text = text.replace('<', "<"); 216 | } 217 | while (text.indexOf(">") != -1) { 218 | text = text.replace('>', ">"); 219 | } 220 | while (text.indexOf("\\") != -1) { 221 | text = text.replace('\\', "\\\\"); 222 | } 223 | return text; 224 | } 225 | 226 | public static convertChat(text: string): string { 227 | if (text.match(/(https?:\/\/[\w\d%-_ /]*\.((jpg)|(png)|(bmp)|(gif)|(jpeg)))/)) 228 | text = text.replace(/(https?:\/\/[\w\d%-_ /]*\.((jpg)|(png)|(bmp)|(gif)|(jpeg)))/, ''); 229 | else if (text.match(/(https?:\/\/[\w\.\d%-_ /]+)/)) 230 | text = text.replace(/(https?:\/\/[\w\d%-_ /]+)/, '$1'); 231 | return text; 232 | } 233 | 234 | public static showMessage(text: string): void { 235 | MyEvent.call(Signal.TEXT, { text: text, pid: 0 }); 236 | } 237 | } 238 | 239 | class Server { 240 | public static instance: Server; 241 | public socket: WebSocket; 242 | 243 | private antiFlush: boolean = false; 244 | 245 | constructor() { 246 | Server.instance = this; 247 | this.socket = new WebSocket(GameSettings.Server); 248 | this.socket.onopen = (evt) => { this.onOpen(evt) }; 249 | this.socket.onclose = (evt) => { this.onClose(evt) }; 250 | this.socket.onmessage = (evt) => { this.onMessage(evt) }; 251 | this.socket.onerror = (evt) => { this.onError(evt) }; 252 | setInterval(this.flush, 300, this); 253 | } 254 | 255 | private flush(_this1: Server ): void { 256 | _this1.antiFlush = false; 257 | } 258 | 259 | /** 260 | * 成功连接到服务器事件 261 | */ 262 | onOpen(evt): void { 263 | if (GameSettings.debugMode) 264 | console.log("成功连接到服务器."); 265 | } 266 | 267 | /** 268 | * 从服务器断开事件 269 | */ 270 | onClose(evt): void { 271 | if (GameSettings.debugMode) 272 | console.log("已从服务器断开:" + evt.data); 273 | MyEvent.call('connectionclose', evt.data); 274 | } 275 | 276 | /** 277 | * 收到服务器信息事件 278 | */ 279 | onMessage(evt): void { 280 | if (GameSettings.debugMode) 281 | console.log('接收到消息: ' + evt.data); 282 | 283 | Main.unfreezeMe(); 284 | var data = MessageAnalysis.parseMessage(evt.data); 285 | switch (data.t) { 286 | case "flag": 287 | MyEvent.call(data.k); 288 | break; 289 | case "kv": 290 | MyEvent.call(data.k, data.v); 291 | break; 292 | default: 293 | MyEvent.call(data.t, data); 294 | break; 295 | } 296 | } 297 | 298 | /** 299 | * 发生错误事件 300 | */ 301 | onError(evt): void { 302 | console.log('发生错误: ' + evt.data); 303 | MyEvent.call('connectionerror', evt.data); 304 | } 305 | 306 | /** 307 | * 发送信息至服务器事件 308 | */ 309 | send(data, isVital, isUser): void { 310 | if ((this.antiFlush || Main.nextSendTime > new Date().getTime()) && isUser) { 311 | MyEvent.call("text", { pid: 0, text: "您操作太快了!" }); 312 | return; 313 | } 314 | 315 | this.antiFlush = true; 316 | if (isVital && Main.isFrozen()) { 317 | console.log('网络被堵塞'); 318 | MyEvent.call("text", { pid:0, text:"网络被堵塞,请稍后再试!"}); 319 | return; 320 | } 321 | 322 | if (GameSettings.debugMode) 323 | console.log('发送消息: ' + data); 324 | 325 | this.socket.send(data); 326 | 327 | if (isVital) 328 | Main.freezeMe(); 329 | 330 | Main.nextSendTime = new Date().getTime() + 500; 331 | } 332 | } 333 | 334 | class PackageBuilder { 335 | public static buildLoginPackage(username: string, password: string): string { 336 | username = Util.safeString(username); 337 | var pack = '{"t":"login", "username":"' + username + '", "password":"' + password + '", "ip":"' + returnCitySN["cip"] + '"}'; 338 | return pack; 339 | } 340 | 341 | public static buildTextPackage(text: string): string { 342 | //if (text.substr(0,5) == "/help") { 343 | // Util.showMessage(GameSettings.help); 344 | // return; 345 | //} 346 | 347 | text = Util.safeString(text); 348 | var pack = '{"t":"text", "text":"' + text + '"}'; 349 | return pack; 350 | } 351 | 352 | public static buildQuitPackage(): string { 353 | var pack = '{"t":"quit"}'; 354 | return pack; 355 | } 356 | 357 | public static buildCreateRoomPackage(level: number, name:string, password:string, packs:string): string { 358 | var pack = '{"t":"createroom","lv":"' + level + '","name":"' + name + '", "pw":"' + password + '","cp":"' + packs + '"}'; 359 | return pack; 360 | } 361 | 362 | public static buildSetRoomPackage(level: number, name: string, password: string, packs: string): string { 363 | var pack = '{"t":"setroom","lv":"' + level + '","name":"' + name + '", "pw":"' + password + '","cp":"' + packs + '"}'; 364 | return pack; 365 | } 366 | 367 | public static buildEnterRoomPackage(id: number): string { 368 | var pack = '{"t":"enterroom", "id":"' + id + '"}'; 369 | return pack; 370 | } 371 | 372 | public static buildReturnLobbyPackage(): string { 373 | var pack = '{"t":"returnlobby"}'; 374 | return pack; 375 | } 376 | 377 | public static buildSwitchPlacePackage(place: number): string { 378 | var pack = '{"t":"switch", "place":"' + place + '"}'; 379 | return pack; 380 | } 381 | 382 | public static buildCreateCardPackage(cardType: number, cardPack: number, text: string): string { 383 | text = Util.safeString(text); 384 | var pack = '{"t":"createcard", "cardType":"' + cardType + '", "cardPack":"' + cardPack + '", "text":"' + text + '"}'; 385 | return pack; 386 | } 387 | 388 | public static buildCreateSugPackage(text: string): string { 389 | text = Util.safeString(text); 390 | var pack = '{"t":"sug", "text":"' + text + '"}'; 391 | return pack; 392 | } 393 | 394 | public static buildSendPendPackage(approve: string, reject: string) { 395 | var pack = '{"t":"pendover", "ap":"' + approve + '", "re":"' + reject + '"}'; 396 | return pack; 397 | } 398 | } 399 | 400 | class MessageAnalysis { 401 | public static parseMessage(data): any { 402 | return JSON.parse(data); 403 | } 404 | } 405 | 406 | enum State { 407 | CONNECTING, 408 | CONNECTED, 409 | LOBBY, 410 | PLAYING 411 | } 412 | 413 | class Signal { 414 | public static ServerInfo: string = "serverinfo"; 415 | public static OnClickLogin: string = "OnClickLogin"; 416 | public static LoginErr: string = "logerr"; 417 | public static MyInfo: string = "myinfo"; 418 | public static LobbyInfo: string = "lobbyinfo"; 419 | public static PLAYERENTER: string = "playerenter"; 420 | public static PLAYERLEAVE: string = "playerleave"; 421 | public static TEXT: string = "text"; 422 | public static SendText: string = "sendtext"; 423 | public static RoomInfo: string = "roominfo"; 424 | public static ONCLICKCREATEROOM: string = "ONCLICKCREATEROOM"; 425 | public static ONCLICKROOM: string = "ONCLICKROOM"; 426 | public static INFO: string = "info"; 427 | public static DESTROYROOM: string = "destroyroom"; 428 | public static ADDROOM: string = "addroom"; 429 | public static OnClickLeave: string = "returnlobby"; 430 | public static OnClickSwitchButton: string = "switchplace"; 431 | public static OnPlayerSwitch: string = "onswitch"; 432 | public static OnClickCloseSettings: string = "OnClickCloseSettings"; 433 | public static OnClickCreateCard: string = "OnClickCreateCard"; 434 | public static OnClickSendCard: string = "OnClickSendCard"; 435 | public static OnClickSendSug: string = "OnClickSendSug"; 436 | public static OnClickSendPend: string = "OnClickSendPend"; 437 | public static OnSendCardCallback: string = "cardsended"; 438 | public static PEND: string = "pend"; 439 | public static HOST: string = "host"; 440 | public static UNHOST: string = "unhost"; 441 | public static OnClickRoomSetButton: string = "OnClickRoomSetButton"; 442 | public static OnClickRoomSetButtonOK: string = "OnClickRoomSetButtonOK"; 443 | public static KickPlayer: string = "KickPlayer"; 444 | } 445 | 446 | class Main { 447 | public static cardpacks: Array; 448 | 449 | public static nextSendTime: number; 450 | 451 | public static server: Server; 452 | public static state: State; 453 | public static me: Player; 454 | public static isHost: boolean = false; 455 | public static currentRoom: Room; 456 | 457 | public static loginState: LoginState; 458 | public static lobbyState: LobbyState; 459 | public static playState: PlayState; 460 | 461 | private static freeze: boolean = false; 462 | public static isFrozen(): boolean { 463 | return Main.freeze; 464 | } 465 | 466 | public static freezeMe(): void { 467 | Main.freeze = true; 468 | } 469 | 470 | public static unfreezeMe(): void { 471 | Main.freeze = false; 472 | } 473 | 474 | public start(): void { 475 | Main.me = new Player(); 476 | Main.loginState = new LoginState(); 477 | Main.lobbyState = new LobbyState(); 478 | Main.playState = new PlayState(); 479 | Main.loginState.start(); 480 | 481 | MyEvent.bind(Signal.PEND, this.onReceivePendInfo, this); 482 | MyEvent.bind(Signal.INFO, this.onReceiveInfo, this); 483 | MyEvent.bind("uc", function (data: any, _this: Main) { Util.showMessage("未知命令!") }, this); 484 | MyEvent.bind("nc", function (data: any, _this: Main) { Util.showMessage("您没有权限使用此命令!") }, this); 485 | MyEvent.bind("ban", function (data: any, _this: Main) { alert("您已被服务器Ban了!"); location.reload(true); }, this); 486 | MyEvent.bind("kick", function (data: any, _this: Main) { alert("您已被请出游戏!"); location.reload(true); }, this); 487 | MyEvent.bind("quit", function (data: any, _this: Main) { alert("服务器更新!"); location.reload(true); }, this); 488 | MyEvent.bind(Signal.MyInfo, this.onUpdateMyInfo, this); 489 | this.bindLocalEvent(); 490 | } 491 | 492 | private bindLocalEvent(): void { 493 | MyEvent.bind(Signal.OnClickCloseSettings, Main.OnClickCloseSettings, this); 494 | MyEvent.bind(Signal.OnClickSendPend, Main.OnClickSendPend, this); 495 | jQuery(".settingsPage .title .closeButton").tapOrClick(function () { MyEvent.call(Signal.OnClickCloseSettings) }); 496 | 497 | jQuery('#lobbyPage #inputArea #inputbox').keypress(function (event) { 498 | var keycode = (event.keyCode ? event.keyCode : event.which); 499 | if (keycode == '13') { 500 | MyEvent.call(Signal.SendText); 501 | } 502 | }); 503 | jQuery('#lobbyPage #inputArea #submit').tapOrClick(function (event) { 504 | MyEvent.call(Signal.SendText); 505 | }); 506 | jQuery('#settingsArea #createRoom').tapOrClick(function (event) { 507 | jQuery("#createroom #roomtitle").val(Main.me.name + "的房间"); 508 | jQuery("#createroom #roompassword").val(""); 509 | jQuery("#createroom #cardpacks").empty(); 510 | for (var i = 0; i < Main.cardpacks.length; i++) { 511 | if (Main.me.getLevel() >= Main.cardpacks[i].level) 512 | jQuery("#createroom #cardpacks").append('
'); 513 | else 514 | jQuery("#createroom #cardpacks").append('
'); 515 | } 516 | 517 | 518 | jQuery(".settingsPage[id=createroom]").show(0); 519 | jQuery("#wrapper").addClass("mask"); 520 | jQuery("#mask").show(); 521 | }); 522 | 523 | jQuery("#settingsArea #createCard").tapOrClick(function () { 524 | jQuery(".settingsPage[id=createcard]").show(0); 525 | jQuery("#wrapper").addClass("mask"); 526 | jQuery("#mask").show(); 527 | jQuery("#createcard #cardpack").empty(); 528 | for (var i: number = 0; i < Main.cardpacks.length; i++) { 529 | var cardPack: CardPack = Main.cardpacks[i]; 530 | if (i == 0) 531 | jQuery("#createcard #cardpack").append(''); 532 | else 533 | jQuery("#createcard #cardpack").append(''); 534 | } 535 | }); 536 | 537 | jQuery("#settingsArea #suggest").tapOrClick(function () { 538 | jQuery(".settingsPage[id=sug]").show(0); 539 | jQuery("#wrapper").addClass("mask"); 540 | jQuery("#mask").show(); 541 | }); 542 | 543 | jQuery("#setroom #submit").tapOrClick(function () { 544 | MyEvent.call(Signal.OnClickRoomSetButtonOK); 545 | }); 546 | 547 | jQuery("#gamePage #settings").tapOrClick(function () { 548 | MyEvent.call(Signal.OnClickRoomSetButton); 549 | }); 550 | 551 | jQuery("#createcard #submit").tapOrClick(function () { MyEvent.call(Signal.OnClickSendCard) }); 552 | jQuery('#createroom #submit').tapOrClick(function (event) { 553 | MyEvent.call(Signal.ONCLICKCREATEROOM); 554 | }); 555 | jQuery("#sug #submit").tapOrClick(function () { MyEvent.call(Signal.OnClickSendSug) }); 556 | jQuery("#pend #submit").tapOrClick(function () { MyEvent.call(Signal.OnClickSendPend) }); 557 | 558 | jQuery('#gamePage #inputArea #inputbox').keypress(function (event) { 559 | var keycode = (event.keyCode ? event.keyCode : event.which); 560 | if (keycode == '13') { 561 | MyEvent.call(Signal.SendText); 562 | } 563 | }); 564 | jQuery('#gamePage #inputArea #submit').tapOrClick(function (event) { 565 | MyEvent.call(Signal.SendText); 566 | }); 567 | jQuery('#gamePage #leave').tapOrClick(function (event) { 568 | MyEvent.call(Signal.OnClickLeave); 569 | }); 570 | jQuery('#gamePage #spectate').tapOrClick(function (event) { 571 | MyEvent.call(Signal.OnClickSwitchButton); 572 | }); 573 | } 574 | 575 | public static sayByVoiceCard(text: string): void { 576 | text = text.replace(new RegExp("(https?://[\w\.\d%-_/]+)"), "和谐"); 577 | text = text.replace(new RegExp("((<.*>.*<.*/*.*>)|(<.*/*.*>))"), "和谐"); 578 | 579 | var audio: any = document.getElementById("cardaudio"); 580 | audio.src = 'http://tts.baidu.com/text2audio?lan=zh&pid=101&ie=UTF-8&text=' + encodeURI(text) + '&spd=6'; 581 | audio.play(); 582 | } 583 | 584 | public static sayByVoicePlayer(text: string): void { 585 | text = text.replace(new RegExp("(https?://[\w\.\d%-_/]+)"), "和谐"); 586 | text = text.replace(new RegExp("((<.*>.*<.*/*.*>)|(<.*/*.*>))"), "和谐"); 587 | 588 | var audio: any = document.getElementById("playeraudio"); 589 | audio.src = 'http://tts.baidu.com/text2audio?lan=zh&pid=101&ie=UTF-8&text=' + encodeURI(text) + '&spd=6'; 590 | audio.play(); 591 | } 592 | 593 | public static OnClickCloseSettings(data: any, _this: Main): void { 594 | jQuery(".settingsPage").hide(); 595 | jQuery("#wrapper").removeClass("mask"); 596 | jQuery("#mask").hide(); 597 | } 598 | 599 | public static OnClickSendPend(data: any, _this: Main): void { 600 | var approve: string = ''; 601 | var reject: string = ''; 602 | jQuery('#pend input:checkbox:checked').each(function (i) { 603 | if (0 == i) { 604 | approve = jQuery(this).val(); 605 | } else { 606 | approve += ("," + jQuery(this).val()); 607 | } 608 | }); 609 | 610 | jQuery('#pend input:checkbox').not("input:checked").each(function (i) { 611 | if (0 == i) { 612 | reject = jQuery(this).val(); 613 | } else { 614 | reject += ("," + jQuery(this).val()); 615 | } 616 | }); 617 | 618 | Server.instance.send(PackageBuilder.buildSendPendPackage(approve, reject), false, true); 619 | jQuery(".settingsPage").hide(); 620 | jQuery("#wrapper").removeClass("mask"); 621 | jQuery("#mask").hide(); 622 | } 623 | 624 | private onReceiveInfo(data: any, _this: Main) { 625 | switch (data.k) { 626 | case "cp": 627 | Main.cardpacks = new Array(); 628 | for (var i: number = 0; i < data.cp.length; i++) { 629 | var cp: CardPack = new CardPack(); 630 | cp.id = data.cp[i].id; 631 | cp.name = data.cp[i].name; 632 | cp.level = data.cp[i].lv; 633 | cp.blackcount = data.cp[i].bc; 634 | cp.whitecount = data.cp[i].wc; 635 | Main.cardpacks.push(cp); 636 | } 637 | break; 638 | } 639 | } 640 | 641 | public static getPackName(pid: number): string { 642 | var name: string = '未知'; 643 | 644 | for (var i: number = 0; i < Main.cardpacks.length; i++) { 645 | var cardPack: CardPack = Main.cardpacks[i]; 646 | name = cardPack.name; 647 | } 648 | 649 | return name; 650 | } 651 | 652 | private onReceivePendInfo(data: any, _this: Main) { 653 | var datas: any = data.c; 654 | jQuery(".settingsPage[id=pend] #table").empty(); 655 | jQuery(".settingsPage[id=pend]").show(0); 656 | jQuery("#wrapper").addClass("mask"); 657 | jQuery("#mask").show(); 658 | jQuery(".settingsPage[id=pend] #table").append('通过作者类型卡包内容'); 659 | 660 | for (var i: number = 0; i < datas.length; i++) { 661 | var card: any = datas[i]; 662 | jQuery(".settingsPage[id=pend] #table").append('' + card.pl + '' + (card.ty == 0 ? "黑卡" : "白卡") + '' + Main.getPackName(card.cp) + '' + card.te + ''); 663 | } 664 | } 665 | 666 | public onUpdateMyInfo(data: any, _this: Main): void { 667 | Main.me = Util.convertPlayerData(data.info[0]); 668 | 669 | var level: number = Main.me.getLevel(); 670 | var remainExp: number = Main.me.getRemainExp(); 671 | var needExp: number = Main.me.getNeedExp(); 672 | 673 | jQuery("#statArea #nameTag").html(Main.me.name); 674 | jQuery("#statArea #nameTag").attr("title", "pid:" + Main.me.pid); 675 | jQuery("#statArea #level").html("Lv." + level); 676 | jQuery("#statArea #levelBarExp").html(remainExp + "/" + needExp); 677 | jQuery("#statArea #credit #content").html(Main.me.credit); 678 | jQuery("#statArea #fish #content").html(Main.me.fish); 679 | jQuery("#statArea #levelBarBack").css("width", (remainExp / needExp * 100) + "%"); 680 | } 681 | 682 | 683 | } 684 | 685 | class LoginState { 686 | private ass: string = "ass"; 687 | private loginable: boolean = false; 688 | public start(): void { 689 | Main.server = new Server(); 690 | Main.state = State.CONNECTING; 691 | this.showLoginPage(); 692 | } 693 | 694 | public bindEvents(): void { 695 | MyEvent.bind(Signal.ServerInfo, this.onCanLogin, this); 696 | MyEvent.bind(Signal.OnClickLogin, this.onLogin, this); 697 | MyEvent.bind(Signal.LoginErr, this.onLoginErr, this); 698 | MyEvent.bind(Signal.LobbyInfo, this.onShowLobbyInfo, this); 699 | jQuery(".loginArea #submit").tapOrClick(this.onClickLogin); 700 | } 701 | 702 | public unbindEvents(): void { 703 | MyEvent.unbind(Signal.ServerInfo, this.onCanLogin); 704 | MyEvent.unbind(Signal.OnClickLogin, this.onLogin); 705 | MyEvent.unbind(Signal.LoginErr, this.onLoginErr); 706 | MyEvent.unbind(Signal.LobbyInfo, this.onShowLobbyInfo); 707 | } 708 | 709 | public showLoginPage(): void { 710 | this.bindEvents(); 711 | jQuery("#loginPage").show(); 712 | LoginState.setLoginTip("正在连接服务器..."); 713 | this.activateLoginArea(false); 714 | } 715 | 716 | public static setLoginTip(tip: string): void { 717 | jQuery("#logintip").html(tip); 718 | } 719 | 720 | public activateLoginArea(activate: boolean): void { 721 | if (activate) { 722 | jQuery("#username").attr("disabled", false); 723 | jQuery("#password").attr("disabled", false); 724 | } else { 725 | jQuery("#username").attr("disabled", true); 726 | jQuery("#password").attr("disabled", true); 727 | } 728 | } 729 | 730 | public onCanLogin(data: any, thisObject: LoginState): void { 731 | Main.state = State.CONNECTED; 732 | var par = parseInt(data.players) / parseInt(data.max) * 100; 733 | jQuery("#onlineBar").css("width", par + "%"); 734 | jQuery("#serverinfo").html(data.players + "/" + data.max); 735 | if (parseInt(data.players) < parseInt(data.max)) { 736 | LoginState.setLoginTip("请登录,如果该用户名没有注册过,则将自动为您注册(每个IP最多只能注册5个账号)。"); 737 | thisObject.activateLoginArea(true); 738 | thisObject.loginable = true; 739 | } 740 | } 741 | 742 | public onClickLogin(): void { 743 | MyEvent.call(Signal.OnClickLogin); 744 | } 745 | 746 | public onLogin(data: any, thisObject: LoginState): void { 747 | if (!thisObject.loginable) return; 748 | var $username: any = document.getElementById("username"); 749 | var $password: any = document.getElementById("password"); 750 | var username: string = $username.value.trim(); 751 | var password: string = $password.value.trim(); 752 | 753 | if (Util.getStringLen(username) < 2) { 754 | LoginState.setLoginTip('您的用户名太短!请至少超过6cm2个字符!'); 755 | return; 756 | } else if (Util.getStringLen(username) > 20) { 757 | LoginState.setLoginTip('您的用户名太长!请确保用户名小于20个字符(中文算2个)'); 758 | return; 759 | } else if (password.length < 4) { 760 | LoginState.setLoginTip('您的密码太短!请至少超过4个字符!'); 761 | return; 762 | } else if (password.length > 20) { 763 | LoginState.setLoginTip('您的密码太长!'); 764 | return; 765 | } else if (!LoginState.isUsernameLegal(username)) { 766 | LoginState.setLoginTip('您的用户名不合法!'); 767 | return; 768 | } 769 | 770 | thisObject.sendLogin(username, password ); 771 | } 772 | 773 | public sendLogin(username: string, password: string): void { 774 | if (Main.state != State.CONNECTED) return; 775 | LoginState.setLoginTip('正在登录...'); 776 | Server.instance.send(PackageBuilder.buildLoginPackage(username, password), true, true); 777 | } 778 | 779 | public static isUsernameLegal(name: string): boolean { 780 | return true; 781 | } 782 | 783 | private onLoginErr(data: any, _this: LoginState): void{ 784 | if (data == 101) { 785 | LoginState.setLoginTip('您的输入似乎有问题……'); 786 | } else if (data == 102) { 787 | LoginState.setLoginTip('该用户已被注册且您的密码输入错误。或您的注册已达上限!'); 788 | } else if (data == 103) { 789 | LoginState.setLoginTip('无法登录,该用户已经在线了!'); 790 | } else if (data == 104) { 791 | LoginState.setLoginTip('无法登录,该账号已被封禁!'); 792 | } else if (data == 105) { 793 | LoginState.setLoginTip('无法登录,服务器已满!'); 794 | } 795 | } 796 | 797 | private onShowLobbyInfo(data: any, thisObject: LoginState): void { 798 | jQuery("#loginPage").hide(); 799 | Main.lobbyState.showLobbyPage(data); 800 | thisObject.unbindEvents(); 801 | } 802 | } 803 | 804 | class LobbyState { 805 | private players: Array; 806 | private rooms: Array; 807 | private canCreateRoom: boolean = false; 808 | private canEnterRoom: boolean = false; 809 | 810 | public constructor() { 811 | 812 | } 813 | 814 | public getPlayerByPid(pid: number): Player { 815 | var p: Player = null; 816 | for (var i = 0; i < this.players.length; i++) { 817 | if (this.players[i].pid == pid) { 818 | p = this.players[i]; 819 | break; 820 | } 821 | } 822 | return p; 823 | } 824 | 825 | public clearLobbyPage(): void { 826 | jQuery("#roomArea").empty(); 827 | jQuery("#chatArea #messages").empty(); 828 | jQuery("#playersArea").empty(); 829 | } 830 | 831 | public showLobbyPage(data: any): void { 832 | this.clearLobbyPage(); 833 | this.bindEvents(); 834 | jQuery("#lobbyPage").show(); 835 | this.clearChatArea(); 836 | this.canCreateRoom = true; 837 | this.canEnterRoom = true; 838 | this.getLobbyInfo(data); 839 | } 840 | 841 | public returnToLobbyPage(data: any): void { 842 | this.clearLobbyPage(); 843 | this.bindEvents(); 844 | jQuery("#lobbyPage").show(); 845 | this.clearChatArea(); 846 | this.canCreateRoom = true; 847 | this.canEnterRoom = true; 848 | this.getLobbyInfo(data); 849 | Main.isHost = false; 850 | } 851 | 852 | private bindEvents(): void { 853 | MyEvent.bind(Signal.PLAYERENTER, this.onPlayerEnter, this); 854 | MyEvent.bind(Signal.PLAYERLEAVE, this.onPlayerLeave, this); 855 | MyEvent.bind(Signal.TEXT, this.onReceiveText, this); 856 | MyEvent.bind(Signal.SendText, this.onSendText, this); 857 | MyEvent.bind(Signal.ONCLICKCREATEROOM, this.onClickCreateRoomConfirm, this); 858 | MyEvent.bind(Signal.RoomInfo, this.onReceiveRoomInfo, this); 859 | MyEvent.bind(Signal.DESTROYROOM, this.onDestroyRoom, this); 860 | MyEvent.bind(Signal.ADDROOM, this.onAddRoom, this); 861 | MyEvent.bind(Signal.ONCLICKROOM, this.onClickRoom, this); 862 | MyEvent.bind(Signal.OnClickSendCard, this.OnClickSendCard, this); 863 | MyEvent.bind(Signal.OnClickSendSug, this.OnClickSendSug, this); 864 | MyEvent.bind(Signal.OnSendCardCallback, this.onCardSended, this); 865 | MyEvent.bind("sri", this.onRoomChange, this); 866 | } 867 | 868 | private unbindEvents(): void { 869 | MyEvent.unbindAll(Signal.PLAYERENTER, this.onPlayerEnter); 870 | MyEvent.unbindAll(Signal.PLAYERLEAVE, this.onPlayerLeave); 871 | MyEvent.unbindAll(Signal.TEXT, this.onReceiveText); 872 | MyEvent.unbindAll(Signal.SendText, this.onSendText); 873 | MyEvent.unbindAll(Signal.ONCLICKCREATEROOM, this.onClickCreateRoomConfirm); 874 | MyEvent.unbindAll(Signal.RoomInfo, this.onReceiveRoomInfo); 875 | MyEvent.unbindAll(Signal.DESTROYROOM, this.onDestroyRoom); 876 | MyEvent.unbindAll(Signal.ADDROOM, this.onAddRoom); 877 | MyEvent.unbindAll(Signal.ONCLICKROOM, this.onClickRoom); 878 | MyEvent.unbindAll(Signal.OnClickSendCard, this.OnClickSendCard); 879 | MyEvent.unbindAll(Signal.OnClickSendSug, this.OnClickSendSug); 880 | MyEvent.unbindAll(Signal.OnSendCardCallback, this.onCardSended); 881 | MyEvent.unbindAll("sri", this.onRoomChange); 882 | } 883 | 884 | public onRoomChange(data: any, _this: LobbyState) { 885 | 886 | 887 | 888 | var room: Room = Util.convertRoomData(data); 889 | for (var i: number = 0; i < _this.rooms.length; i++) { 890 | if (_this.rooms[i] != null) { 891 | if (_this.rooms[i].id == room.id) { 892 | _this.rooms[i] = room; 893 | break; 894 | } 895 | } 896 | } 897 | 898 | var state = (room.state == 0 ? "等待中" : "游戏中"); 899 | if (room.password != null && room.password != "") { 900 | state += ",有密码"; 901 | } 902 | 903 | var cp: string = ""; 904 | for (var i: number = 0; i < room.cardPacks.length; i++) { 905 | cp = cp + '
' + room.cardPacks[i].name + '
'; 906 | } 907 | 908 | jQuery("#lobbyPage #roomArea .room[id=" + room.id + "] #desc").html(room.roomname); 909 | jQuery("#lobbyPage #roomArea .room[id=" + room.id + "] #players").html('玩家:' + room.playerCount + '/8'); 910 | jQuery("#lobbyPage #roomArea .room[id=" + room.id + "] #spectors").html('观众:' + room.spectatorCount + '/16'); 911 | jQuery("#lobbyPage #roomArea .room[id=" + room.id + "] #stat").html(state); 912 | jQuery("#lobbyPage #roomArea .room[id=" + room.id + "] #packsArea").html(cp); 913 | } 914 | 915 | public onSendText(): void { 916 | var $text: any = jQuery("#lobbyPage #inputArea #inputbox")[0]; 917 | var text: string = $text.value.trim(); 918 | if (text == null || text.length == 0 || text.length > 200) return; 919 | Server.instance.send(PackageBuilder.buildTextPackage(text), true, true); 920 | $text.value = ""; 921 | } 922 | 923 | private onClickCreateRoomConfirm(data: any, _this:LobbyState): void { 924 | if (!_this.canCreateRoom) { 925 | Util.showMessage("您现在不能创建房间!"); 926 | return; 927 | } 928 | 929 | 930 | var name: string = jQuery("#createroom #roomtitle").val(); 931 | var password: string = jQuery("#createroom #roompassword").val(); 932 | var packs: string = ""; 933 | 934 | var spCodesTemp: string = ""; 935 | jQuery('#createroom input:checkbox[name=cp]:checked').each(function (i) { 936 | if (0 == i) { 937 | spCodesTemp = jQuery(this).val(); 938 | } else { 939 | spCodesTemp += ("," + jQuery(this).val()); 940 | } 941 | }); 942 | Server.instance.send(PackageBuilder.buildCreateRoomPackage(Main.me.getLevel(), name, password, spCodesTemp), true, true); 943 | _this.canCreateRoom = false; 944 | jQuery(".settingsPage[id=createroom]").hide(0); 945 | jQuery("#wrapper").removeClass("mask"); 946 | jQuery("#mask").hide(); 947 | } 948 | 949 | public getLobbyInfo(data: any): void { 950 | this.players = new Array(); 951 | Main.state = State.LOBBY; 952 | for (var i = 0; i < data.players.length; i++) { 953 | this.addOnePlayer(Util.convertPlayerData(data.players[i])); 954 | } 955 | this.updatePlayerList(); 956 | 957 | this.rooms = new Array(); 958 | for (var i = 0; i < data.rooms.length; i++) { 959 | this.addOneRoom(Util.convertRoomData(data.rooms[i])); 960 | } 961 | } 962 | 963 | public onReceiveText(data: any, _this: LobbyState): void { 964 | var pid: any = parseInt(data.pid); 965 | var speakerName: string = "Unknow"; 966 | if (isNaN(data.pid)) { 967 | speakerName = data.pid; 968 | } else if (pid == 0) { 969 | speakerName = "系统"; 970 | } else { 971 | var p: Player = _this.getPlayerByPid(pid); 972 | if (p != null) 973 | speakerName = p.name; 974 | } 975 | 976 | var text: string = data.text; 977 | 978 | text = Util.convertChat(text); 979 | 980 | if (pid == 0) 981 | jQuery("#chatArea #messages").append('
'); 982 | else 983 | jQuery("#chatArea #messages").append('
'); 984 | 985 | jQuery("#chatArea #messages")[0].scrollTop = jQuery("#chatArea #messages")[0].scrollHeight; 986 | } 987 | 988 | public clearChatArea(): void { 989 | jQuery("#chatArea #messages").empty(); 990 | } 991 | 992 | public onClickRoom(data: any, _this: LobbyState) { 993 | if (!_this.canEnterRoom) { 994 | Util.showMessage("您现在不能进入房间!"); 995 | return; 996 | } 997 | 998 | var room: Room = null; 999 | for (var i: number = 0; i < _this.rooms.length; i++) { 1000 | if (_this.rooms[i].id == data) { 1001 | room = _this.rooms[i]; 1002 | } 1003 | } 1004 | 1005 | if (room == null) { 1006 | Util.showMessage("房间不存在!"); 1007 | return; 1008 | } 1009 | 1010 | if (room.password != null && room.password != "") { 1011 | var password:string = prompt("请输入房间密码", ""); 1012 | if (password != room.password) { 1013 | Util.showMessage("密码错误"); 1014 | return; 1015 | } 1016 | } 1017 | 1018 | if (room.playerCount < 8 || room.spectatorCount < 16) { 1019 | this.canEnterRoom = false; 1020 | Server.instance.send(PackageBuilder.buildEnterRoomPackage(data), true, true); 1021 | } else { 1022 | Util.showMessage("该房间已满!"); 1023 | } 1024 | } 1025 | 1026 | public onPlayerEnter(data: any, _this: LobbyState): void{ 1027 | var p: Player = Util.convertPlayerData(data.player[0]); 1028 | MyEvent.call(Signal.TEXT, {text:p.name + " 进入了大厅", pid:0}); 1029 | if (data.player[0].pid == Main.me.pid) 1030 | return; 1031 | _this.addOnePlayer(p); 1032 | } 1033 | 1034 | public onPlayerLeave(data: any, _this: LobbyState): void { 1035 | var p: Player = _this.getPlayerByPid(data.pid); 1036 | if (p != null) { 1037 | MyEvent.call(Signal.TEXT, { text: p.name + " 离开了大厅", pid: 0 }); 1038 | _this.removeOnePlayer(p.pid); 1039 | } 1040 | } 1041 | 1042 | public onAddRoom(data: any, _this: LobbyState): void { 1043 | var room: Room = Util.convertRoomData(data.room[0]); 1044 | _this.addOneRoom(room); 1045 | } 1046 | 1047 | public addOnePlayer(player: Player): void { 1048 | this.players.push(player); 1049 | this.updatePlayerList(); 1050 | } 1051 | 1052 | public removeOnePlayer(pid: number): void { 1053 | var index:number = -1; 1054 | for (var i = 0; i < this.players.length; i++) { 1055 | if (this.players[i].pid == pid) { 1056 | index = i; 1057 | break; 1058 | } 1059 | } 1060 | 1061 | if (index != -1) { 1062 | this.players.splice(index, 1); 1063 | this.updatePlayerList(); 1064 | } 1065 | } 1066 | 1067 | public onDestroyRoom(data: any, _this: LobbyState): void { 1068 | _this.removeOneRoom(data); 1069 | } 1070 | 1071 | public addOneRoom(room: Room): void { 1072 | var state = room.state == 0 ? "等待中" : "游戏中"; 1073 | if (room.password != null && room.password != "") { 1074 | state += ",有密码"; 1075 | } 1076 | var cp: string = ""; 1077 | for (var i: number = 0; i < room.cardPacks.length; i++) { 1078 | cp = cp + '
' + room.cardPacks[i].name + '
'; 1079 | } 1080 | jQuery("#lobbyPage #roomArea").append('
' + (room.id < 10 ? '00' : (room.id < 100 ? '0' : '')) + room.id + '
' + room.roomname + '
玩家:' + room.playerCount + '/8
观众:' + room.spectatorCount + '/16
' + state + '
' + cp + '
'); 1081 | jQuery("#lobbyPage .room[id=" + room.id + "]").tapOrClick(function () { MyEvent.call(Signal.ONCLICKROOM, room.id) }); 1082 | this.rooms.push(room); 1083 | } 1084 | 1085 | public removeOneRoom(id: number): void { 1086 | jQuery("#lobbyPage #roomArea .room[id=" + id + "]").remove(); 1087 | for (var i: number = 0; i < this.rooms.length; i++) { 1088 | if (this.rooms[i].id == id) { 1089 | this.rooms.splice(i, 1); 1090 | break; 1091 | } 1092 | } 1093 | } 1094 | 1095 | public updatePlayerList(): void { 1096 | var ele: any = jQuery("#lobbyPage #playersArea"); 1097 | ele.empty(); 1098 | for (var i = 0; i < this.players.length; i++) { 1099 | ele.append('
Lv.' + this.players[i].getLevel() + '' + this.players[i].name + '
'); 1100 | } 1101 | } 1102 | 1103 | public onReceiveRoomInfo(data: any, _this: LobbyState): void { 1104 | jQuery("#lobbyPage").hide(); 1105 | Main.playState.showGamePage(data); 1106 | _this.unbindEvents(); 1107 | } 1108 | 1109 | public OnClickSendSug(data: any, _this: LobbyState): void { 1110 | var time = new Date().getTime(); 1111 | if (time < parseInt(localStorage["lastSendTime"])) { 1112 | Util.showMessage("技能冷却中,剩余时间:" + Math.round((parseInt(localStorage["lastSendTime"]) - time) / 1000) + "秒"); 1113 | Main.OnClickCloseSettings(null, null); 1114 | return; 1115 | } 1116 | var text: string = jQuery("#sug #text").val(); 1117 | 1118 | if (text == null || text.trim().length < 0) { 1119 | alert("文字内容不能为空!"); 1120 | return 1121 | } 1122 | 1123 | Server.instance.send(PackageBuilder.buildCreateSugPackage(text), false, true); 1124 | localStorage["lastSendTime"] = new Date().getTime() + 60000; 1125 | Main.OnClickCloseSettings(null, null); 1126 | jQuery("#sug #text").val(""); 1127 | Util.showMessage("您的意见已送出,感谢您的支持!"); 1128 | } 1129 | 1130 | public OnClickSendCard(data: any, _this: LobbyState): void { 1131 | var time = new Date().getTime(); 1132 | if (time < parseInt(localStorage["lastSendTime"])) { 1133 | Util.showMessage("技能冷却中,剩余时间:" + Math.round((parseInt(localStorage["lastSendTime"]) - time) / 1000) + "秒"); 1134 | Main.OnClickCloseSettings(null, null); 1135 | return; 1136 | } 1137 | 1138 | var cardType: number = jQuery('#createcard input[name="cardtype"]:checked').val(); 1139 | var cardPack: number = jQuery("#createcard #cardpack option:selected").val(); 1140 | var text: string = jQuery("#createcard #text").val(); 1141 | 1142 | if (cardPack == 1 && Main.me.pid != 1) { 1143 | Util.showMessage("您没有权限向此卡牌包添加卡牌,请选择其他卡牌包!"); 1144 | Main.OnClickCloseSettings(null, null); 1145 | return; 1146 | } 1147 | 1148 | if (text == null || text.trim().length < 0) { 1149 | alert("卡牌内容不能为空!"); 1150 | return 1151 | } 1152 | 1153 | Server.instance.send(PackageBuilder.buildCreateCardPackage(cardType, cardPack, text), true, true); 1154 | localStorage["lastSendTime"] = new Date().getTime() + 60000; 1155 | Main.OnClickCloseSettings(null, null); 1156 | jQuery("#createcard #text").val(""); 1157 | } 1158 | 1159 | public onCardSended(data: any, _this: LobbyState): void { 1160 | var total: number = data.to; 1161 | var success: number = data.su; 1162 | var repeat: number = data.re; 1163 | var illegal: number = data.il; 1164 | 1165 | if (total == 0) { 1166 | Util.showMessage("您的填写有误,此次提交作废!"); 1167 | } else if (success == 0) { 1168 | Util.showMessage("您的卡牌提交失败,总数:" + total + ",成功:" + success + ",重复:" + repeat + ",失败:" + illegal + "。"); 1169 | } else { 1170 | Util.showMessage("您的卡牌已提交审核,总数:" + total + ",成功:" + success + ",重复:" + repeat + ",失败:" + illegal + ",感谢您的支持!"); 1171 | } 1172 | } 1173 | } 1174 | 1175 | class PlayState{ 1176 | private isPlayer: boolean = false; 1177 | private players: Array; 1178 | private spectators: Array; 1179 | private canReturnToLobby: boolean = false; 1180 | private gameState: number 1181 | 1182 | public constructor() { 1183 | this.players = new Array(); 1184 | this.spectators = new Array(); 1185 | } 1186 | 1187 | public showGamePage(data: any): void { 1188 | this.players = new Array(); 1189 | this.spectators = new Array(); 1190 | this.canReturnToLobby = true; 1191 | this.bindEvents(); 1192 | this.clearGamePage(); 1193 | jQuery("#gamePage").show(); 1194 | this.showBlackCardArea(); 1195 | this.initRoomInfo(data); 1196 | this.updateMyInfoDisplay(); 1197 | 1198 | //jQuery(".settingsPage[id=gamestart]").show(); 1199 | } 1200 | 1201 | private initRoomInfo(data: any): void { 1202 | jQuery("#gamePage #roomnum").html(data.id); 1203 | jQuery("#gamePage #roomname").html(data.name); 1204 | 1205 | Main.currentRoom = Util.convertRoomData(data); 1206 | 1207 | for (var i: number = 0; i < data.players.length; i++) { 1208 | var p: Player = Util.convertPlayerData(data.players[i]); 1209 | this.addOnePlayer(p, false); 1210 | if (p.pid == Main.me.pid) 1211 | this.isPlayer = true; 1212 | } 1213 | 1214 | for (var i: number = 0; i < data.spectators.length; i++) { 1215 | var p: Player = Util.convertPlayerData(data.spectators[i]); 1216 | this.addOnePlayer(p, true); 1217 | if (p.pid == Main.me.pid) 1218 | this.isPlayer = false; 1219 | } 1220 | 1221 | if (this.isPlayer) 1222 | jQuery("#settingsArea #spectate").html("观战"); 1223 | else 1224 | jQuery("#settingsArea #spectate").html("加入"); 1225 | } 1226 | 1227 | private bindEvents(): void { 1228 | MyEvent.bind(Signal.PLAYERENTER, this.onPlayerEnter, this); 1229 | MyEvent.bind(Signal.PLAYERLEAVE, this.onPlayerLeave, this); 1230 | MyEvent.bind(Signal.TEXT, this.onReceiveText, this); 1231 | MyEvent.bind(Signal.SendText, this.onSendText, this); 1232 | MyEvent.bind(Signal.OnClickLeave, this.onClickReturnLobby, this); 1233 | MyEvent.bind(Signal.LobbyInfo, this.onReturnToLobby, this); 1234 | MyEvent.bind(Signal.OnClickSwitchButton, this.onClickSwitchButton, this); 1235 | MyEvent.bind(Signal.OnPlayerSwitch, this.onPlayerSwitch, this); 1236 | MyEvent.bind(Signal.OnClickRoomSetButton, this.onClickRoomSetButton, this); 1237 | MyEvent.bind(Signal.OnClickRoomSetButtonOK, this.onClickRoomSetButtonOK, this); 1238 | MyEvent.bind(Signal.HOST, this.setMeAsHost, this); 1239 | MyEvent.bind(Signal.UNHOST, this.setMeAsNotHost, this); 1240 | MyEvent.bind("sri", this.onRoomChange, this); 1241 | MyEvent.bind(Signal.KickPlayer, this.onKickPlayer, this); 1242 | } 1243 | 1244 | private unbindEvents(): void { 1245 | MyEvent.unbind(Signal.PLAYERENTER, this.onPlayerEnter); 1246 | MyEvent.unbind(Signal.PLAYERLEAVE, this.onPlayerLeave); 1247 | MyEvent.unbind(Signal.TEXT, this.onReceiveText); 1248 | MyEvent.unbind(Signal.SendText, this.onSendText); 1249 | MyEvent.unbind(Signal.OnClickLeave, this.onClickReturnLobby); 1250 | MyEvent.unbind(Signal.LobbyInfo, this.onReturnToLobby); 1251 | MyEvent.unbind(Signal.OnClickSwitchButton, this.onClickSwitchButton); 1252 | MyEvent.unbind(Signal.OnPlayerSwitch, this.onPlayerSwitch); 1253 | MyEvent.unbind(Signal.OnClickRoomSetButton, this.onClickRoomSetButton); 1254 | MyEvent.unbind(Signal.OnClickRoomSetButtonOK, this.onClickRoomSetButtonOK); 1255 | MyEvent.unbind(Signal.HOST, this.setMeAsHost); 1256 | MyEvent.unbind(Signal.UNHOST, this.setMeAsNotHost); 1257 | MyEvent.unbind("sri", this.onRoomChange); 1258 | MyEvent.unbind(Signal.KickPlayer, this.onKickPlayer); 1259 | } 1260 | 1261 | private onKickPlayer(data: any, _this: PlayState): void { 1262 | alert(data); 1263 | } 1264 | 1265 | public onRoomChange(data: any, _this: PlayState): void { 1266 | jQuery("#gamePage #roomnum").html(data.id); 1267 | jQuery("#gamePage #roomname").html(data.name); 1268 | Main.currentRoom = Util.convertRoomData(data); 1269 | } 1270 | 1271 | public onClickRoomSetButton(data: any, _this: PlayState): void{ 1272 | jQuery(".settingsPage[id=setroom]").show(0); 1273 | jQuery("#wrapper").addClass("mask"); 1274 | jQuery("#mask").show(); 1275 | 1276 | if (Main.isHost) { 1277 | if (Main.currentRoom.state == 0) { 1278 | jQuery("#setroom #roomtitle").val(Main.currentRoom.roomname); 1279 | jQuery("#setroom #roomtitle").removeAttr("disabled", "disabled"); 1280 | jQuery("#setroom #roompassword").val(Main.currentRoom.password); 1281 | jQuery("#setroom #roompassword").removeAttr("disabled", "disabled"); 1282 | jQuery("#setroom #cardpacks").empty(); 1283 | for (var i = 0; i < Main.cardpacks.length; i++) { 1284 | var checked: boolean = false; 1285 | for (var j: number = 0; j < Main.currentRoom.cardPacks.length; j++) { 1286 | if (Main.cardpacks[i].id == Main.currentRoom.cardPacks[j].id) { 1287 | checked = true; 1288 | break; 1289 | } 1290 | } 1291 | 1292 | if (Main.me.getLevel() >= Main.cardpacks[i].level) 1293 | jQuery("#setroom #cardpacks").append('
'); 1294 | else 1295 | jQuery("#setroom #cardpacks").append('
'); 1296 | } 1297 | } else { 1298 | jQuery("#setroom #roomtitle").val(Main.currentRoom.roomname); 1299 | jQuery("#setroom #roomtitle").removeAttr("disabled", "disabled"); 1300 | jQuery("#setroom #roompassword").val(Main.currentRoom.password); 1301 | jQuery("#setroom #roompassword").removeAttr("disabled", "disabled"); 1302 | jQuery("#setroom #cardpacks").empty(); 1303 | for (var i = 0; i < Main.cardpacks.length; i++) { 1304 | var checked: boolean = false; 1305 | for (var j: number = 0; j < Main.currentRoom.cardPacks.length; j++) { 1306 | if (Main.cardpacks[i].id == Main.currentRoom.cardPacks[j].id) { 1307 | checked = true; 1308 | break; 1309 | } 1310 | } 1311 | 1312 | if (Main.me.getLevel() >= Main.cardpacks[i].level) 1313 | jQuery("#setroom #cardpacks").append('
'); 1314 | else 1315 | jQuery("#setroom #cardpacks").append('
'); 1316 | } 1317 | } 1318 | } else { 1319 | jQuery("#setroom #roomtitle").val(Main.currentRoom.roomname); 1320 | jQuery("#setroom #roomtitle").attr("disabled", "disabled"); 1321 | jQuery("#setroom #roompassword").val(Main.currentRoom.password); 1322 | jQuery("#setroom #roompassword").attr("disabled", "disabled"); 1323 | jQuery("#setroom #cardpacks").empty(); 1324 | for (var i = 0; i < Main.cardpacks.length; i++) { 1325 | var checked: boolean = false; 1326 | for (var j: number = 0; j < Main.currentRoom.cardPacks.length; j++) { 1327 | if (Main.cardpacks[i].id == Main.currentRoom.cardPacks[j].id) { 1328 | checked = true; 1329 | break; 1330 | } 1331 | } 1332 | 1333 | if (Main.me.getLevel() >= Main.cardpacks[i].level) 1334 | jQuery("#setroom #cardpacks").append('
'); 1335 | else 1336 | jQuery("#setroom #cardpacks").append('
'); 1337 | } 1338 | } 1339 | } 1340 | 1341 | public onClickRoomSetButtonOK(data: any, _this: PlayState): void { 1342 | 1343 | 1344 | jQuery(".settingsPage").hide(); 1345 | jQuery("#wrapper").removeClass("mask"); 1346 | jQuery("#mask").hide(); 1347 | 1348 | var time = new Date().getTime(); 1349 | if (time < parseInt(localStorage["lastSendTime"])) { 1350 | Util.showMessage("技能冷却中,剩余时间:" + Math.round((parseInt(localStorage["lastSendTime"]) - time) / 1000) + "秒"); 1351 | Main.OnClickCloseSettings(null, null); 1352 | return; 1353 | } 1354 | 1355 | if (!Main.isHost) 1356 | return; 1357 | 1358 | var name: string = jQuery("#setroom #roomtitle").val(); 1359 | var password: string = jQuery("#setroom #roompassword").val(); 1360 | var spCodesTemp: string = ""; 1361 | var level: number = Main.me.getLevel(); 1362 | jQuery('#setroom input:checkbox[name=cp]:checked').each(function (i) { 1363 | if (0 == i) { 1364 | spCodesTemp = jQuery(this).val(); 1365 | } else { 1366 | spCodesTemp += ("," + jQuery(this).val()); 1367 | } 1368 | }); 1369 | 1370 | Server.instance.send(PackageBuilder.buildSetRoomPackage(level, name, password, spCodesTemp), true, true); 1371 | localStorage["lastSendTime"] = new Date().getTime() + 60000; 1372 | } 1373 | 1374 | public clearGamePage(): void { 1375 | jQuery("#roominfo #roomnum").empty(); 1376 | jQuery("#roominfo #roomname").empty(); 1377 | jQuery("#roominfo #roomname").empty(); 1378 | jQuery("#blackCardArea #blackCard").empty(); 1379 | jQuery("#timerArea #timerFill").css("width", "0%"); 1380 | jQuery("#chatArea #messages").empty(); 1381 | jQuery("#tableArea #table").empty(); 1382 | jQuery("#handArea #hand").empty(); 1383 | jQuery("#rightArea #playerArea").empty(); 1384 | jQuery("#rightArea #spectateArea").empty(); 1385 | } 1386 | 1387 | public showHostSettings(): void { 1388 | jQuery("#blackCardArea #blackCard").hide(); 1389 | jQuery("#blackCardArea #hostSettings").show(); 1390 | } 1391 | 1392 | public showBlackCardArea(): void { 1393 | jQuery("#blackCardArea #blackCard").show(); 1394 | jQuery("#blackCardArea #hostSettings").hide(); 1395 | } 1396 | 1397 | public setMeAsHost(): void { 1398 | Main.isHost = true; 1399 | } 1400 | 1401 | public setMeAsNotHost(): void { 1402 | Main.isHost = false; 1403 | } 1404 | 1405 | public updateMyInfoDisplay(): void { 1406 | 1407 | var level: number = Main.me.getLevel(); 1408 | var remainExp: number = Main.me.getRemainExp(); 1409 | var needExp: number = Main.me.getNeedExp(); 1410 | 1411 | jQuery("#gamePage #statArea #nameTag").html(Main.me.name); 1412 | jQuery("#gamePage #statArea #nameTag").attr("title", "pid:" + Main.me.pid); 1413 | jQuery("#gamePage #statArea #level").html("Lv." + level); 1414 | jQuery("#gamePage #statArea #levelBarExp").html(remainExp + "/" + needExp); 1415 | jQuery("#gamePage #statArea #credit #content").html(Main.me.credit); 1416 | jQuery("#gamePage #statArea #fish #content").html(Main.me.fish); 1417 | jQuery("#gamePage #statArea #levelBarBack").css("width", (remainExp / needExp * 100) + "%"); 1418 | 1419 | 1420 | } 1421 | 1422 | public updateMyInfo(data: any): void { 1423 | Main.me = Util.convertPlayerData(data.info[0]); 1424 | this.updateMyInfoDisplay(); 1425 | } 1426 | 1427 | public getPlayerByPid(pid: number): Player { 1428 | var p: Player = null; 1429 | for (var i = 0; i < this.players.length; i++) { 1430 | if (this.players[i].pid == pid) { 1431 | p = this.players[i]; 1432 | break; 1433 | } 1434 | } 1435 | 1436 | if (p == null) { 1437 | for (var i = 0; i < this.spectators.length; i++) { 1438 | if (this.spectators[i].pid == pid) { 1439 | p = this.spectators[i]; 1440 | break; 1441 | } 1442 | } 1443 | } 1444 | 1445 | return p; 1446 | } 1447 | 1448 | public onPlayerEnter(data: any, _this: PlayState): void { 1449 | var p: Player = Util.convertPlayerData(data.player[0]); 1450 | if (data.spectate == true || data.spectate == "true") 1451 | MyEvent.call(Signal.TEXT, { text: p.name + " 前来贴窗", pid: 0 }); 1452 | else 1453 | MyEvent.call(Signal.TEXT, { text: p.name + " 进入了房间", pid: 0 }); 1454 | if (data.player[0].pid == Main.me.pid) 1455 | return; 1456 | _this.addOnePlayer(p, data.spectate); 1457 | } 1458 | 1459 | public onPlayerLeave(data: any, _this: PlayState): void { 1460 | var p: Player = _this.getPlayerByPid(data.pid); 1461 | if (p != null) { 1462 | MyEvent.call(Signal.TEXT, { text: p.name + " 离开了房间", pid: 0 }); 1463 | _this.removeOnePlayer(p.pid); 1464 | } 1465 | } 1466 | 1467 | public addOnePlayer(p: Player, isSpector: any): void { 1468 | if (isSpector == true || isSpector == "true") { 1469 | this.spectators.push(p); 1470 | } else { 1471 | this.players.push(p); 1472 | } 1473 | this.updatePlayerList(); 1474 | } 1475 | 1476 | public removeOnePlayer(pid: number): void { 1477 | var index: number = -1; 1478 | for (var i = 0; i < this.players.length; i++) { 1479 | if (this.players[i].pid == pid) { 1480 | index = i; 1481 | break; 1482 | } 1483 | } 1484 | 1485 | if (index != -1) { 1486 | this.players.splice(index, 1); 1487 | this.updatePlayerList(); 1488 | } else { 1489 | for (var i = 0; i < this.spectators.length; i++) { 1490 | if (this.spectators[i].pid == pid) { 1491 | index = i; 1492 | break; 1493 | } 1494 | } 1495 | 1496 | if (index != -1) { 1497 | this.spectators.splice(index, 1); 1498 | this.updatePlayerList(); 1499 | } 1500 | } 1501 | } 1502 | 1503 | public updatePlayerList(): void { 1504 | var ele: any = jQuery("#gamePage #playerArea"); 1505 | var elesp: any = jQuery("#gamePage #spectateArea"); 1506 | ele.empty(); 1507 | elesp.empty(); 1508 | for (var i = 0; i < this.players.length; i++) { 1509 | var p: Player = this.players[i]; 1510 | ele.append('
' + p.name + '
Lv.' + p.getLevel() + '
' + 0 + '
裁判
'); 1511 | //jQuery("#gamePage #playerArea .player").tapOrClick(function (e) { MyEvent.call(Signal.KickPlayer, jQuery(e.target).attr("pid")); }); 1512 | jQuery("#gamePage #playerArea .player").click(function (e) { alert(jQuery(e.target).attr('pid')); }); 1513 | } 1514 | 1515 | for (var i = 0; i < this.spectators.length; i++) { 1516 | var p: Player = this.spectators[i]; 1517 | elesp.append('
' + p.name + '
'); 1518 | } 1519 | } 1520 | 1521 | public onReceiveText(data: any, _this: PlayState): void { 1522 | var pid: any = parseInt(data.pid); 1523 | var speakerName: string = "Unknow"; 1524 | if (isNaN(data.pid)) { 1525 | speakerName = data.pid; 1526 | } else if (pid == 0) { 1527 | speakerName = "系统"; 1528 | } else { 1529 | var p: Player = _this.getPlayerByPid(pid); 1530 | if (p != null) 1531 | speakerName = p.name; 1532 | } 1533 | 1534 | var text: string = data.text; 1535 | text = Util.convertChat(text); 1536 | if (pid == 0) 1537 | jQuery("#chatArea #messages").append('
'); 1538 | else 1539 | jQuery("#chatArea #messages").append('
'); 1540 | 1541 | jQuery("#chatArea #messages")[1].scrollTop = jQuery("#chatArea #messages")[1].scrollHeight; 1542 | if (pid != 0) 1543 | Main.sayByVoicePlayer(text); 1544 | } 1545 | 1546 | public onSendText(data: any, _this: PlayState): void { 1547 | var $text: any = jQuery("#gamePage #inputArea #inputbox")[0]; 1548 | var text: string = $text.value.trim(); 1549 | if (text == null || text.length == 0 || text.length > 200) return; 1550 | Server.instance.send(PackageBuilder.buildTextPackage(text), true, true); 1551 | $text.value = ""; 1552 | } 1553 | 1554 | public onClickSwitchButton(data: any, _this: PlayState): void { 1555 | if (_this.isPlayer) { 1556 | if (_this.spectators.length >= 16) { 1557 | Util.showMessage("无法观战,观众已满!"); 1558 | return; 1559 | } 1560 | } else { 1561 | if (_this.players.length >= 8) { 1562 | Util.showMessage("无法加入,玩家已满!"); 1563 | return; 1564 | } 1565 | } 1566 | Server.instance.send(PackageBuilder.buildSwitchPlacePackage(_this.isPlayer ? 1 : 0), true, true); 1567 | } 1568 | 1569 | public onPlayerSwitch(data: any, _this: PlayState): void { 1570 | var id: number = data.pid; 1571 | var place: number = data.place; 1572 | var p: Player = _this.getPlayerByPid(id); 1573 | if (p == null) return; 1574 | 1575 | _this.removeOnePlayer(p.pid); 1576 | _this.addOnePlayer(p, place == 1); 1577 | if (place == 1) { 1578 | Util.showMessage(p.name + "开始旁观"); 1579 | } else { 1580 | Util.showMessage(p.name + "进入对局"); 1581 | } 1582 | 1583 | 1584 | if (id == Main.me.pid) { 1585 | if (place == 0) { 1586 | jQuery("#settingsArea #spectate").html("观战"); 1587 | _this.isPlayer = true; 1588 | } else { 1589 | jQuery("#settingsArea #spectate").html("加入"); 1590 | _this.isPlayer = false; 1591 | } 1592 | } 1593 | } 1594 | 1595 | public onClickReturnLobby(data: any, _this: PlayState): void { 1596 | if (!_this.canReturnToLobby) { 1597 | Util.showMessage("无法退出"); 1598 | return; 1599 | } 1600 | Server.instance.send(PackageBuilder.buildReturnLobbyPackage(), true, true); 1601 | } 1602 | 1603 | public onReturnToLobby(data: any, _this: PlayState): void { 1604 | _this.unbindEvents(); 1605 | jQuery("#gamePage").hide(); 1606 | Main.lobbyState.returnToLobbyPage(data); 1607 | } 1608 | } 1609 | 1610 | window.onload = () => { 1611 | new Main().start(); 1612 | }; --------------------------------------------------------------------------------