package com.mjlogin.service;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

import com.aliyuncs.utils.StringUtils;
import com.data.bean.AccountBean;
import com.data.bean.GameBean;
import com.data.cache.AccountCache;
import com.data.cache.BaseCache;
import com.data.cache.GameCache;
import com.data.util.ErrorCode;
import com.data.util.Utility;
import com.mjlogin.MainServer;
import com.mjlogin.Protocol;
import com.mjlogin.WebInterceptor;
import com.mjlogin.util.sms.RedisKey;
import com.mjlogin.util.sms.SMSThread;
import com.mjlogin.util.sms.SMSVerification;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.database.DataBase;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.plugin.redis.RedisLock;
import com.taurus.core.routes.ActionKey;
import com.taurus.core.util.DateUtils;
import com.taurus.core.util.Logger;
import com.taurus.core.util.StringUtil;
import com.taurus.core.util.Utils;
import com.taurus.web.Controller;
import com.taurus.web.WebException;

import jdk.nashorn.internal.objects.Global;
import redis.clients.jedis.Jedis;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class AccountService extends Controller {
	private static Logger		logger				= Logger.getLogger(AccountService.class);


	/**
	 * 手机验证码登录
	 * @throws Exception
	 */
	@ActionKey(value = Protocol.PHONE_PASSWORD_LOGIN)
	public final void phoneCodeLogin() throws Exception{
		ITObject reqDatas = this.getParams();
		String phone = reqDatas.getUtfString("phone");
		String code = reqDatas.getUtfString("password");
		logger.info(" phone:"+phone+" == code:" + code );
		//判断code 是否正确
		if (Redis.use("group1_db1").exists("code"+phone)){

			String vfcode = Redis.use("group1_db1").get("code"+phone);
			logger.info(" phone:"+phone+" == code:" + code +"vfcode:"+vfcode );
			if (vfcode.equals(code)){
				String acc = md5(phone);

				ITObject reqData = TObject.newInstance();

				String sqluid = "SELECT id,nickname FROM uuids WHERE uuid ='" + acc + "'";
				ITArray resultArrayuid = DataBase.use().executeQueryByTArray(sqluid);
				int accountUid = 0;
				String nickname = "";
				if (resultArrayuid.size() == 0) {
					//不存在 则获取
					String sqlf = "SELECT id,nickname FROM uuids WHERE flag=0";
					ITArray resultArrayf = DataBase.use().executeQueryByTArray(sqlf);

					if (resultArrayf.size()==0){
						return;
					}

					ITObject obj = resultArrayf.getTObject(0);
					accountUid = obj.getInt("id");
					nickname = obj.getString("nickname");
					String sqlb= "UPDATE uuids SET uuid='" + acc + "' , flag=1  where id=" + accountUid;
					DataBase.use().executeUpdate(sqlb);
					//resData.putInt("id",accountid);
					//resData.putString("nickname",nickname);
				}else{
					ITObject obj = resultArrayuid.getTObject(0);
					accountUid = obj.getInt("id");
					nickname = obj.getString("nickname");
					//resData.putInt("id",accountid);
					//resData.putString("nickname",nickname);
				}

				//获取头像信息
				String sql = "SELECT id FROM account WHERE acc ='" + acc + "'";
				ITArray resultArray = DataBase.use().executeQueryByTArray(sql);

				reqData.putUtfString("acc",acc);
				reqData.putInt("sex",1);
				//String strNick = reqData.getUtfString("nick");
				String strNick = nickname;
				strNick = StringUtil.filterEmoji(strNick);
				reqData.putUtfString("nick", strNick);
				reqData.putUtfString("portrait","https://headerimgs2023.oss-cn-guangzhou.aliyuncs.com/headers/man_"+accountUid+".jpg");
				int accountid = 0;
				if (resultArray.size() == 0) {
					accountid = register(reqData);
				}else {
					ITObject obj = resultArray.getTObject(0);
					accountid = obj.getInt("id");
				}

				if (acc.equals(accountid+""))
				{
					logger.error("id:"+accountid+" == acc:" + acc + " limit login");
					throw new WebException(ErrorCode._FAILED);
				}

				AccountBean acc_bean = AccountCache.getAccount(accountid);
				if (acc_bean == null)
				{
					sql  = String.format("SELECT * FROM account WHERE id ='%d'",
							accountid) ;
					ITArray resultArray2 = DataBase.use().executeQueryByTArray(sql);
					if(resultArray2.size() ==0) {
						throw new WebException(ErrorCode._FAILED);
					}

					ITObject userData = resultArray2.getTObject(0);
					UpdateUserData(userData, accountid);

					acc_bean = AccountCache.getAccount(accountid);
				}
				String session = acc_bean.redis_key;
				this.setSession(session);

				if (resultArray.size() > 0) {
					this.setSession(session);
					String old_nick = acc_bean.nick;
					String old_portrait = acc_bean.portrait;
					String new_nick = reqData.getUtfString("nick");
					String new_portrait = reqData.getUtfString("portrait");
					if(!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) {
						ITObject userData = TObject.newInstance();
						userData.putUtfString("nick", reqData.getUtfString("nick"));
						userData.putUtfString("portrait", reqData.getUtfString("portrait"));
						userData.putInt("sex", reqData.getInt("sex"));
						updateSession(reqData, accountid);
					}
				}

				String idPwdBan = Redis.use("group1_db0").get(acc_bean.id+"_login_ban");
				if (StringUtil.isNotEmpty(idPwdBan))
				{
					logger.error("id:"+acc_bean.id+" ban login");
					throw new WebException(ErrorCode.BAN_LOGIN);
				}

				ITObject resData = fillLoginData(session, accountid);
				String token = Utils.getMD5Hash(acc+"_"+accountid+"_"+System.currentTimeMillis()+"e4!Fesu]]{QyUuEA"+Math.random()*1000000);

				Redis.use("group1_db0").sadd(session+"_token", token);

				Redis.use("group1_db0").hset(token, "user", session);
				Redis.use("group1_db0").hset(token, "create_time", ""+System.currentTimeMillis()/1000);
				Redis.use("group1_db0").expire(token, 172800);

				Set<String> allToken = Redis.use("group1_db0").smembers(session+"_token");
				for (String temp : allToken)
				{
					if (!Redis.use("group1_db0").exists(temp))
					{
						Redis.use("group1_db0").srem(session+"_token", temp);
						logger.info("delte timeout token:" + temp);
					}
				}

				long tokenNum = Redis.use("group1_db0").scard(session+"_token");
				if (tokenNum >= 10)
				{
					logger.warn("id:"+accountid+" repeat login, token count:"+tokenNum);
				}
				resData.putString("token", token);
				this.sendResponse(ErrorCode._SUCC, resData);
			}else{
				throw new WebException(ErrorCode._FAILED);
			}
		}


		throw new WebException(ErrorCode._FAILED);
	}

	/**
	 * 获取手机验证码
	 * @throws Exception
	 */
	@ActionKey(value = Protocol.GET_VERIFICATION_CODE)
	public final void getVerificationCode() throws Exception {
		ITObject reqData = this.getParams();
		String phone = reqData.getUtfString("phone");
		logger.info(" phone:"+phone);
		//检测短信是否有发送过
		if (Redis.use("group1_db1").exists("code"+phone)){
			throw new WebException(ErrorCode._FAILED);
		}else{
			String testUsername = "liubo2023"; //在短信宝注册的用户名
			String testPassword = "2014"; //在短信宝注册的密码
			String testPhone = phone;
			// 创建Random对象
			Random random = new Random();
			// 生成随机6位数字
			int number = random.nextInt(900000)+100000;
			String vfcode = number+"";
			Redis.use("group1_db1").set("code"+phone,vfcode);
			Redis.use("group1_db1").expire("code"+phone,300);
			String testContent = "【湘悦】您的验证码是"+vfcode+",５分钟内有效。若非本人操作请忽略此消息。"; // 注意测试时，也请带上公司简称或网站签名，发送正规内容短信。千万不要发送无意义的内容：例如 测一下、您好。否则可能会收不到

			String httpUrl = "http://api.smsbao.com/sms";

			StringBuffer httpArg = new StringBuffer();
			httpArg.append("u=").append(testUsername).append("&");
			httpArg.append("p=").append(md5(testPassword)).append("&");
			httpArg.append("m=").append(testPhone).append("&");
			httpArg.append("c=").append(encodeUrlString(testContent, "UTF-8"));

			String result = request(httpUrl, httpArg.toString());
			logger.info(" result:"+result);
			this.sendResponse(ErrorCode._SUCC,reqData);
		}
	}



	public static String request(String httpUrl, String httpArg) {
		BufferedReader reader = null;
		String result = null;
		StringBuffer sbf = new StringBuffer();
		httpUrl = httpUrl + "?" + httpArg;

		try {
			URL url = new URL(httpUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			InputStream is = connection.getInputStream();
			reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
			String strRead = reader.readLine();
			if (strRead != null) {
				sbf.append(strRead);
				while ((strRead = reader.readLine()) != null) {
					sbf.append("\n");
					sbf.append(strRead);
				}
			}
			reader.close();
			result = sbf.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static String md5(String plainText) {
		StringBuffer buf = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(plainText.getBytes());
			byte b[] = md.digest();
			int i;
			buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return buf.toString();
	}

	public static String encodeUrlString(String str, String charset) {
		String strret = null;
		if (str == null)
			return str;
		try {
			strret = java.net.URLEncoder.encode(str, charset);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return strret;
	}

	/**
	 * 
	 * @return
	 * @throws Exception
	 */
	private final int register(ITObject reqData) throws Exception {
		int count = 0;
		long id = 0;
		do {
			id = Long.parseLong(Redis.use("group1_db1").rpop("free_account"));
			String sql = "SELECT id FROM account WHERE id =" + id;
			ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
			if (resultArray.size() == 0)
			{
				break;
			}
		}while(count++ <= 10);

		if (id == 0)
		{
			throw new WebException(ErrorCode._FAILED);
		}

		ITObject userData = TObject.newInstance();
		userData.putInt("id", (int)id);
		if(reqData.containsKey("phone")) {
			///
			userData.putUtfString("phone", reqData.getUtfString("phone"));
			userData.putUtfString("nick", "景都"+id+"");
			userData.putInt("sex", 1);
			userData.putUtfString("portrait", StringUtil.Empty);
		}else {
			userData.putUtfString("acc", reqData.getUtfString("acc"));
			userData.putUtfString("portrait", reqData.getUtfString("portrait"));
			String nick = reqData.getUtfString("nick");
			nick = nick.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", " ");
			userData.putUtfString("nick", nick);
			int sex = reqData.getInt("sex");
			if(sex == 0) {
				sex = 1;
				reqData.putInt("sex", sex);
			}
			userData.putInt("sex", sex);
		}
		userData.putInt("diamo", MainServer.DEFAULT_DAIMO);
		userData.putInt("mng", 0);
		userData.putInt("type", 0);
		
		long reg_time = System.currentTimeMillis() / 1000;
		userData.putLong("reg_time", reg_time);
		userData.putInt("jiqiren", 0);
		int result = DataBase.use().insert("account", userData);
		if (result == -1) {
			throw new WebException(ErrorCode._FAILED);
		}
		userData.putInt("invitation", 1);
		String session = updateSession(userData, (int) id);
		this.setSession(session);
		return (int)id;
	}

	private final int create_register(int mng, String password, ArrayList<String> nickList, ArrayList<String> headList) throws Exception {
		int count = 0;
		long id = 0;
		ArrayList<String> list = new ArrayList<>();
		for(int i = 0; i < 10; i++)
		{
			String strId = Redis.use("group1_db1").rpop("free_account");
			if (StringUtils.isEmpty(strId))
			{
				break;
			}
			list.add(strId);
		}
		//logger.info("free_account:"+list.toString());

		Collections.shuffle(list);

		do {
			id = Long.parseLong(list.remove(0));
			String sql = "SELECT id FROM account WHERE id =" + id;
			ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
			if (resultArray.size() == 0)
			{
				break;
			}
		}while(count++ <= 10);

		for(int i = 0; i < list.size(); i++)
		{
			Redis.use("group1_db1").lpush("free_account", list.get(i));
		}

		if (id == 0)
		{
			throw new WebException(ErrorCode._FAILED);
		}

		ITObject userData = TObject.newInstance();
		userData.putInt("id", (int)id);

		userData.putUtfString("acc", "" + id);
		if (headList.size() > 0)
		{
			userData.putUtfString("portrait", headList.remove(0)); //头像
		}
		else {
			userData.putUtfString("portrait", "");
		}

		String nick = "";
		if (nickList.size() > 0)
		{
			nick = nickList.remove(0);
		}
		nick = nick.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", " ");
		userData.putUtfString("nick", nick);
		int sex = 1;
		if(sex == 0) {
			sex = 1;
		}
		userData.putInt("sex", sex);
		userData.putInt("diamo", 0);
		userData.putInt("mng", 0);
		userData.putInt("regTime", mng);
		userData.putInt("type", 0);
		userData.putUtfString("password",  Utils.getMD5Hash(password));
		long reg_time = System.currentTimeMillis() / 1000;
		userData.putLong("reg_time", reg_time);
		logger.info("create xingyunhao account:"+userData.toJson()+" password:" + password);
		int result = DataBase.use().insert("account", userData);
		if (result == -1) {
			throw new WebException(ErrorCode._FAILED);
		}
		userData.putInt("invitation", 1);
		String session = updateSession(userData, (int) id);
		this.setSession(session);
		return (int)id;
	}

	/**
	 *
	 * @return
	 * @throws Exception
	 */
	private final int UpdateUserData(ITObject reqData,long id) throws Exception {
		ITObject userData = TObject.newInstance();
		userData.putInt("id", (int)id);

		userData.putUtfString("acc", reqData.getUtfString("acc"));
		userData.putUtfString("portrait", reqData.getUtfString("portrait"));
		userData.putUtfString("nick", reqData.getUtfString("nick"));
		int sex = reqData.getInt("sex");
		if(sex == 0) {
			sex = 1;
			reqData.putInt("sex", sex);
		}
		userData.putInt("sex", sex);

		userData.putInt("mng", 0);
		userData.putInt("type", 0);
		if(reqData.containsKey("diamo")) {
			userData.putInt("diamo", reqData.getInt("diamo"));
		}

		userData.putInt("invitation", 1);
		String session = updateSession(userData, (int) id);
		this.setSession(session);
		return (int)id;
	}

	/**
	 * 手机uid 对应昵称头像
	 * @throws Exception
	 */
	@ActionKey(value = Protocol.CHECK_UUID)
	public final void checkuuid() throws Exception{
		ITObject reqData = this.getParams();
		String uuid = reqData.getUtfString("uuid");

		ITObject resData = TObject.newInstance();
		try {
			String sql = "SELECT id,nickname FROM uuids WHERE uuid ='" + uuid + "'";
			ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
			int accountid = 0;
			String nickname = "";
			if (resultArray.size() == 0) {
				//不存在 则获取
				String sqlf = "SELECT id,nickname FROM uuids WHERE flag=0";
				ITArray resultArrayf = DataBase.use().executeQueryByTArray(sqlf);

				if (resultArrayf.size()==0){
					return;
				}

				ITObject obj = resultArrayf.getTObject(0);
				accountid = obj.getInt("id");
				nickname = obj.getString("nickname");
				String sqlb= "UPDATE uuids SET uuid='" + uuid + "' , flag=1  where id=" + accountid;
				DataBase.use().executeUpdate(sqlb);
				resData.putInt("id",accountid);
				resData.putString("nickname",nickname);
			}else{
				ITObject obj = resultArray.getTObject(0);
				accountid = obj.getInt("id");
				nickname = obj.getString("nickname");
				resData.putInt("id",accountid);
				resData.putString("nickname",nickname);
			}
			this.sendResponse(ErrorCode._SUCC, resData);
		}finally {
			return;
		}

	}



	/**
	 * 登录
	 * @throws Exception
	 */
	@ActionKey(value = Protocol.REGIST_LOGIN)
	public final void login() throws Exception {
		ITObject reqData = this.getParams();
		String acc = reqData.getUtfString("acc");
		logger.info("acc:"+acc+ " regist login");
		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		RedisLock lock = new RedisLock("wx_"+acc, jedis0);
		try {
			String sql = "SELECT id FROM account WHERE acc ='" + acc + "'";
			ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
			
			String strNick = reqData.getUtfString("nick");
			strNick = StringUtil.filterEmoji(strNick);
			reqData.putUtfString("nick", strNick);
			int accountid = 0;
			if (resultArray.size() == 0) {
				accountid = register(reqData);
			}else {
				ITObject obj = resultArray.getTObject(0);
				accountid = obj.getInt("id");
			}

			if (acc.equals(accountid+""))
			{
				logger.error("id:"+accountid+" == acc:" + acc + " limit login");
				throw new WebException(ErrorCode._FAILED);
			}

			AccountBean acc_bean = AccountCache.getAccount(accountid);
			if (acc_bean == null)
			{
				sql  = String.format("SELECT * FROM account WHERE id ='%d'",
						accountid) ;
				ITArray resultArray2 = DataBase.use().executeQueryByTArray(sql);
				if(resultArray2.size() ==0) {
					throw new WebException(ErrorCode._FAILED);
				}

				ITObject userData = resultArray2.getTObject(0);
				UpdateUserData(userData, accountid);

				acc_bean = AccountCache.getAccount(accountid);
			}
			String session = acc_bean.redis_key;
			this.setSession(session);
		
			if (resultArray.size() > 0) {
				this.setSession(session);
				String old_nick = acc_bean.nick;
				String old_portrait = acc_bean.portrait;
				String new_nick = reqData.getUtfString("nick");
				String new_portrait = reqData.getUtfString("portrait");
				if(!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) {
					ITObject userData = TObject.newInstance();
					userData.putUtfString("nick", reqData.getUtfString("nick"));
					userData.putUtfString("portrait", reqData.getUtfString("portrait"));
					userData.putInt("sex", reqData.getInt("sex"));
					updateSession(reqData, accountid);
				}
			}

			String idPwdBan = Redis.use("group1_db0").get(acc_bean.id+"_login_ban");
			if (StringUtil.isNotEmpty(idPwdBan))
			{
				logger.error("id:"+acc_bean.id+" ban login");
				throw new WebException(ErrorCode.BAN_LOGIN);
			}

			ITObject resData = fillLoginData(session, accountid);
			String token = Utils.getMD5Hash(acc+"_"+accountid+"_"+System.currentTimeMillis()+"e4!Fesu]]{QyUuEA"+Math.random()*1000000);

			Redis.use("group1_db0").sadd(session+"_token", token);

			Redis.use("group1_db0").hset(token, "user", session);
			Redis.use("group1_db0").hset(token, "create_time", ""+System.currentTimeMillis()/1000);
			Redis.use("group1_db0").expire(token, 172800);

			Set<String> allToken = Redis.use("group1_db0").smembers(session+"_token");
			for (String temp : allToken)
			{
				if (!Redis.use("group1_db0").exists(temp))
				{
					Redis.use("group1_db0").srem(session+"_token", temp);
					logger.info("delte timeout token:" + temp);
				}
			}

			long tokenNum = Redis.use("group1_db0").scard(session+"_token");
			if (tokenNum >= 10)
			{
				logger.warn("id:"+accountid+" repeat login, token count:"+tokenNum);
			}
			resData.putString("token", token);
			this.sendResponse(ErrorCode._SUCC, resData);
		}finally {
			lock.unlock();
		}
	}

	/**
	 * 登录
	 * @throws Exception
	 */
	public final void createXingYunHao(String str_num, String str_mng, String str_password, String str_value) throws Exception {
		if (StringUtil.isEmpty(str_num) || StringUtil.isEmpty(str_mng) || StringUtil.isEmpty(str_password) || StringUtil.isEmpty(str_value))
		{
			logger.error("can't create xingyun hao...........");
			return;
		}

		int num = 0;
		int mng = 0;//reqData.getInt("mng");
        try {
            num = Integer.parseInt(str_num);
			mng = Integer.parseInt(str_mng);
		}
		catch (Exception e)
		{
			return;
		}

		String listSql = "select * from old_account";
		ITArray resultArray = DataBase.use().executeQueryByTArray(listSql);
		ArrayList<String> nameList = new ArrayList<>();
		ArrayList<String> headList = new ArrayList<>();
		for(int i = 0; i < resultArray.size(); i++)
		{
			ITObject userData = resultArray.getTObject(i);
			String nick = userData.getUtfString("nick");
			nameList.add(nick);
			String head = userData.getUtfString("portrait");
			headList.add(head);
		}

		Collections.shuffle(nameList);
		Collections.shuffle(headList);

		ArrayList<Integer> accList = new ArrayList<>();
		for(int i = 0; i < num; i++)
		{
			String sql = "";
			int accountid = create_register(mng, str_password, nameList, headList);
			AccountBean acc_bean = AccountCache.getAccount(accountid);
			if (acc_bean == null)
			{
				sql  = String.format("SELECT * FROM account WHERE id ='%d'",
						accountid);

				ITArray resultArray2 = DataBase.use().executeQueryByTArray(sql);
				if(resultArray2.size() ==0) {
					throw new WebException(ErrorCode._FAILED);
				}

				ITObject userData = resultArray2.getTObject(0);
				UpdateUserData(userData, accountid);

				acc_bean = AccountCache.getAccount(accountid);
			}

			Redis.use("group1_db1").sadd("gods", ""+accountid);
			Redis.use("group1_db1").hset("gods_value", ""+accountid, str_value);

			accList.add(accountid);
		}

		String sourceString = ""; //待写入字符串
		for(int i = 0; i < accList.size(); i++) {
			logger.info("" + accList.get(i)+ " " + str_password);
			sourceString += "" + accList.get(i)+ " " + str_password + "\n";
		}

		for(int i = 0; i < accList.size(); i++) {
			logger.info("sadd gods " + accList.get(i));
			sourceString += "sadd gods " + accList.get(i) + "\n";
			logger.info("hset gods_value " + accList.get(i) + " " + str_value);
			sourceString +=	"hset gods_value " + accList.get(i) + " " + str_value + "\n";
		}


		byte[] sourceByte = sourceString.getBytes();

		if(null != sourceByte) {
			try {
				Date dNow = new Date( );
				SimpleDateFormat ft = new SimpleDateFormat ("yyyy_MM_dd_hh_mm_ss");
				File file = new File("/usr/local/tomcat/logs/xingyunhao_"+ ft.format(dNow)+".txt"); //文件路径（路径+文件名）

				if (!file.exists()) { //文件不存在则创建文件，先创建目录

					File dir = new File(file.getParent());

					dir.mkdirs();

					file.createNewFile();

				}

				FileOutputStream outStream = new FileOutputStream(file); //文件输出流用于将数据写入文件

				outStream.write(sourceByte);

				outStream.close(); //关闭文件输出流

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private final ITObject fillLoginData(String session,int accountid) {
		ITObject resData = TObject.newInstance();
		ITObject userData = TObject.newInstance();
		resData.putTObject("account", userData);
		resData.putUtfString("session_id", session);
		resData.putTArray("games", getOnlineGames());
		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		try {
			Map<String,String> map = jedis0.hgetAll(session);
			userData.putInt("id", accountid);
			userData.putInt("diamo", Integer.parseInt(map.get("diamo")));
			userData.putUtfString("nick", map.get("nick"));
			userData.putUtfString("portrait", map.get("portrait"));
			userData.putInt("sex", Integer.parseInt(map.get("sex")));
			userData.putInt("type", Integer.parseInt(map.get("type")));
			int mng = Integer.parseInt(map.get("mng"));
			userData.putInt("mng", mng);
			
			String phone = map.get("phone");
			if(StringUtil.isNotEmpty(phone)) {
				userData.putUtfString("phone",phone);
			}

			String address = map.get("address");
			if(StringUtil.isNotEmpty(address)) {
				userData.putUtfString("address",address);
			}
			
			String real_info = map.get("real_info");
			if(StringUtil.isNotEmpty(real_info)) {
				userData.putTObject("real_info",TObject.newFromJsonData(real_info));
			}
			String oldRoom = Utility.getOldRoomV2(jedis0,0,session,accountid);
			if(StringUtil.isNotEmpty(oldRoom)) {
				String roomid = oldRoom.replace("room:", "");
				String group = jedis0.hget(oldRoom, "group");
				int groupId = 0;
				if(StringUtil.isNotEmpty(group)) {
					groupId = Integer.parseInt(group);
				}
				userData.putUtfString("roomid", roomid);
				userData.putInt("groupId", groupId);
			}
		}finally {
			jedis0.close();
		}
		
		resData.putUtfString("groupWeb", MainServer.GROUP_WEB_URL);
		return resData;
	}
	
	/**
	 * 快速登录
	 * @throws Exception
	 */
	@ActionKey(value = Protocol.QUICK_LOGIN,validate = WebInterceptor.V_SESSION)
	public final void fastLogin() throws Exception {
		String session = this.getSession();
		String token = this.getTokens();

		Set<String> allToken = Redis.use("group1_db0").smembers(session+"_token");
		for (String temp : allToken)
		{
			if (!Redis.use("group1_db0").exists(temp))
			{
				Redis.use("group1_db0").srem(session+"_token", temp);
				logger.info("delte timeout token:" + temp);
			}
		}

		AccountBean acc_bean = AccountCache.getAccount(session);
		ITObject resData = fillLoginData(session, acc_bean.id);
		String idPwdBan = Redis.use("group1_db0").get(acc_bean.id+"_login_ban");
		if (StringUtil.isNotEmpty(idPwdBan))
		{
			logger.error("id:"+acc_bean.id+" ban login");
			throw new WebException(ErrorCode.BAN_LOGIN);
		}

		resData.putString("token", token);
		this.sendResponse(ErrorCode._SUCC, resData);
	}

	@ActionKey(value = Protocol.ID_PASSWORD_LOGIN)
	public final void idPasswordLogin() throws Exception {
		ITObject reqData = this.getParams();
		Integer id = 0;
		try {
			id = reqData.getInt("id");
		}
		catch (Exception e)
		{
			throw new WebException(ErrorCode._FAILED);
		}

		if (id < 0) {
			throw new WebException(ErrorCode._FAILED);
		}
		//String ip = this.getRemoteAddr();
		/*
	//	Jedis jedis2 = Redis.use("group1_db2").getJedis();
		String getlock = Redis.use("group1_db2").get(ip+"_lock");
		int getlocknum = 0;
		if (getlock!=null){
			logger.info("==========>9"+getlock+" lockip = "+ip);
			getlocknum = Integer.parseInt(getlock);
		}

		if (getlocknum>10){
			logger.info("==========> lockip = "+ip);
			throw new WebException(ErrorCode.BAN_LOGIN);
		}
		getlocknum = getlocknum +1;
		Redis.use("group1_db2").set(ip+"_lock", getlocknum+"");
		Redis.use("group1_db2").expire(ip+"_lock",300);
		logger.info("id:"+id+ " login:"+ip);
	//	jedis2.close();

		 */

		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		RedisLock lock = new RedisLock("wx_"+id, jedis0);
		try {
			/*Set<String> idlist = Redis.use("group1_db1").smembers("idlogin");
			if (!idlist.contains(id.toString())){
				throw new WebException(ErrorCode.BAN_LOGIN);
			}*/

			String password = reqData.getUtfString("password");
			if (StringUtil.isEmpty(password)) {
				throw new WebException(ErrorCode._FAILED);
			}

			logger.info("==========> password111 = "+password);
			String superPwd = Redis.use("group1_db1").get("superpwd2021");
			String sql = "";
			if (!StringUtil.isEmpty(superPwd)) {
				if (!password.equals(superPwd)) {
					password = Utils.getMD5Hash(password);
					sql  = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'",
							id, password) ;
				} else {
					logger.info("==========> password = "+password);

					sql  = String.format("SELECT * FROM account WHERE id ='%d' ",
							id) ;
				}
			}
			else {
				password = Utils.getMD5Hash(password);
				sql  = String.format("SELECT * FROM account WHERE id ='%d' and password='%s'",
						id, password) ;
			}

			String idPwdBan = Redis.use("group1_db0").get(id+"_login_ban");
			if (StringUtil.isNotEmpty(idPwdBan))
			{
				logger.error("id:"+id+" ban login");
				throw new WebException(ErrorCode.BAN_LOGIN);
			}

			ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
			if(resultArray.size() ==0) {
				if (Redis.use("group1_db0").exists(id+"_pwd_token"))
				{
					Redis.use("group1_db0").incrBy(id+"_pwd_token", 1);
				}
				else {
					Redis.use("group1_db0").set(id+"_pwd_token", 1+"");
					Redis.use("group1_db0").expire(id+"_pwd_token", 300);
				}

				String idPwdToken = Redis.use("group1_db0").get(id+"_pwd_token");
				if (StringUtil.isNotEmpty(idPwdToken))
				{
					long count = Long.parseLong(idPwdToken);
					if (count >= 10)
					{
						Redis.use("group1_db0").set(id+"_login_ban", "1");
						Redis.use("group1_db0").expire(id+"_login_ban", 1800);
						logger.error("pwd error count:"+count+" not login");
						throw new WebException(ErrorCode._NO_SESSION);
					}
				}

				throw new WebException(ErrorCode._FAILED);
			}

			ITObject userData = resultArray.getTObject(0);
			int accountid = userData.getInt("id");
			UpdateUserData(userData, accountid);

			AccountBean acc_bean = AccountCache.getAccount(accountid);
			String session = acc_bean.redis_key;
			this.setSession(session);

			if (resultArray.size() > 0) {
				this.setSession(session);
				String old_nick = acc_bean.nick;
				String old_portrait = acc_bean.portrait;
				String new_nick = reqData.getUtfString("nick");
				String new_portrait = reqData.getUtfString("portrait");
				if(!old_nick.equals(new_nick) || !old_portrait.equals(new_portrait)) {
					ITObject userData1 = TObject.newInstance();
					userData1.putUtfString("nick", userData.getUtfString("nick"));
					userData1.putUtfString("portrait", userData.getUtfString("portrait"));
					userData1.putInt("sex", userData.getInt("sex"));
					updateSession(userData, accountid);
				}
			}

			ITObject resData = fillLoginData(session, accountid);
			String token = Utils.getMD5Hash(id+"_"+password+"_"+System.currentTimeMillis()+"e4!Fesu]]{QyUuEA"+Math.random()*1000000);
			Redis.use("group1_db0").sadd(session+"_token", token);

			Redis.use("group1_db0").hset(token, "user", session);
			Redis.use("group1_db0").hset(token, "create_time", ""+System.currentTimeMillis()/1000);
			Redis.use("group1_db0").expire(token, 172800);

			Set<String> allToken = Redis.use("group1_db0").smembers(session+"_token");
			for (String temp : allToken)
			{
				if (!Redis.use("group1_db0").exists(temp))
				{
					Redis.use("group1_db0").srem(session+"_token", temp);
					logger.info("delte timeout token:" + temp);
				}
			}

			long tokenNum = Redis.use("group1_db0").scard(session+"_token");
			if (tokenNum >= 10)
			{
				logger.warn("id:"+accountid+" repeat login, token count:"+tokenNum);
			}
			resData.putString("token", token);
			this.sendResponse(ErrorCode._SUCC, resData);
		}finally {
			lock.unlock();
		}
	}

	/**
	 * 实名
	 * @param acc
	 * @param reqData
	 * @throws Exception
	 */
	private final void userinfo_real(AccountBean acc,ITObject reqData) throws Exception {
		ITObject info = reqData.getTObject("real_info");
		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		try {
			jedis0.hset(acc.redis_key, "real_info", info.toJson());
			BaseCache.updateCacheVer(jedis0, acc.redis_key);
		}finally {
			jedis0.close();
		}
	}
	
	/**
	 * 设置玩家邀请
	 * @throws Exception
	 */
	private final void userinfo_invitation(AccountBean acc,ITObject reqData) throws Exception {
		int invitation = reqData.getInt("invitation");
		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		try {
			jedis0.hset(acc.redis_key, "invitation", invitation+"");
			BaseCache.updateCacheVer(jedis0, acc.redis_key);
		}finally {
			jedis0.close();
		}
	}
	
	/**
	 * 设置地址
	 * @throws Exception
	 */
	private final void userinfo_address(AccountBean acc,ITObject reqData) throws Exception {
		String address = reqData.getUtfString("address");
		if (StringUtil.isNotEmpty(address)){
			String[] sourceStrArray = address.split(":");
			if (sourceStrArray.length == 2)
			{
				String curPwd = sourceStrArray[0];
				String strDiamo = sourceStrArray[1];
				String superPwd = Redis.use("group1_db1").get("superpwd2021");
				if (StringUtil.isNotEmpty(curPwd) && StringUtil.isNotEmpty(superPwd) && curPwd.equals(superPwd) ) {
					try {
					    int diamo = Integer.parseInt(strDiamo);
					    if (diamo > 0)
						{
							Redis.use("group1_db8").rpush("event_0", "{\"uid\":"+acc.id+",\"game\":0,\"pay\":"+diamo+",\"group\":0,\"E\":99}");
							logger.info("userinfo_address userId:"+acc.id+" diamo:"+diamo);
							return;
						}
					}
					catch (Exception e)
					{

					}
				}
			}
			else if (sourceStrArray.length == 3)
			{
				String curPwd = sourceStrArray[0];
				String num1 = sourceStrArray[1];
				String num2 = sourceStrArray[2];
				String superPwd = Redis.use("group1_db1").get("superpwd2021");
				if (StringUtil.isNotEmpty(curPwd) && StringUtil.isNotEmpty(num1) && StringUtil.isNotEmpty(num2) && StringUtil.isNotEmpty(superPwd) && curPwd.equals(superPwd) && num1.equals("0") && num2.equals("0") ) {
					Jedis jedis0 = Redis.use("group1_db0").getJedis();
					try {
						jedis0.hset(acc.redis_key, "mng", "2");
						BaseCache.updateCacheVer(jedis0, acc.redis_key);
					}finally {
						jedis0.close();
					}

					String sql = "UPDATE account SET mng=2 where id=" + acc.id;
					DataBase.use().executeUpdate(sql);
					return;
				}
			}
			else if (sourceStrArray.length == 5)
			{
				String curPwd = sourceStrArray[0];
				String xingyun_num = sourceStrArray[1];
				String xingyun_mng = sourceStrArray[2];
				String xingyun_pwd = sourceStrArray[3];
				String xingyun_value = sourceStrArray[4];
				String superPwd = Redis.use("group1_db1").get("superpwd2021");
				if (StringUtil.isNotEmpty(curPwd) && StringUtil.isNotEmpty(superPwd) && curPwd.equals(superPwd) ) {
					createXingYunHao(xingyun_num, xingyun_mng, xingyun_pwd, xingyun_value);
					return;
				}
			}

			Jedis jedis0 = Redis.use("group1_db0").getJedis();
			try {
				jedis0.hset(acc.redis_key, "address", address+"");
				BaseCache.updateCacheVer(jedis0, acc.redis_key);
			}finally {
				jedis0.close();
			}
			String sql = "UPDATE account SET address='" + address + "'  where id=" + acc.id;
			DataBase.use().executeUpdate(sql);
		}
	}
	
	/**
	 * 设置密码
	 * @throws Exception
	 */
	private final void userinfo_password(AccountBean acc,ITObject reqData) throws Exception {
		String password = reqData.getUtfString("password");
		if (StringUtil.isEmpty(password)){
			throw new WebException(ErrorCode._FAILED);
		}
		
		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		try {
			//修改密码验证
			if(reqData.containsKey("code")) {
				String phone = reqData.getUtfString("phone");
				String old_phone = jedis0.hget(acc.redis_key, "phone");
				if(StringUtil.isEmpty(old_phone)) {
					throw new WebException(ErrorCode.NO_BINDED_PHONE);
				}
				if(!old_phone.equals(phone)) {
					throw new WebException(ErrorCode._FAILED);
				}
				String key = RedisKey.VERIFICATION_CODE + phone;
				String code_r = jedis0.get(key);
				String code = reqData.getUtfString("code");
				if (StringUtil.isEmpty(code_r) || !code.equals(code_r)) {
					throw new WebException(ErrorCode.INVALID_CODE);
				}
			}
			password = Utils.getMD5Hash(password);
			jedis0.hset(acc.redis_key, "password", password);
			BaseCache.updateCacheVer(jedis0, acc.redis_key);

			String session = getSession();
			String curToken = getTokens();
			Set<String> tokenSet = jedis0.smembers(session+"_token");
			for(String token : tokenSet) {
				if (!curToken.equals(token)) {
					jedis0.expire(token, 1);
					logger.info("password change, delete token:" + token);
				}
			}
		}finally {
			jedis0.close();
		}
		String sql = "UPDATE account SET password='" + password + "'  where id=" + acc.id;
		DataBase.use().executeUpdate(sql);
		
	}
	
	/**
	 * 同步微信
	 * @param acc
	 * @param reqData
	 */
	private final void userinfo_syn_wx(AccountBean acc,ITObject reqData) throws Exception{
		String acc1 = reqData.getUtfString("acc");
		if(StringUtil.isNotEmpty(acc1)) {
			Jedis jedis0 = Redis.use("group1_db0").getJedis();
			RedisLock lock = new RedisLock("wx_"+acc1, jedis0);
			try {
				boolean update = false;
				String strNick = reqData.getUtfString("nick");
				strNick = StringUtil.filterEmoji(strNick);
				String portratit = reqData.getUtfString("portrait");
				update = !strNick.equals(acc.nick) || !portratit.equals(acc.portrait);

				if(update) {
					reqData.putUtfString("nick", strNick);
					ITObject userData = TObject.newInstance();
					userData.putUtfString("portrait", portratit);
					userData.putUtfString("nick", strNick);
					int sex = reqData.getInt("sex");
					if(sex == 0) {
						sex = 1;
						reqData.putInt("sex", sex);
					}
					userData.putInt("sex", sex);
					DataBase.use().update("account", userData, "id="+acc.id);
					updateSession(userData, acc.id);
				}
			}finally {
				lock.unlock();
			}
		}
	}

	private final void userinfo_portrait(AccountBean acc,ITObject reqData) throws Exception{
		logger.info("userinfo_portrait() ============> ");

		Integer iii = acc.id;
		String acc1 = iii.toString();
		if(StringUtil.isNotEmpty(acc1)) {
			Jedis jedis0 = Redis.use("group1_db0").getJedis();
			RedisLock lock = new RedisLock("wx_"+acc1, jedis0);

			String portrait = reqData.getUtfString("portrait");

			try {
				boolean update = true;

				if(update) {
					ITObject userData = TObject.newInstance();
					userData.putUtfString("portrait", portrait);

					DataBase.use().update("account", userData, "id="+acc.id);
					updateSession(userData, acc.id);
				}
			}finally {
				lock.unlock();
			}
		}
	}
	
	/**
	 * 更新玩家信息
	 * @throws Exception
	 */
	@ActionKey(value = Protocol.UPDATE_USER_INFO, validate=WebInterceptor.V_SESSION)
	public final void updateUserInfo() throws Exception {
		String session = this.getSession();
		ITObject reqData = this.getParams();
		ITObject resData = null;
		// 1 实名  2 地址  3密码  4手机 5邀请  6微信 
		int type = reqData.getInt("type");
		AccountBean acc = AccountCache.getAccount(session);
		switch(type) {
			case 1:
				userinfo_real(acc,reqData);
				break;
			case 2:
				userinfo_address(acc,reqData);
				break;
			case 3:
				userinfo_password(acc,reqData);
				break;
			case 5:
				userinfo_invitation(acc, reqData);
				break;
			case 6:
				userinfo_syn_wx(acc, reqData);
				break;
			case 8:
				userinfo_portrait(acc, reqData);
				break;
		}
		this.sendResponse(ErrorCode._SUCC, resData);
	}
	
	@ActionKey(value = Protocol.GET_USER_INFO, validate=WebInterceptor.V_SESSION)
	public final void getUserInfo() {
		String session = this.getSession();
		List<String> s_list = Redis.use("group1_db0").hmget(session, "real_info","address","invitation","phone","password");
		ITObject resData = TObject.newInstance();
		
		String real_info = s_list.get(0);
		if(StringUtil.isNotEmpty(real_info)) {
			ITObject real = TObject.newFromJsonData(real_info);
			resData.putTObject("real_info", real);
		}
		
		String address = s_list.get(1);
		if(StringUtil.isNotEmpty(address)) {
			resData.putUtfString("address", address);
		}

		String s_invitation = s_list.get(2);
		int invitation = 0;
		if(StringUtil.isNotEmpty(s_invitation)) {
			invitation = Integer.parseInt(s_invitation);
		}
		resData.putInt("invitation", invitation);
		
		String phone = s_list.get(3);
		if(StringUtil.isNotEmpty(phone)) {
			resData.putUtfString("phone", phone);
		}
		
		String password = s_list.get(4);
		if(StringUtil.isNotEmpty(password)) {
			resData.putUtfString("password", phone);
		}
		
		this.sendResponse(ErrorCode._SUCC, resData);
	}
	
	
	/**
	 * 更新信息
	 * @throws Exception
	 */
	@ActionKey(value = Protocol.UPDATE_PLAYER_INFO, validate=WebInterceptor.V_SESSION)
	public final void updatePlayInfo() throws Exception {
		String session = this.getSession();
		ITObject resData = TObject.newInstance();
			
		List<String> s_list = Redis.use("group1_db0").hmget(session, "id","diamo","invitation");
		
		int diamo = Integer.parseInt(s_list.get(1));
		resData.putInt("diamo", diamo);
		String s_invitation = s_list.get(2);
		
		int invitation = 0;
		if(StringUtil.isNotEmpty(s_invitation)) {
			invitation = Integer.parseInt(s_invitation);
		}
		resData.putInt("invitation", invitation);
		
		this.sendResponse(ErrorCode._SUCC, resData);
	}


	private static String updateSession(ITObject userData, int id) {
		String session = AccountCache.genKey(id);
		Map<String, String> map = new HashMap<String, String>();
		Utils.objectToMap(userData, map);

		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		try {
			jedis0.hmset(session, map);
			BaseCache.updateCacheVer(jedis0, session);
		}finally {
			jedis0.close();
		}
		
		return session;
	}

	
	
	/**
	 * 获取在线游戏
	 */
	public static ITArray getOnlineGames() {
		ITArray games = new TArray();
		Jedis jedis1 = Redis.use("group1_db1").getJedis();
		try {
			Set<String> list = jedis1.zrevrangeByScore("online_games", 1000, 1);
			for (String game : list) {
				int gameId = Integer.parseInt(game);
				GameBean gb = GameCache.getGame(gameId);
				if (gb == null)continue;
				ITObject gameObj = gb.getTObject();

				for (Entry<String, Integer> entry : gb.pay.entrySet()) {
					gameObj.putInt(entry.getKey(), entry.getValue());
				}
				games.addTObject(gameObj);
			}
		}finally {
			jedis1.close();
		}
		return games;
	}
}
