기본 콘텐츠로 건너뛰기

추천 가젯

리눅스 홈서버 알림용 텔레그램 봇(Telegram Bot) 연동 및 쉘 스크립트 구축 가이드

개인 홈서버를 운영하다 보면 백업 완료 여부나 시스템 에러 같은 단방향 알림을 스마트폰으로 빠르게 받아보고 싶어집니다. 외부 메일 서버나 복잡한 SMTP 설정을 거치지 않고, 가장 확실하고 가볍게 쓸 수 있는 텔레그램 봇을 이용한 홈서버 알림 구축 방법 을 정리합니다. 1단계: 텔레그램 봇 생성하기 (BotFather) 텔레그램 앱을 켜고 상단 검색창에 BotFather 를 검색하여 공식 봇(파란색 체크마크 확인)을 엽니다. 대화창에 아래 명령어를 입력하여 새로운 봇을 만듭니다. Plaintext /newbot 봇의 이름(Name)을 입력합니다. (예: My Home Server Bot ) 봇의 아이디(Username)를 입력합니다. (반드시 영문이며 끝에 bot 또는 _bot 으로 끝나야 합니다. 예: my_home_backup_bot ) 생성이 완료되면 HTTP API 토큰(Token)이 발급됩니다. 이 토큰을 안전하게 보관합니다. 2단계: 내 Chat ID(채팅방 고유 번호) 확인하기 텔레그램은 보안상 사용자가 먼저 봇에게 말을 걸어야 메시지를 받을 수 있으며, 봇이 나에게 메시지를 보내려면 고유 Chat ID 가 필요합니다. 텔레그램 검색창에 userinfobot 을 검색하여 들어갑니다. 하단의 [시작하기] 버튼을 누르면 내 계정의 정보와 함께 Id (숫자) 값을 알려줍니다. 이 숫자를 복사해 둡니다. [중요] 1단계에서 만든 내 봇의 아이디(예: @my_home_backup_bot )를 검색해서 대화창을 열고, [시작] 버튼을 누르거나 아무 메시지나 먼저 한 번 전송해 둡니다. 3단계: 리눅스 쉘 스크립트 작성 및 테스트 서버(터미널)에서 환경변수를 설정하고 curl 명령어를 통해 테스트 메시지를 보낼 수 있습니다. 특히 인자값이 없을 때를 대비해 기본값 처리를 해두면 유용합니다. 아래 내용을 포함하는 쉘 스크립트 파일(예: send_telegram.sh )을 작성합니다. Bash #!/bin/bash # 환경변수 설정 (실제 토큰과 C...

[리버싱 일기/리메이크] 랑그릿사 2의 마법 데미지 공식은 어떻게 설계되었는가?

필자는 최근 고전 명작 랑그릿사 2 PC판을 기드라로 분석하며, 마법 데미지가 계산되는 내부 로직을 추적했습니다. 각종 구조체와 변수명을 정리하고 나니, 90년대 게임 특유의 실용적이면서도 명쾌한 공식이 모습을 드러냈습니다.

1. 특정 마법의 개별 로직: 토네이도(Tornado)

가장 먼저 분석한 것은 범위 마법인 토네이도입니다. 코드상에서는 대상 유닛의 타입에 따른 보너스 판정이 가장 먼저 눈에 띕니다.

C
void Tornado(void)
{
    // 대상 유닛이 비병일 경우, 보너스 데미지 플래그 활성화
    if (ARMY2_UNITTYPE == FLYING_UNIT) {
        BonusSpellDamage = 1;
    }

    /* 계산 공식: ((레벨 / 2) + 시전자의 SP) * 2 */
    int damageValue = (((int)FORCE1_LV >> 1) + (int)FORCE1_SP) * 2;

    // 최종 데미지 적용 함수 호출 (마법 방어력 계산 포함)
    ApplySpellDamage_MDF(damageValue);
}

토네이도는 비병에게 치명적이라는 설정답게, BonusSpellDamage를 통해 추가 타격을 줍니다. 흥미로운 점은 기본 데미지가 (레벨 >> 1 + SP) * 2로 계산된다는 것인데, 여기서 SP는 유닛의 티어값(파이터=1, 로드=2 등)을 의미합니다.

2. 마법 방어력을 고려한 최종 데미지 산출

입력된 기초 데미지는 ApplySpellDamage_MDF 함수를 거치며 타겟의 마법 방어력(MDF)에 의해 가공됩니다.

C
void ApplySpellDamage_MDF(int damage)
{
    // 1. 마법 면역 상태 및 마법 방어력 체크
    if (is_magic_immune(FORCE2) || (100 - FORCE1_2_MDF == 0)) return;

    // 2. 최종 데미지 계산식
    // 보너스 데미지 + 아이템 보너스 + (기초 데미지 * 마방 관통률)
    int real_damage = BonusSpellDamage + SpellDamage_Item + 
                      (damage * (100 - (uint)FORCE1_2_MDF)) / 100;

    // 3. 데미지 보정 (데미지 하한선 및 HP 초과 방지)
    if (real_damage <= 0) real_damage = 1;

    int targetHP = (int)FORCE2->Army[ARMY2_NUMBER].HP;
    if (targetHP < real_damage) real_damage = targetHP;

    // 4. 누적 결과 기록 (범위 마법 계산용)
    AccumSpellEffect += real_damage;
    AccumSpellTarget += 1;

    // 5. 실행 플래그 확인 후 실제 데이터 반영
    if (_run_flag_apply == 1) {
        FORCE2->Army[ARMY2_NUMBER].HP -= (char)real_damage;
        
        if (FORCE2->Army[ARMY2_NUMBER].HP == 0) {
            killed_target_logic(); // 유닛 전사 처리
        }
    }
}

3. 분석을 통해 알 수 있는 사실들

분석 결과, 랑그릿사 2의 마법 데미지는 크게 세 단계를 거쳐 적용됩니다.

  1. 최소 데미지의 보장: 마법 방어력이 아무리 높더라도, 공식에 의해 산출된 데미지가 0이라면 강제로 1의 데미지를 가합니다.

  2. 누적 데이터의 활용: AccumSpellEffect와 AccumSpellTarget 변수를 통해 마법 한 번으로 총 얼마의 데미지를 몇 명에게 입혔는지 기록합니다. 이는 주로 범위 마법의 효율을 계산할 때 사용됩니다.

  3. AI 시뮬레이션의 분리: _run_flag_apply라는 플래그가 매우 중요합니다. AI가 마법을 쓸지 말지 결정하기 위해 데미지를 미리 계산해 볼 때는 이 플래그를 끄고 함수를 호출하여, 실제 HP는 깎지 않은 채 예상 결과물만 얻어가는 구조입니다.

맺으며

기드라에서 이 로직을 타고 올라가면, 적군 AI가 마법을 선택하는 판단 근거를 찾을 수 있을 것으로 보입니다. 비병에게 토네이도를 날리는 AI의 영리함은 결국 이런 간결한 if문과 시뮬레이션 플래그에서 시작된 것이었습니다. 리버싱은 단순한 코드 해독을 넘어, 30년 전 개발자의 설계 철학을 엿보는 즐거운 과정입니다.

댓글