카테고리 없음
[멀티,모바일(안드로이드),전략] 오목 APP Script
김조성준
2024. 10. 19. 16:22
1. App Script
구글 스프레드 시트의 ID를 이용하여 해당 Sheet의 정보에 접근하고 이용/갱신/추가하는 기능을 담당한다.
Post와 Get을 주로 지원한다. 갱신,추가하는 기능을 사용해야 하므로 Post 기능을 위주로 구현했다.
var sheetId = SpreadsheetApp.openById("Secret");
var sheet = sheetId.getSheets()[0]; // 첫번째 sheet 정보를 불러온다.
var cache = CacheService.getUserCache(); // 로그인 정보를 기록 (캐쉬해둔 정보는 6~12시간 뒤 소멸)
var p; // wwwform의 정보를 기록
var result, playerName, scoreValue; // 결과의 종류와 스코어를 저장한 변수
// 저장된 ID의 캐쉬를 삭제
function removeCache() {
if(cache.get("row_" + p.id) == null)
return;
sheet.getRange(cache.get("row_" + p.id), 4).setValue(0);
cache.removeAll(["id_" + p.id, "row_" + p.id]);
}
// POST로 호출된 값 반환
function response() {
var json = {};
json.result = result;
json.playerName = playerName;
json.scoreValue = scoreValue;
jsonData = JSON.stringify(json);
return ContentService.createTextOutput(jsonData);
}
// 특수 문자를 포함하고 있는지 확인 (부정한 공격을 방지하기 위함)
function specialCheck(val) {
var specialExp = /[\{\}\[\]\/?.,;"|\)*~`!^\-+<>@\#$%&\\\=\(\'\"]/gi;
if(specialExp.test(val))
return false;
else
return true;
}
// 정보를 받기만 한다. (스코어를 전달하는 기능만 구현)
function doGet(e) {
p = e.parameter;
// 특수 문자 포함을 방지
if(!specialCheck(p.order) || !specialCheck(p.id) || !specialCheck(p.password) || !specialCheck(p.scoreValue))
return ContentService.createTextOutput("");
// 만약 p값이 없다면 null(빈 값)을 전달한다.
if(!p.scoreValue)
return ContentService.createTextOutput("");
return ContentService.createTextOutput(p.scoreValue);
}
// 정보를 받고 갱신까지 할 수 있다.
function doPost(e) {
p = e.parameter;
// 특수 문자 포함을 방지
if(!specialCheck(p.order) || !specialCheck(p.id) || !specialCheck(p.password) || !specialCheck(p.scoreValue))
return ContentService.createTextOutput("");
// 등록, 로그인, 로그아웃, 값 설정
switch(p.order) {
case "RENEW" : reNew(); break;
case "OVERLAP" : overlap(); break;
case "REGISTER": register(); break;
case "LOGIN": login(); break;
case "LOGOUT": removeCache(); logout(); break;
case "SETSCOREVALUE": setScoreValue(); break;
case "GETSCOREVALUE" : getScoreValue(); break;
}
return response();
}
// POST 결과를 갱신
function setResult(_result, _playerName, _scoreValue) {
result = _result;
playerName = _playerName;
scoreValue = _scoreValue;
}
// 캐쉬를 갱신
function reNew() {
if(cache.get("row_" + p.id) == null) {
if(p.id.toString() != "") {
var cell = sheet.getRange(2, 1, sheet.getLastRow() - 1 , 4).getValues();
for(i = 0; i < cell.length; i++) {
if(cell[i][0] != p.id)
continue;
sheet.getRange(i + 2, 4).setValue(0);
setResult("ERROR", "", "-1000");
return;
}
}
setResult("ERROR", "", "-1000");
return;
}
var cell = sheet.getRange(2, 1, sheet.getLastRow() - 1 , 4).getValues();
var rowIndex = parseInt(cache.get("row_" + p.id)) - 2;
var cacheID = cell[rowIndex][0];
var cachePassword = cell[rowIndex][1];
for(i = 0; i < cell.length; i++) {
if(cell[i][0] != cacheID || cell[i][1] != cachePassword)
continue;
cache.put("id_" + p.id, cell[i][0]);
cache.put("row_" + p.id, (i + 2).toString());
setResult("RENEW", cell[i][0].toString(), cell[i][2].toString());
sheet.getRange(i + 2, 4).setValue(1);
return;
}
setResult("ERROR", "", "-1000");
}
// 중복된 ID인지를 확인
function overlap() {
var cell = sheet.getRange(2, 1, sheet.getLastRow() - 1, 1).getValues();
// 해당 ID가 있다면 오류
if(cell.some(row => row == p.id)) {
setResult("ERROR", "", "-1000");
return;
}
setResult("CANUSE", "", "1000");
}
// 계정 생성
function register() {
sheet.appendRow([p.id, p.password, p.scoreValue, 0]);
setResult("RSUCCESS", p.id, "1000");
}
// 계정 로그인을 위해 ID와 PASSWORD를 조회
function getProfile() {
var cell = sheet.getRange(2, 1, sheet.getLastRow() - 1 , 2).getValues();
for(i = 0; i < cell.length; i++) {
if(cell[i][0] != p.id || cell[i][1] != p.password)
continue;
cache.put("id_" + p.id, cell[i][0]);
cache.put("row_" + p.id, (i + 2).toString());
return true;
}
return false;
}
// 로그인
function login() {
if(cache.get("row_" + p.id) != null)
cache.removeAll(["id_" + p.id, "row_" + p.id]);
if (!getProfile()) {
setResult("ERROR", "", "-1000");
return;
}
var cell = sheet.getRange(2, 1, sheet.getLastRow() - 1 , 4).getValues();
var rowIndex = parseInt(cache.get("row_" + p.id)) - 2; // 배열 인덱스 보정
if(cell[rowIndex][3].toString() == "1") {
cache.removeAll(["id_" + p.id, "row_" + p.id]);
setResult("OVERLAP", "", "-1000");
return;
}
// 스코어 값이 유효한지 확인
var scoreValue = cell[rowIndex][2] !== undefined ? cell[rowIndex][2].toString() : "-1000"; // 기본값을 설정
setResult("LSUCCESS", cell[rowIndex][0].toString(), scoreValue);
if(scoreValue.toString() != "-1000") {
sheet.getRange(cache.get("row_" + p.id), 4).setValue(1);
}
}
function logout() {
setResult("LOGOUT", "", "");
}
// 스코어 점수 갱신
function setScoreValue() {
if(cache.get("row_" + p.id) == null) {
setResult("ERROR", "", "-1000");
return;
}
sheet.getRange(cache.get("row_" + p.id), 3).setValue(p.scoreValue);
setResult("SET", p.id.toString(), p.scoreValue.toString());
}
// 스코어 점수 받아오기
function getScoreValue() {
if(cache.get("row_" + p.id) == null) {
setResult("ERROR", "", "-1000");
return;
}
var loadScore = sheet.getRange(cache.get("row_" + p.id), 3).getValue();
setResult("GET", cache.get("id_" + p.id), loadScore);
}