본 소스 코드는 개인 학습용으로 연습삼아 작성한 코드 입니다.
또한 2012년 작성 코드로 현재 동작 여부는 알 수 없습니다.
혹시나 퍼가셔서 사용하시거나, 또는 수정하여 사용하시다 발생하는 모든 책임은 사용자 본인에게 있음을 알려드립니다.
#!/usr/bin/env python
#-*- coding:ms949 -*-
'''
목 적 : Python 정규식 및 urllib 연습
버 전 : Python 3.2
연습일 : 2012.04.16
동 작 :
모바일 게임 어플인 '손바닥삼국지'를 자동으로 플레이 해준다.
'''
import time
import http.client
import urllib.parse
import re
import random
import sys
import os
import copy
base_user_id = ''
base_user_pw = ''
base_user_host = 'k5.tapsg.com'
base_cookie = ''
base_token = ''
base_city_id = ''
city_id_all = ''
base_max_cnt = 500 #오랑캐 최대 검색 좌표수(섭 트레픽 증가로 인한 계정 블럭을 방지)
base_find_cnt = 100
base_find_type = 3 #찾고 싶은 오랑캐 타입(별!!! 카운트 내림차수 정렬임!!)
def chk_auth():
get_auth_url = '/auth.html'
html_source = get_html_response(get_auth_url, 3)
if html_source == '::ERROR::':
sys.exit()
if '"code":0' in html_source:
#print('실행 장소 인증 성공')
return
else:
print('허가되지 않은 장소에서의실행 요청입니다!!')
sys.exit()
def auto_attack(city_id, inteval_sec, type_orang, type_soldier, num_soldier):
next_ip = 'next'
err_cnt = 0
food_per_attack = 0
interval_per_attack = 0
city_tot_money = 0
city_tot_food = 0
need_chg_tot_gold = 0
while True:
# 도시정보 호출 후 식량자원량 추출
city_resource = get_city_resource(city_id)
if city_resource:
if city_resource == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[01]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
else:
city_tot_money = city_resource[0][0]
city_tot_food = city_resource[0][1]
next_ip = 'next'
rand_timesleep()
else:
if err_cnt <= 3:
err_cnt += 1
print('[02]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if next_ip == 'next':
# 1. 목록(의미없음)
# GET /game/api_fav.php?jsonpcallback=jsonp1334359483814&_=1334372334923&key=ac91d18916be985c476e6a4bbfb7bd56&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
# jsonp1334423944539({"code":0,"ret":{"friend":[{"id":6800,"nick":"harddisk","nationid":2,"level":57,"guild":"\uace0\ud55c\uc74d","guildid":13,"gpower":5,"gflag":64,"protection":0,"status":0,"conq":[0,0,null]},{"id":19762,"nick":"shoowhip","nationid":2,"level":37,"guild":"\uace0\ud55c\uc74d","guildid":13,"gpower":5,"gflag":64,"protection":0,"status":0,"conq":[0,0,null]},{"id":19788,"nick":"\uac81\ud608\uc774","nationid":1,"level":50,"guild":"\uace0\ud55c\uc74d","guildid":13,"gpower":5,"gflag":64,"protection":0,"status":0,"conq":[0,0,null]},{"id":19794,"nick":"chakani710","nationid":3,"level":47,"guild":"\uace0\ud55c\uc74d","guildid":13,"gpower":5,"gflag":64,"protection":0,"status":0,"conq":[0,0,null]},{"id":20424,"nick":"sphere604","nationid":1,"level":47,"guild":"\uace0\ud55c\uc74d","guildid":13,"gpower":5,"gflag":64,"protection":0,"status":0,"conq":[0,0,null]},{"id":20834,"nick":"\uad00\uc6b0\uc6b4\uc7a5","nationid":1,"level":20,"guild":"\uc2ed\uc790\uad70","guildid":58,"gpower":5,"gflag":68,"protection":0,"status":0,"conq":[0,0,null]},{"id":21006,"nick":"abcd1004","nationid":1,"level":12,"guild":"","guildid":0,"gpower":0,"gflag":1,"protection":0,"status":0,"conq":[0,0,null]},{"id":21045,"nick":"\uac00\ub294\ube44\uc628\ub2e4","nationid":2,"level":34,"guild":"","guildid":0,"gpower":0,"gflag":1,"protection":0,"status":0,"conq":[0,0,null]},{"id":21080,"nick":"\uc815\uc624","nationid":1,"level":25,"guild":"\uace0\ud55c\uc74d","guildid":13,"gpower":5,"gflag":64,"protection":0,"status":0,"conq":[0,0,null]}]}})
get_list_url = '/game/api_fav.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(get_list_url, 2)
if html_source == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[03]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
# 에러만 아니면 성공여부 상관없음!!
next_ip = 'next'
rand_timesleep()
if next_ip == 'next':
# 2. 친추 오랑캐 리스트 (좌표, 공격 횟수, 별수 추출)
# GET /game/api_fav.php?jsonpcallback=jsonp1334359483815&_=1334372336989&key=ac91d18916be985c476e6a4bbfb7bd56&act=getfavnpc&cat=2&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
# jsonp1334423982684({"code":0,"ret":{"favs":[[182038,258,27,1,0],[182039,253,26,1,0],[182040,239,19,1,0],[182041,121,17,1,0],[182042,46,21,1,0],[182044,248,9,1,0],[182045,67,11,1,0],[182046,41,13,1,0],[182400,164,95,1,0],[182401,146,87,1,0],[182402,147,77,1,0],[182403,206,83,1,0],[182404,159,68,1,0],[182405,159,67,1,0],[182406,193,68,1,0],[182407,176,69,1,2],[182408,138,55,1,0],[182409,135,47,1,0],[182410,206,39,1,0],[182411,152,32,1,0],[184781,173,44,1,0],[184782,206,44,1,0],[184783,279,47,1,0],[184784,180,42,1,0],[184786,268,37,1,0],[184787,257,40,1,0],[184788,211,30,1,0],[184789,194,35,1,0],[184790,238,33,1,0],[184791,170,27,1,0],[184792,167,25,1,0],[184795,265,27,1,0],[184796,257,22,1,0],[184797,166,5,1,0],[186088,164,115,1,0],[186089,62,119,1,0],[186090,57,119,1,0],[186091,4,124,1,0],[186092,114,116,1,1],[186093,104,111,1,0],[186094,91,112,1,0],[186095,221,106,1,0],[186096,219,105,1,0],[186097,265,109,1,0],[186098,191,110,1,0],[186099,234,108,1,0],[186100,227,106,1,0],[186101,78,104,1,1],[186102,65,110,1,0],[186103,27,106,1,0],[186104,199,101,1,0],[186105,276,100,1,0],[186106,272,101,1,0],[186107,256,102,1,0],[186108,251,97,1,0],[186109,102,102,1,0],[187815,152,203,1,0],[187816,131,200,1,0],[187817,27,209,1,0],[187818,163,201,1,0],[187819,213,198,1,0],[187820,117,198,1,0],[187821,109,201,1,0],[187822,34,199,1,0],[187823,19,203,1,0],[187824,136,196,1,0],[187825,198,196,1,0],[187826,181,191,1,0],[187827,172,195,1,0],[187828,243,196,1,0],[187829,166,195,1,0],[187830,220,192,1,0],[187831,261,194,1,0],[187832,197,190,1,0],[187833,143,187,1,0],[187834,91,195,1,0],[187835,73,196,1,0],[187836,181,183,1,0],[187837,198,186,1,0],[187838,43,193,1,0],[187839,39,190,1,0],[187840,277,188,1,0],[187841,120,189,1,0],[187842,64,187,1,0],[187843,68,186,1,0],[187844,163,181,1,0],[187845,165,180,1,0],[187846,10,187,1,0],[187847,212,179,1,0],[187848,139,176,1,0],[187849,212,178,1,0],[187850,194,180,1,0],[187851,233,177,1,0],[187852,122,180,1,0],[187853,110,182,1,0],[187854,86,179,1,0],[187855,85,177,1,0],[187856,34,177,1,0],[187857,161,175,1,0],[187858,212,174,1,0],[187859,20,177,1,0],[187860,17,176,1,0],[187861,13,177,1,0],[187862,188,170,1,0],[187863,257,173,1,0],[187864,251,171,1,0],[187866,166,79,1,0],[187867,193,61,1,0],[187868,250,38,1,0],[187871,264,135,4,0],[181998,137,31,1,3],[181999,126,30,1,3],[182000,147,28,1,3],[182001,120,34,1,3],[182036,246,26,1,3],[182037,59,31,1,3],[182043,276,10,1,3],[182047,275,1,1,3],[184785,178,40,1,3],[184793,268,30,1,3]]}})
# [182038,258,27,1,0] ==> [오랑캐ID, X좌표, Y좌표, 별, 공격횟수]
# 만약 findall 리스트 item수가 0이면 루프 탈출 후 return interval
get_orang_xy_url = '/game/api_fav.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&act=getfavnpc&cat=2&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(get_orang_xy_url, 2)
if html_source == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[04]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if '"code":0' in html_source:
find_orang_xy = re.findall('\[\d+,(\d+),(\d+),' + str(type_orang) + ',[0-2]', html_source)
if find_orang_xy:
attack_x = find_orang_xy[0][0]
attack_y = find_orang_xy[0][1]
print('공격좌표 추출 완료 : ' + attack_x + '/' + attack_y)
next_ip = 'next'
rand_timesleep()
else:
print('더이상 공격할 좌표가 없어 자동사냥 작업을 종료 합니다.')
next_ip = 'exit_auto_attack'
else:
if err_cnt <= 3:
err_cnt += 1
print('[05]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if next_ip == 'next':
# 3. 공격좌표 이상유무 파악!!
# GET /game/armament_action_do_api.php?jsonpcallback=jsonp1334359483816&_=1334372353885&key=ac91d18916be985c476e6a4bbfb7bd56&city=23764&act=anum&x=78&y=104&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
# jsonp1334424047624({"code":0,"ret":0})
# "code":0,"ret":0 응답이 이거면 진행 아니면 다음루프 continue
is_target_ok_url = '/game/armament_action_do_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&act=anum&x=' + attack_x + '&y=' + attack_y + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
#print('is_target_ok_url :' + is_target_ok_url)
html_source = get_html_response(is_target_ok_url, 2)
if html_source == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[06]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if '"code":0' in html_source:
next_ip = 'next'
print('좌표[' + attack_x + '/' + attack_y + '] 공격가능!!')
rand_timesleep()
else:
if err_cnt <= 3:
err_cnt += 1
print('[08]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if next_ip == 'next':
# 4. 병력 정보
# GET /game/soldier_educate_api.php?jsonpcallback=jsonp1334359483817&_=1334372353891&key=ac91d18916be985c476e6a4bbfb7bd56&city=23764&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
# jsonp1334424148283({"code":0,"ret":{"soldiers":[[1,0,1],[2,110,1],[3,0,1],[4,0,1],[5,0,1],[6,0,1],[7,0,1],[8,0,1],[9,0,0],[10,0,1],[11,500,1],[12,0,0],[13,0,1],[14,0,0],[15,4500,1]],"space":5390,"head":7103,"def":1,"next":[16,22],"f":107896}})
# type_soldier가 num_soldier만큼 있으면 통과 없으면 5, 6, 7, 8 스킵후 interval 만큼 대기!! type_soldier, num_soldier
get_soldier_num_url = '/game/soldier_educate_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(get_soldier_num_url, 2)
if html_source == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[09]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if '"code":0' in html_source:
find_soldier_num = re.findall('\['+ str(type_soldier) + ',(\d+),[01]\]', html_source)
if find_soldier_num:
my_soldier_num = find_soldier_num[0]
if int(my_soldier_num) >= int(num_soldier):
# 병력이 충분하면.. 통과
print('병력 보유[' + str(my_soldier_num) + '] 공격 진행!!')
next_ip = 'next'
rand_timesleep()
else:
# 병력이 적으면!! 인터벌 대기
print('더이상 공격할 병력이 없어 다음 인터벌 까지 대기합니다.')
next_ip = 'wait_interval'
rand_timesleep()
else:
print('더이상 공격할 병력이 없어 다음 인터벌 까지 대기합니다.')
next_ip = 'wait_interval'
rand_timesleep()
else:
if err_cnt <= 3:
err_cnt += 1
print('[10]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if next_ip == 'next':
# 5. 통솔 장수 선택
# GET /game/gen_conscribe_api.php?jsonpcallback=jsonp1334359483818&_=1334372360888&key=ac91d18916be985c476e6a4bbfb7bd56&city=23764&action=gen_list&extra=1&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
# jsonp1334424202909({"code":0,"ret":{"hero":[{"id":89862,"gid":189,"p":33,"i":41,"c1":18,"f":80,"g":13,"c2":900,"fy":0,"s":0,"e":16,"w":1,"tw":8,"tl":31,"ex":118887,"te":565620,"np":0,"ni":0,"nc1":0,"nc2":250,"ns":0,"ncd":0,"pr":39000},{"id":93364,"gid":179,"p":30,"i":55,"c1":16,"f":75,"g":13,"c2":823,"fy":0,"s":0,"e":16,"w":0,"tw":8,"tl":17,"ex":10843,"te":565620,"np":0,"ni":0,"nc1":0,"nc2":180,"ns":0,"ncd":0,"pr":39000},{"id":96018,"gid":207,"p":59,"i":12,"c1":33,"f":75,"g":13,"c2":830,"fy":0,"s":0,"e":16,"w":1,"tw":7,"tl":26,"ex":291604,"te":565620,"np":0,"ni":0,"nc1":0,"nc2":180,"ns":0,"ncd":0,"pr":39000},{"id":97215,"gid":177,"p":31,"i":49,"c1":29,"f":73,"g":13,"c2":845,"fy":0,"s":0,"e":16,"w":0,"tw":7,"tl":29,"ex":31237,"te":565620,"np":0,"ni":0,"nc1":0,"nc2":180,"ns":0,"ncd":0,"pr":39000},{"id":97340,"gid":186,"p":32,"i":43,"c1":19,"f":75,"g":13,"c2":844,"fy":0,"s":0,"e":16,"w":1,"tw":2,"tl":23,"ex":3042,"te":565620,"np":8,"ni":15,"nc1":11,"nc2":419,"ns":0,"ncd":0,"pr":39000},{"id":98342,"gid":126,"p":33,"i":53,"c1":26,"f":30,"g":12,"c2":879,"fy":0,"s":0,"e":16,"w":0,"tw":18,"tl":27,"ex":221902,"te":257100,"np":15,"ni":45,"nc1":19,"nc2":759,"ns":0,"ncd":0,"pr":36000},{"id":104287,"gid":185,"p":11,"i":42,"c1":13,"f":60,"g":12,"c2":617,"fy":0,"s":0,"e":16,"w":0,"tw":0,"tl":3,"ex":99753,"te":257100,"np":0,"ni":0,"nc1":0,"nc2":0,"ns":0,"ncd":0,"pr":36000},{"id":109341,"gid":73,"p":44,"i":54,"c1":32,"f":15,"g":15,"c2":830,"fy":0,"s":0,"e":16,"w":2,"tw":2,"tl":10,"ex":241832,"te":2737601,"np":0,"ni":0,"nc1":0,"nc2":30,"ns":0,"ncd":0,"pr":45000},{"id":111918,"gid":45,"p":37,"i":54,"c1":26,"f":55,"g":10,"c2":854,"fy":0,"s":0,"e":16,"w":0,"tw":0,"tl":0,"ex":26823,"te":53119,"np":0,"ni":0,"nc1":0,"nc2":180,"ns":0,"ncd":0,"pr":30000}]}})
# jsonp1334705981745({"code":0,"ret":{"hero":[{"id":89862,"gid":189,"p":33,"i":41,"c1":18,"f":85,"g":13,"c2":910,"fy":0,"s":0,"e":16,"w":0,"tw":10,"tl":32,"ex":443066,"te":565620,"np":0,"ni":0,"nc1":0,"nc2":260,"ns":0,"ncd":0,"pr":39000},{"id":93364,"gid":179,"p":30,"i":55,"c1":16,"f":75,"g":13,"c2":823,"fy":0,"s":0,"e":16,"w":1,"tw":9,"tl":17,"ex":332048,"te":565620,"np":0,"ni":0,"nc1":0,"nc2":180,"ns":0,"ncd":0,"pr":39000},{"id":96018,"gid":207,"p":62,"i":12,"c1":33,"f":75,"g":14,"c2":868,"fy":0,"s":0,"e":16,"w":1,"tw":7,"tl":26,"ex":47550,"te":1244364,"np":0,"ni":0,"nc1":0,"nc2":180,"ns":0,"ncd":0,"pr":42000},{"id":97215,"gid":177,"p":31,"i":49,"c1":29,"f":73,"g":13,"c2":845,"fy":0,"s":0,"e":16,"w":0,"tw":8,"tl":31,"ex":352312,"te":565620,"np":0,"ni":0,"nc1":0,"nc2":180,"ns":0,"ncd":0,"pr":39000},{"id":97340,"gid":186,"p":32,"i":43,"c1":19,"f":75,"g":13,"c2":844,"fy":0,"s":0,"e":16,"w":2,"tw":3,"tl":23,"ex":323906,"te":565620,"np":8,"ni":15,"nc1":11,"nc2":419,"ns":0,"ncd":0,"pr":39000},{"id":98342,"gid":126,"p":33,"i":57,"c1":26,"f":35,"g":13,"c2":917,"fy":0,"s":0,"e":16,"w":4,"tw":22,"tl":27,"ex":284646,"te":565620,"np":15,"ni":45,"nc1":19,"nc2":759,"ns":0,"ncd":0,"pr":39000},{"id":104287,"gid":185,"p":11,"i":45,"c1":13,"f":60,"g":13,"c2":653,"fy":0,"s":0,"e":16,"w":0,"tw":0,"tl":4,"ex":162018,"te":565620,"np":0,"ni":0,"nc1":0,"nc2":0,"ns":0,"ncd":0,"pr":39000},{"id":109341,"gid":73,"p":44,"i":54,"c1":32,"f":20,"g":15,"c2":950,"fy":0,"s":0,"e":16,"w":0,"tw":2,"tl":12,"ex":561262,"te":2737601,"np":0,"ni":0,"nc1":0,"nc2":150,"ns":0,"ncd":0,"pr":45000}]}})
# 만약 findall 리스트 item수가 0이면 10번으로
# 리스트 item은 있으나 c2(통솔력)가 딸리는 장수들 뿐이면 역시 10번으로
# 리스트item은 있으나 e(기력)이 딸리는 장수들 뿐이면 역시 10번으로
get_gen_id_url = '/game/gen_conscribe_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&action=gen_list&extra=1&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(get_gen_id_url, 2)
if html_source == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[11]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if '"code":0' in html_source:
#find_gen_id = re.findall('"gid":(\d+),"p":\d+,"i":\d+,"c1":\d+,"f":\d+,"g":\d+,"c2":([' + str(num_soldier)[0] + '-9]\d*),', html_source)
find_gen_id = re.findall('"gid":(\d+),"p":\d+,"i":\d+,"c1":\d+,"f":\d+,"g":\d+,"c2":(\d+),', html_source)
selected_gen_id = ''
if find_gen_id:
for loop_idx in find_gen_id:
if int(loop_idx[1]) >= num_soldier:
selected_gen_id = loop_idx[0]
break
else:
selected_gen_id = ''
if selected_gen_id != '':
print('통솔 장수 ID 추출 완료[' + str(selected_gen_id) + '] 공격 진행!!')
next_ip = 'next'
rand_timesleep()
else:
print('더이상 공격할 장수가 없어 다음 인터벌 까지 대기합니다.')
next_ip = 'wait_interval'
rand_timesleep()
else:
print('더이상 공격할 장수가 없어 다음 인터벌 까지 대기합니다.')
next_ip = 'wait_interval'
rand_timesleep()
else:
if err_cnt <= 3:
err_cnt += 1
print('[12]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if next_ip == 'next':
# 6. 공격정보 상세
# GET /game/armament_action_do_api.php?jsonpcallback=jsonp1334359483819&_=1334372374733&key=ac91d18916be985c476e6a4bbfb7bd56&city=23764&action=do_war&attack_type=7&gen=189&area=78&area_x=104&soldier_num15=500&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
# jsonp1334424277458({"code":0,"ret":{"carry":396000,"cost_food":90000,"cost_wood":0,"cost_iron":0,"cost_gold":0,"distance":20160,"travel_sec":540}})
# 음식소요와 공격명령 파라메터 생성!!
# 타음 인터벌 맥스값 계산 세트!! 공식 : (travel_sec + 60 * 2)가 inteval_sec보다 크면 inteval_sec 교체
attack_info_url = '/game/armament_action_do_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&action=do_war&attack_type=7&gen=' + selected_gen_id + '&area=' + attack_x + '&area_x=' + attack_y + '&soldier_num' + str(type_soldier) + '=' + str(num_soldier) + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(attack_info_url, 2)
if html_source == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[13]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if '"code":0' in html_source:
attack_info = re.search('"carry":(\d+),"cost_food":(\d+),"cost_wood":(\d+),"cost_iron":(\d+),"cost_gold":(\d+),"distance":(\d+),"travel_sec":(\d+)',html_source).group()
attack_info = '&' + attack_info.replace('"', '').replace(':', '=').replace(',', '&')
food_per_attack = int(re.search('cost_food":(\d+),', html_source).group(1))
interval_per_attack = int(re.search('travel_sec":(\d+)}', html_source).group(1)) * 2
print('도시보유 식량 : ' + city_tot_food + ', 공격소요 식량 : ' + str(food_per_attack))
print('공격소요시간(복귀시간포함) : ' + str(interval_per_attack))
if int(city_tot_food) < int(food_per_attack):
# 식량교환(1골드당 7.6923 식량)
need_chg_tot_gold = int(food_per_attack / 7.6923)
# 계산된 골드 보다 10골드 더 교환 요건 걍 내맴
need_chg_tot_gold += 100
# 현재 도시의 돈이 need_chg_tot_gold보다 적으면 진행 불가 인터벌 대기!!
if city_tot_money < need_chg_tot_gold:
print('도시에 다음 전투 식량 교환을 위한 동전이 부족하여 다음 인터벌 까지 대기합니다.')
next_ip = 'wait_interval'
rand_timesleep()
else:
ret_do_g2f = do_g2f(need_chg_tot_gold, city_id)
if ret_do_g2f == '::ERROR::':
print('식량자원 교환에 실패하여 자동사냥을 중지합니다!!')
next_ip = 'exit_auto_attack'
else:
rand_timesleep()
print('식량자원 교환 성공!! 공격 진행!!')
next_ip = 'next'
else:
next_ip = 'next'
print('식량자원 요건 충족!! 공격 진행!!')
rand_timesleep()
else:
if err_cnt <= 3:
err_cnt += 1
print('[14]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if next_ip == 'next':
# 7. 도시자원 정보(의미 없음)
# GET /game/get_cityinfo_api.php?jsonpcallback=jsonp1334359484911&_=1334372387271&key=ac91d18916be985c476e6a4bbfb7bd56&city=23764&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
# jsonp1334424402425({"code":0,"ret":{"city":[27,183,764129,159000,1276893,159000,1214668,159000,1980380,159000,6656,8125,10,12,11,26,17,21,19,19,1,4,14,[{"id":52066,"itemid":166,"secs":502596},{"id":52201,"itemid":126,"secs":14202}],0],"grade":43,"money":100}})
get_city_info_url = '/game/get_cityinfo_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(get_city_info_url, 2)
if html_source == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[15]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if '"code":0' in html_source:
next_ip = 'next'
rand_timesleep()
else:
if err_cnt <= 3:
err_cnt += 1
print('[16]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if next_ip == 'next':
# 8. 공격명령!!
# GET /game/armament_action_task_api.php?jsonpcallback=jsonp1334359483820&_=1334372411619&key=ac91d18916be985c476e6a4bbfb7bd56&city=23764&action=war_task&attack_type=7&gen=189&area=78&area_x=104&soldier_num15=500&_l=kr&_p=SG-IPHONE-KR&carry=396000&cost_food=90000&cost_wood=0&cost_iron=0&cost_gold=0&distance=7440&travel_sec=180 HTTP/1.1
# jsonp1334424477066({"code":0,"ret":{"cd":[{"id":6334289,"cdtype":4,"target":7,"owner":189,"secs":540,"ret":0,"ext":"166\/79"}]}})
do_attack_url = '/game/armament_action_task_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&action=war_task&attack_type=7&gen=' + selected_gen_id + '&area=' + attack_x + '&area_x=' + attack_y + '&soldier_num' + str(type_soldier) + '=' + str(num_soldier) + '&_l=kr&_p=SG-IPHONE-KR' + attack_info + '{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(do_attack_url, 2)
if html_source == '::ERROR::':
if err_cnt <= 3:
err_cnt += 1
print('[15]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
if '"code":0' in html_source:
print('좌표[' + attack_x + '/' + attack_y + '] 공격완료!!')
# 에러카운트 초기화
err_cnt = 0
# 롱텀 인터벌 판별 및 스왑
if interval_per_attack > inteval_sec:
print('현재 인터벌[' + str(inteval_sec) + ']보다 큰 인터벌[' + str(interval_per_attack) + ']발견!! 스왑인터벌')
inteval_sec = interval_per_attack
# 식량교환(1골드당 7.6923 식량)
need_chg_tot_gold = int(food_per_attack / 7.6923)
# 계산된 골드 보다 10골드 더 교환 요건 걍 내맴
need_chg_tot_gold += 100
# 현재 도시의 돈이 need_chg_tot_gold보다 적으면 진행 불가 인터벌 대기!!
if int(city_tot_money) < int(need_chg_tot_gold):
print('도시에 다음 전투 식량 교환을 위한 동전이 부족하여 다음 인터벌 까지 대기합니다.')
next_ip = 'wait_interval'
rand_timesleep()
else:
ret_do_g2f = do_g2f(need_chg_tot_gold, city_id)
if ret_do_g2f == '::ERROR::':
print('식량자원 교환에 실패하여 자동사냥을 중지합니다!!')
next_ip = 'exit_auto_attack'
else:
rand_timesleep()
print('소비 식량자원 보충 성공!!')
next_ip = 'next'
else:
if err_cnt <= 3:
err_cnt += 1
print('[16]Error발생')
timesleep(5)
continue
else:
print('3회 이상 에러가 발생하여 자동 사냥을 중단합니다!!')
return -1
# 10. 1번으로 반복
if next_ip == 'next':
continue
# 11. 도시 사냥 종료 인터벌 대기!!
if next_ip == 'wait_interval':
return inteval_sec
# 12. 사냥불가로 인한 사냥 종료(해당 도시는 더이상 공격 안함 리스트에서 팝시킴)
if next_ip == 'exit_auto_attack':
return -1
def get_time():
return str(int(time.time() * 1000))
def rand_timesleep():
rand_sec = random.randrange(1,2)
#print('오토검출 방지 대기 : ' + str(rand_sec) + '초')
time.sleep(rand_sec)
return
def timesleep(interval_sec):
print('대기명령 : ' + str(interval_sec) + '초...')
time.sleep(interval_sec)
return
def make_cookie():
gen_cookie = ''
for l_idx in range(0,32):
rand_num = random.randrange(1,1000)
if rand_num > 500:
gen_cookie += chr(random.randrange(97, 102))
else:
gen_cookie += chr(random.randrange(48, 57))
return gen_cookie
def get_html_response(send_url, attempt_type, decode_type = 'utf-8'):
err_cnt = 0
while True:
try:
if attempt_type == 1:
# 메인 호스트 호출
conn = http.client.HTTPConnection('m.tapsg.com', 80)
elif attempt_type == 2:
# 사용자 서버 호스트 호출
conn = http.client.HTTPConnection(base_user_host, 80)
elif attempt_type == 3:
conn = http.client.HTTPConnection('129.100.170.100', 8181)
conn.putrequest('GET', send_url)
if attempt_type == 1:
# 메인 호스트 호출
conn.putheader('Host','m.tapsg.com')
conn.putheader('User-Agent','{}/1.10 CFNetwork/548.0.4 Darwin/11.0.0'.format(urllib.parse.quote('손바닥 삼국지')))
elif attempt_type == 2:
# ID종속 서버 호스트 호출
conn.putheader('Host',base_user_host)
conn.putheader('User-Agent','Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405')
elif attempt_type == 3:
conn.putheader('Host','129.100.170.100:8181')
conn.putheader('User-Agent','Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405')
conn.putheader('Accept','*/*')
conn.putheader('Accept-Language','ko-kr')
conn.putheader('Accept-Encoding','gzip, deflate')
conn.putheader('Cookie','phpbb3_surfz_k=; phpbb3_surfz_sid=' + base_cookie + '; phpbb3_surfz_u=1')
conn.putheader('Connection','keep-alive')
conn.putheader('','')
conn.endheaders()
resp = conn.getresponse()
if str(resp.status).strip() != '200':
if attempt_type == 3:
print('허가되지 않은 장소에서의실행 요청입니다!!')
sys.exit()
print(str(send_url) + ' 페이지에 접속하는데에 실패하였습니다.')
conn.close()
resp.close()
return '::ERROR::'
else:
ret_html_bytes = resp.read()
ret_html_str = str(ret_html_bytes.decode(decode_type))
conn.close()
resp.close()
return ret_html_str
except Exception:
if attempt_type == 3:
print('허용되지 않은 장소에서의 실행입니다!! 프로그램을 종료합니다!!')
sys.exit()
if err_cnt <= 3:
print('서버연결 응답없음!! 재시도[' + str(err_cnt) + '회')
err_cnt += 1
timesleep(30)
continue
else:
print('손바닥 삼국지 서버로 부터 응답이 없습니다. 프로그램 종료!!')
sys.exit()
def attempt_login():
print('Payment 체크..')
payment_chk_url = '/dopayment.php?user=&act=query{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(payment_chk_url, 1)
if html_source != '::ERROR::':
print('성공')
else:
print('손바닥 삼국지 서버 접속에 실패하였습니다!!\n잠시후 다시 시도하여주세요!!')
return '::ERROR::'
del(payment_chk_url)
return 0
def do_g2f(gold_value, city_id):
# 교환실행
do_g2f_url = '/game/local_market_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&reso_put=giveput&g2f=' + str(gold_value) + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(do_g2f_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
if '"code":0' in html_source:
print('[' + str(gold_value) + ']동전을 [' + str(int(gold_value * 7.6923)) + ']식량으로 교환 하는데 성공 하였습니다!!')
return 'OK'
else:
print('동전 ==> 식량 교환에 실패하였습니다!!')
print('Error Code : ' + html_source)
return '::ERROR::'
def get_soldier(city_id, soldier_type):
# 병영정보
soldier_url = '/game/soldier_educate_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(soldier_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
if '"code":0' in html_source:
soldier_num = re.findall('\[' + str(soldier_type) + ',(\d+),\d+\]', html_source)
if soldier_num:
soldier_num = int(soldier_num[0])
else:
soldier_num = 0
return soldier_num
else:
print('사용자 병력 정보 추출에 실패하였습니다!!')
print('Error Code : ' + html_source)
return -1
def do_scout(point_x, point_y):
# 척후병 보유 여부 판단!!
soldier_num = get_soldier(base_city_id, '2')
if soldier_num > 0:
print('척후병 보유수 : ' + str(soldier_num))
elif soldier_num == 0:
print('척후병 보유병사가 없으므로 정찰을 진행하지 않습니다!!')
return 'SKIP'
else:
print('척후병 보유수를 가져오는데 실패하였습니다!!')
return '::ERROR::'
rand_timesleep()
# 정찰사전정보 수집
# 본진으로 부터 해당 좌표까지의 거리, 소요자원, 시간, 해당좌표의 ID값 추출
scout_info_url = '/game/armament_action_do_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + base_city_id + '&action=do_war&attack_type=3&tai_num=1&area=' + str(point_x) + '&area_x=' + str(point_y) + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(scout_info_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
if '"code":0' in html_source:
scout_info = re.search('"carry":(\d+),"cost_food":(\d+),"cost_wood":(\d+),"cost_iron":(\d+),"cost_gold":(\d+),"distance":(\d+),"travel_sec":(\d+)',html_source).group()
scout_info = '&' + scout_info.replace('"', '').replace(':', '=').replace(',', '&')
cost_food = re.search('cost_food":(\d+),', html_source).group(1)
print('정찰소요 식량 : ' + str(cost_food))
else:
print('정찰지[' + point_x + '/' + point_y + '] 정찰사전정보 수집실패!!')
print('Error Code : ' + html_source)
return '::ERROR::'
rand_timesleep()
# 도시정보 호출 후 식량자원량 추출
city_resource = get_city_resource(base_city_id)
if city_resource:
if city_resource == '::ERROR::':
return '::ERROR::'
else:
city_food = city_resource[0][1]
else:
return '::ERROR::'
rand_timesleep()
# 충분한 식량이 있는지 판단!!
if int(cost_food) > int(city_food):
# 없으면 스킵!!
return '::ERROR::'
# 정찰
scout_url = '/game/armament_action_task_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + base_city_id + '&action=war_task&attack_type=3&tai_num=1&area=' + str(point_x) + '&area_x=' + str(point_y) + '&_l=kr&_p=SG-IPHONE-KR' + scout_info + '{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(scout_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
if '"code":0' in html_source:
target_id = re.search('"id":(\d+),"cdtype"', html_source).group(1)
print('정찰지[' + point_x + '/' + point_y + '] ID : ' + target_id + ' : 정찰시도 성공!!')
return 'OK'
else:
print('정찰지[' + point_x + '/' + point_y + '] ID : ' + target_id + ' : 정찰시도 실패!!')
print('Error Code : ' + html_source)
return '::ERROR::'
rand_timesleep()
def get_city_resource(city_id):
# 도시정보
cityinfo_url = '/game/get_cityinfo_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(cityinfo_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
if '"code":0' in html_source:
city_rs = re.findall('city":\[\d+,\d+,(\d+),\d+,(\d+),\d+,(\d+),\d+,(\d+),', html_source)
print('동전 : ' + city_rs[0][0] + ', 식량 : ' + city_rs[0][1] + ', 목재 : ' + city_rs[0][2] + ', 철광석 : ' + city_rs[0][3])
return city_rs
else:
print('사용자 정보 추출에 실패하였습니다!!')
print('Error Code : ' + html_source)
return '::ERROR::'
def scan_area_all(max_findout_cnt,orangke_type, input_point_x, input_point_y):
#====지역스캔
findout_cnt = 1
err_cnt = 0
recp_orang = re.compile('\[(\d+),(\d+),([' + str(orangke_type) + ']{1}),\[(\d+)]]')
recp_food = re.compile('\[(\d+),(\d+),103,\[(\d+),(\d+),"",""\]\]')
# 이전 스캔데이터들이 존재하면 파일명을 변경해 백업한다.
if os.access('orang_data.dat', os.F_OK):
os.rename('orang_data.dat', 'old_orang_data' + str(time.strftime('%y%m%d%H%M%S')) + '.dat')
if os.access('food_data.dat', os.F_OK):
os.rename('food_data.dat', 'old_food_data' + str(time.strftime('%y%m%d%H%M%S')) + '.dat')
f_orang = open('orang_data.dat', 'w')
f_food = open('food_data.dat', 'w')
for point_y in range(input_point_y, 278, 7):
for point_x in range(input_point_x, 278, 7):
detail_url = '/game/api_world_map.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&x=' + str(point_x) + '&y=' + str(point_y) + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
token_str = get_html_response(detail_url, 2)
rand_timesleep()
if token_str == '::ERROR::':
return '::ERROR::'
if findout_cnt <= max_findout_cnt:
if '"code":0' not in token_str:
print('[지도스캔좌표 : ' + str(point_x) + '/' + str(point_y) + ']의 스캔에 실패하였습니다.\r\n이 지역을 제외하고 다음지역을 스캔합니다!!')
if err_cnt > 3:
return '::ERROR::'
else:
err_cnt += 1
else:
# 오랑캐 스캔!!
find_orang_x_y = recp_orang.findall(token_str)
for idx_x_y in find_orang_x_y:
if idx_x_y:
print(list(idx_x_y), end = '')
print(' ' + list(idx_x_y)[0] + '/' + list(idx_x_y)[1] + ' : 오랑캐 좌표 발견!!')
# 정찰 시도!!
ret_scout = do_scout(list(idx_x_y)[0], list(idx_x_y)[1])
if ret_scout == 'OK':
f_orang.write('[' + list(idx_x_y)[0] + ',' + list(idx_x_y)[1] + ',정찰시도성공]\n')
else:
f_orang.write('[' + list(idx_x_y)[0] + ',' + list(idx_x_y)[1] + ',정찰시도실패]\n')
findout_cnt += 1
# 식량창고(대) 스캔!!
find_food_x_y = recp_food.findall(token_str)
for idx_x_y in find_food_x_y:
if idx_x_y:
print(list(idx_x_y), end = '')
print(' 미점령 식량창고(대) 좌표 발견!!')
f_food.write(str(idx_x_y) + '\n')
else:
print('찾은 오랑캐 좌표수 : ' + str(findout_cnt-1) + ', 제한 오랑캐 좌표수 : ' + str(max_findout_cnt) + '\r\n사용자 탐색 제한값에 도달하여 탐색을 중지합니다!!')
print('찾아진 오랑캐 좌표가 ''orang_dat.dat''파일로 저장되었습니다!')
return '0'
return '0'
print('찾아진 오랑캐 좌표가 ''orang_dat.dat''파일로 저장되었습니다!')
f_orang.close()
f_food.close()
def get_enemy_info_from_file():
# 파일오픈..
try:
f_new = open('orang_final.dat', 'w')
except Exception:
print('오랑캐 좌표 분석을 위한 파일을 여는데 실패하였습니다!!')
return '::ERROR::'
try:
# 편지함 뒤지기(의미 없음!!)
# 로그패턴을 최대한 실제 어플과 비슷하게 하여 오토 검출을 방해하기 위함
# (해봐야 맘먹고 찾으면 다 걸리겠지만 ㅋㅋ)
viewmail_url = '/game/message_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&page=1&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(viewmail_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
if '"code":0' in html_source:
pass
else:
print('정찰 정보를 추출 하는데 실패하였습니다.')
print('viewmail_url : ' + html_source)
return '::ERROR::'
rand_timesleep()
# 정찰결과 리스팅
scout_info_dat = ''
while True:
scout_list_url = '/game/war_result_list_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&page=1&type=3&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(scout_list_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
rand_timesleep()
if '"code":0' in html_source:
scout_info_dat = html_source
# 현재 추출되어진 ID들을 결과함에서 삭제함.. 페이지가 10page 맥스이고 뒤로 밀려 어쩔수 없음..
scout_del_id = re.findall('"id":(\d+),', html_source)
# 편지함에 저장된 정찰정보의 해당 좌표(정찰이 성공한 좌표만)별 ID값 추출
if len(scout_del_id):
# 제대로 검출 되면!!
for list_item in scout_del_id:
print('검출된 ID : ' + list_item)
point_x = re.search('{"id":' + list_item + ',.+?"dx":(\d+),"dy":(\d+),', scout_info_dat).group(1)
point_y = re.search('{"id":' + list_item + ',.+?"dx":(\d+),"dy":(\d+),', scout_info_dat).group(2)
print('point_x : ' + point_x + ', point_y : ' + point_y)
scout_detail_url = '/game/war_result_info_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&id=' + str(list_item) + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(scout_detail_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
if '"code":0' in html_source:
str_token = str(html_source)
if '\\uc0b0\\ub3c4\\uc801' in str_token:
san_num = '1'
else:
san_num = '0'
if '\\ud654\\uc801' in str_token:
hwa_num = '1'
else:
hwa_num = '0'
write_str = '[' + point_x + ',' + point_y + ',' + '산도적(' + san_num + '),화적(' + hwa_num + ')]'
print(write_str)
f_new.write(write_str + '\n')
rand_timesleep()
if int(hwa_num) == 0 and int(san_num) > 0:
add_friend_url = '/game/api_fav.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&act=addreport&wid=' + str(list_item) + '&cat=2&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(add_friend_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
if '"code":0' in html_source:
print(write_str + 'Only 산도적 오랑캐 ==> 친구추가완료!!')
else:
print(write_str + 'Only 산도적 오랑캐 ==> 친구추가실패!!')
print('add_friend_url : ' + html_source)
rand_timesleep()
else:
print('scout_detail_url Error : ' + html_source)
else:
print('[' + point_x + '/' + point_y + '] 병력상세정보 검출 실패!!')
print('scout_detail_url : ' + scout_detail_url)
if len(scout_del_id):
del_str = ''
del_id_cnt = len(scout_del_id)
while len(scout_del_id):
del_pop_item = str(scout_del_id.pop())
if len(scout_del_id) == 0:
del_str += del_pop_item
else:
del_str += del_pop_item + '%2C'
scout_del_url = '/game/war_result_list_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&action=delete&id=' + del_str + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
#print('scout_del_url : ' + scout_del_url)
html_source = get_html_response(scout_del_url, 2)
if html_source == '::ERROR::':
return '::ERROR::'
rand_timesleep()
if '"code":0' in html_source:
print('정찰완료 정보' + str(del_id_cnt) + '개 삭제 완료!!')
else:
print('정찰완료 정보' + str(del_id_cnt) + '개 삭제 실패!!')
print('scout_del_url : ' + scout_del_url)
print('다음 정찰결과 정보 추출..')
else:
print('모든 정찰결과 정보 추출 완료!!')
break
else:
print('정찰결과 리스트를 불러오는데 실패하였습니다. 프로그램을 종료합니다!!')
print('Error Code : ' + html_source)
return '::ERROR::'
finally:
print('정찰결과 분석 정보가 ''orang_final.dat''에 저장되었습니다!!')
f_new.close()
# 메인함수 시작!!
# 장소 인증
chk_auth()
print("""
***************************************************************
손바닥삼국지 도우미 Ver 0.31(alpha) - by hElLoOnG(2012.04.02)
***************************************************************
*주의사항
*이 프로그램 사용으로 인하여 발생하는 불이익에 대하여
*개발자는 어떠한 책임도 지지 않습니다.
*
*기타 문의 및 버그 수정 요청은 살포시 넣어둬 주세요 ㅋㅋ
***************************************************************
""")
# 쿠키 생성
base_cookie = make_cookie()
print('Session 생성 : ' + base_cookie)
# 사용자 아이디/패스워드 입력부(입력안하면 기본 아이디로 진행)
temp_user_id = input('손바닥삼국지 ID : ')
if str(temp_user_id).strip() != '':
base_user_id = temp_user_id
print('입력된 사용자 ID : ' + base_user_id)
else:
print('ID가 입력되지 않았습니다!!')
sys.exit()
temp_user_pw = input('손바닥삼국지 PW : ')
if str(temp_user_pw).strip() != '':
base_user_pw = temp_user_pw
print('입력된 사용자 PW : ' + base_user_pw)
else:
print('PW가 입력되지 않았습니다!!')
sys.exit()
# 실제 앱에서 일어나는 의미없는 체크
print('손바닥 삼국지 서버로 접속을 시도합니다...')
html_source = attempt_login()
if html_source == '::ERROR::':
sys.exit()
rand_timesleep()
# 사용자 서버 정보 추출
print('사용자의 손바닥 삼국지 서버 정보를 추출합니다...')
get_server_url = '/info.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&user=' + base_user_id + '&action=login&pvp=0&code=a1c1ef3363ae6f52d8e823ecd7d62da618a98c43&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(get_server_url, 1)
if html_source == '::ERROR::':
sys.exit()
if '"code":0' in html_source:
base_user_host = re.search('k(\d+)\.tapsg\.com', html_source).group()
print('사용자 서버 추출 성공 : ' + base_user_host)
else:
print('사용자 서버정보 추출에 실패하였습니다!!\nID, PW를 확인하고 다시 시도하여 주세요!!')
print('Error Code : ' + html_source)
sys.exit()
# 실제 인증 키값 추출
print('손바닥 삼국지 인증키 값을 추출합니다...')
login_url = '/game/login_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&username=' + base_user_id + '&password=' + base_user_pw + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
print('login_url : ' + login_url)
html_source = get_html_response(login_url, 2)
if html_source == '::ERROR::':
sys.exit()
if '"code":0' in html_source:
base_token = re.search('key":"(\\w+)"}',html_source).group(1)
print('사용자 인증키 추출 성공 : ' + base_token)
else:
print('사용자 인증키 추출에 실패하였습니다!!')
print('Error Code : ' + html_source)
sys.exit()
# 사용자 정보 추출
#userinfo_url : jsonp1333982142599({"code":0,"ret":{"user":{"id":20440,"nick":"helloong","nationid":1,"level":39,"money":100,"guild":"\uace0\ud55c\uc74d","guildid":13,"gpower":5,"gflag":64,"protection":0,"p_end":1332411629,"status":0,"city":[{"id":23764,"name":"\ub69d\ub531\uc131","landtype":5,"x":264,"y":133},{"id":24410,"name":"\ub69d\ub531\uc1312","landtype":5,"x":265,"y":133}],"conq":[0,0,null,5],"gift":[],"pvp":0},"events":[{"id":1,"icon":"gem.jpg","name":"\uc131\uc2e4\ud55c \ub2f9\uc2e0\uc744 \uc704\ud55c \ubcf4\uc0c1! [5\/7\uc77c]","desc":"<b>\uc77c\uc77c \uc120\ubb3c<\/b>\uc740 \ub85c\uadf8\uc778 \ud6c4 \ubc1b\uc73c\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4. 7\uc77c\uac04 \uc5f0\uc18d \ub85c\uadf8\uc778\uc744 \ud558\uc2dc\uba74 <b>\ub3d9\uc6d0\ub839(7\uc77c)<\/b>\uc744 \ub4dc\ub9bd\ub2c8\ub2e4!"},{"id":2,"icon":"0.png","name":"\ub4f1\uae09\uaca9\ucc28 \ubcf4\ud638\uc0c1\ud0dc","desc":"\uba3c\uc800 \uacf5\uaca9\ud558\uc9c0 \uc54a\ub294 \uc774\uc0c1, 10\ub4f1\uae09\uc774\uc0c1\uc758 \uc720\uc800\ub85c\ubd80\ud130 \ubcf4\ud638 \ubc1b\uc2b5\ub2c8\ub2e4. \uc774 \ubcf4\ud638\ub294 \ub85c\uadf8\uc544\uc6c3\ud6c4 24\uc2dc\uac04\uc774 \uc9c0\ub098\uba74 \uc790\ub3d9\uc73c\ub85c \ucde8\uc18c\ub429\ub2c8\ub2e4."}],"status":{"invite":1,"ver":0.9,"vs":1.25,"vr":0.5,"ce":1,"he":1}}})
print('사용자 정보 추출')
userinfo_url = '/game/get_userinfo_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(userinfo_url, 2)
if html_source == '::ERROR::':
sys.exit()
if '"code":0' in html_source:
base_city_id = re.search('"city":\[\{"id":(\d+),"name":',html_source).group(1)
city_id_all = re.findall('"id":(\d+),"name"', html_source)
print('사용자 본성 ID : ' + base_city_id)
print('사용자 전체성 ID : ', end ='')
print(city_id_all)
else:
print('사용자 정보 추출에 실패하였습니다!!')
print('Error Code : ' + html_source)
sys.exit()
# 사용자 테스크 정보
usertask_url = '/game/system_task_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&action=task_list&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(usertask_url, 2)
if html_source == '::ERROR::':
sys.exit()
# 도시정보 호출
city_resource = get_city_resource(base_city_id)
if city_resource == '::ERROR::':
sys.exit()
# cd 정보??
cdinfo_url = '/game/get_cdinfo_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + base_city_id + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
html_source = get_html_response(cdinfo_url, 2)
if html_source == '::ERROR::':
sys.exit()
# 사용자 희망 작업 선택!!
print("""
***************************************************************
* 메뉴 선택
***************************************************************
* 1: 오랑캐 좌표 및 현시간 미점령 식량창고(대) 좌표 스캔!!
* 본성에 척후병이 약 100명정도 보유 하셔야 합니다!!
* 초반 성별 식량은 15만 이상 맞춰 주세요!!
*
* 2: ID 정찰결과 함에 존재하는 병력정보 검색(Only산도적 좌표 자동친구추가)
* 3: 도시별 연무장 소문 수집 작업(연무장 레벨 최소 16이상, 고용 공간 필요)
* 4: 친구추가 되어있는 오랑캐 자동사냥
* 5: 종료
***************************************************************
""")
which_way = int(input('원하시는 작업을 선택하여주세요[1 - 4] : '))
if which_way == 1:
# 오랑캐 추출 갯수 입력부
base_find_cnt = int(input('얼마나 많은 오랑캐 좌표를 찾길 원하세요?(1-' + str(base_max_cnt) + ') : '))
if (base_find_cnt < 1) or (base_find_cnt > base_max_cnt):
print('입력값의 범위가 잘못되었습니다.(입력값은 숫자 1 부터 ' + str(base_max_cnt) + '사이 값이어야 합니다.')
sys.exit()
base_find_type = int(input('어떤 종류의 오랑캐를 찾고 싶으세요(1-6)??\n(1:별6개 오랑캐,2:별5개 오랑캐,3:별4개 오랑캐, ...): '))
if (base_find_type < 1) or (base_find_type > 6):
print('입력값의 범위가 잘못되었습니다!!(입력값은 숫자 1부터 6사이 값이어야 합니다!!')
sys.exit()
point_x = int(input('지도상 x축 스캔시작 좌표 입력[4 - 270](기본값 4) : '))
if (point_x < 4) or (point_x > 270):
print('입력값의 범위가 잘못되었습니다!!(입력값은 숫자 4부터 270사이 값이어야 합니다!!')
sys.exit()
point_y = int(input('지도상 y축 스캔시작 좌표 입력[4 - 270](기본값 4) : '))
if (point_y < 4) or (point_y > 270):
print('입력값의 범위가 잘못되었습니다!!(입력값은 숫자 4부터 270사이 값이어야 합니다!!')
sys.exit()
# 지도 스캔 및 오랑캐/식량창고(대) 좌표추출
print('지도 스캔작업을 시작합니다...')
ret_val = scan_area_all(base_find_cnt,base_find_type,point_x,point_y)
if ret_val == '::ERROR::':
sys.exit()
elif which_way == 2:
print('입력하신 ID 정찰결과 함으로 부터 병력정보 및 친구추가 작업을 진행합니다...')
ret_str = get_enemy_info_from_file()
elif which_way == 3:
print('다음 도시의 연무장에 1시간 5분마다 모든 도시의 한잔하기를 시행합니다!!')
print('실행중 서버가 불안정 하거나 한잔하기에 필요한 동전이 부족하면 자동 종료됩니다!!')
print('대상도시 ID : ', end=''); print(city_id_all)
#GET /game/gen_conscribe_api.php?jsonpcallback=jsonp1333983704456&_=1333983724728&key=c9808b7af18f45e2e6e599ef6a0fcc02&city=23764&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
#chk_somedrink_url : jsonp1333985951179({"code":0,"ret":{"price":66,"type":3}})
#GET /game/gen_conscribe_api.php?jsonpcallback=jsonp1333983704457&_=1333983726653&key=c9808b7af18f45e2e6e599ef6a0fcc02&city=23764&action=pub_process&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
#buy_response : jsonp1334004741746({"code":0,"ret":{"gold":102706,"price":8545,"refresh":3600,"hero":{"gid":205,"p":21,"i":8,"c1":11,"g":3,"c2":300},"rumor":0}})
#hero gid:아이디, p:공격력, i:지혜력, c1:방어력, c2: 통솔력
int_drink_tick = 0
int_mod_sec = 3780 # 1시간 3분
try:
f_drink_name = 'drink_log_' + time.strftime('%y%m%d%H%M') + '.dat'
while True:
if (int_drink_tick == 0) or (int_drink_tick % int_mod_sec == 0):
file_drink = open(f_drink_name, 'a')
for city_id_item in city_id_all:
print('현재시간 : ' + time.strftime('%Y-%m-%d %H:%M:%S'))
chk_somedrink_url = '/game/gen_conscribe_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id_item + '&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
print('chk_somedrink_url : ' + chk_somedrink_url)
html_source = get_html_response(chk_somedrink_url, 2)
file_drink.write('chk_somedrink_url : ' + chk_somedrink_url + '\n')
if html_source == '::ERROR::':
sys.exit()
if '"code":0' in html_source:
if '"refresh":' in html_source:
need_refresh_t = int(re.search('"refresh":(\d+),"hero"', html_source).group(1))
print('도시[' + city_id_item + ']의 한잔하기 남은 대기시간 : ' + str(need_refresh_t) + '초 입니다.')
else:
need_refresh_t = 0
need_money = re.search('"price":(\d+),"type"', html_source).group(1)
file_drink.write('OK[chk] : ' + str(html_source) + '\n')
else:
print('도시[' + city_id_item + ']의 소문모으기 준비 작업에 실패하였습니다!!')
print('Error Code : ' + html_source)
file_drink.write('Err[chk] : ' + str(html_source) + '\n')
if need_refresh_t == 0:
get_city_money = get_city_resource(city_id_item)
print('remain money : ' + get_city_money[0][0] + ', need money : ' + need_money)
if int(need_money) > int(get_city_money[0][0]):
print('한잔하기에 필요한 동전이 부족하여 작업을 종료합니다!!')
sys.exit()
buy_somedrink_url = '/game/gen_conscribe_api.php?jsonpcallback=jsonp' + get_time() + '&_=' + get_time() + '&key=' + base_token + '&city=' + city_id_item + '&action=pub_process&_l=kr&_p=SG-IPHONE-KR{}HTTP/1.1'.format(urllib.parse.quote(' '))
print('buy_somedrink_url : ' + buy_somedrink_url)
html_source = get_html_response(buy_somedrink_url, 2)
file_drink.write('buy_somedrink_url : ' + buy_somedrink_url + '\n')
if html_source == '::ERROR::':
sys.exit()
if '"code":0' in html_source:
print('buy_response : ' + html_source)
file_drink.write('OK[buy] : ' + html_source + '\n')
else:
print('도시[' + city_id_item + ']의 소문모으기 준비 작업에 실패하였습니다!!')
print('Error Code : ' + html_source)
file_drink.write('Err[chk] : ' + str(html_source) + '\n')
int_drink_tick = 0
int_drink_tick += 1
time.sleep(1)
file_drink.close()
else:
#print('현재시간 : ' + time.strftime('%Y-%m-%d %H:%M:%S'))
int_drink_tick += 1
#print('남은대기 초 : ' + str(int_drink_tick) + '/' + str(int_mod_sec))
time.sleep(1)
finally:
file_drink.close()
elif which_way == 110:
while True:
print('사용자 인증키 : ' + base_token)
print('현재시간_1 : ' + get_time())
print('현재시간_2 : ' + get_time())
print('사용자 본성 ID : ' + base_city_id)
print('사용자 전체성 ID : ', end ='')
print(city_id_all)
input_send_str = str(input('send_str(quit is "q") : '))
if len(input_send_str) > 1:
input_send_str = input_send_str.format(urllib.parse.quote(' '))
if input_send_str == 'q':
break
html_source = get_html_response(input_send_str, 2)
if html_source == '::ERROR::':
sys.exit()
print('Response : ')
print(html_source)
print('테스트 종료!!')
elif which_way == 4:
city_id_loop = ''
# 질문1
# 오랑캐 타입!! 어떤 오랑캘 잡을지!!
type_orang = str(input('친구추가된 오랑캐중 어떤 종류의 오랑캐를 공격하고 싶으세요(1-6)??\n(1:별6개, 2:별5개, 3:별4개, 4:별3개, 5:별2개, 6:별1개): '))
if (type_orang < '1') or (type_orang > '6'):
print('입력값의 범위가 잘못되었습니다.(입력값은 숫자 1 부터 6사이 값 이어야 합니다.')
sys.exit()
# 질문2
# 공격 병력타입(중보 : 11, 친위 : 15)
type_soldier = str(input('어떤 병력으로 오랑캐를 공격하시겠습니까??\n(11: 중보병, 15: 친위기병): '))
if (type_soldier != '11') and (type_soldier != '15'):
print('입력값의 범위가 잘못되었습니다.(입력값은 11 또는 15 이어야 합니다.')
sys.exit()
# 질문3
# 공격 병력수 100단위로 입력!!(6성 평균 기준 : 중보 : 800, 친위 : 500)
num_soldier = int(input('몇명의 병력을 공격에 동원하고 싶으세요\n(100단위 입력, 최소300-최대800): '))
if (num_soldier < 300) or (num_soldier > 800):
print('입력값의 범위가 잘못되었습니다!!(입력값은 숫자 300부터 800사이 값이어야 합니다!!')
sys.exit()
if (num_soldier % 100) != 0:
print('입력값의 범위가 잘못되었습니다!!(입력값은 100단위로 이루어져야 합니다!!')
sys.exit()
city_id_loop = copy.deepcopy(city_id_all)
while city_id_loop:
# 리스트 마지막 item을 검출!!
last_city_id = city_id_loop[len(city_id_loop) - 1]
# 기본대기시간 10분 60초 * 10분 = 600초
ret_max_timesleep = 600
for idx_city_id in city_id_loop:
print('[' + idx_city_id + ']성의 자동사냥을 시작합니다...')
ret_max_timesleep = auto_attack(idx_city_id, ret_max_timesleep, type_orang, type_soldier, num_soldier)
# 리턴값 판별!!
if ret_max_timesleep < 0:
# 해당 성 자동 사냥 종료
city_id_loop.pop(city_id_loop.index(idx_city_id))
print('[' + idx_city_id + ']성은 자동사냥 목록에서 제외됩니다.')
else:
if idx_city_id == last_city_id:
print('자동사냥 목록에 있는 모든 성의 자동 사냥 턴이 완료 되었습니다!!')
print('인터벌 대기 후 재시작 합니다!!')
timesleep(300)
else:
print('[' + idx_city_id + ']성의 자동사냥 턴이 완료 되었습니다!!')
print('다음성[' + city_id_loop[city_id_loop.index(idx_city_id) + 1] + ']의 자동사냥을 시작합니다!!')
rand_timesleep()
print('자동 사냥 목록에 남은 성이 없습니다!!')
input('아무키나 누르시면 자동사냥을 종료합니다.')
sys.exit()
# 12. 동전 동괴화 작업!!
#GET /game/get_userinfo_api.php?jsonpcallback=jsonp1334481191259&_=1334481287964&key=a79a44877dece79457f4e78152c3b08f&action=exp&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
#GET /game/get_userinfo_api.php?jsonpcallback=jsonp1334481191260&_=1334481290297&key=a79a44877dece79457f4e78152c3b08f&action=g_cd&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
#GET /game/gold_local_market_api.php?jsonpcallback=jsonp1334481191261&_=1334481299554&key=a79a44877dece79457f4e78152c3b08f&city=23764&type=2&num=1&_l=kr&_p=SG-IPHONE-KR HTTP/1.1
elif which_way == 5:
print('손바닥삼국지 도우미를 종료합니다.')
sys.exit()
'Study > python' 카테고리의 다른 글
wxpython webview test (0) | 2013.10.05 |
---|---|
[연습중]MK RSS 파싱 (0) | 2013.09.23 |
[연습]Python regular expression & sqlite (0) | 2013.09.22 |
[펌]Unicode In Python, Completely Demystified (0) | 2013.09.18 |
python ODBC 연결시~ (0) | 2013.01.26 |