/*
=========================================================
PHONE GUARD Ω - 次世代電子生態系版
Next-Gen Autonomous Evolutionary Simulation
=========================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <errno.h>
#define MAX_TARGETS 50
#define NAME_LEN 64
#define IP_LEN 64
#define SEVERITY_LEN 16
#define REGION_LEN 64
#define PART_LEN 32
#define ROOM_LEN 32
#define TYPE_LEN 32
#define COMM_LEN 32
#define LINE_LEN 768
#define LOG_FILE "phone_guard.log"
#define TARGET_FILE "targets.dat"
#define TARGET_BAK "targets.bak"
#define TARGET_BAK2 "targets.bak2"
typedef struct {
char name[NAME_LEN];
char ip[IP_LEN];
int port;
char severity[SEVERITY_LEN];
int blocked;
char estimated_region[REGION_LEN];
char partition[PART_LEN];
char room[ROOM_LEN];
char type[TYPE_LEN];
char comm_id[COMM_LEN];
double latitude;
double longitude;
int location_known;
int generation; /* 生存世代数 */
int fitness; /* 環境適応度スコア */
} Target;
static Target targets[MAX_TARGETS];
static int target_count = 0;
static int selected = 0;
static int cycle_count = 0;
static int env_stress = 0; /* 環境ストレス蓄積値 */
/* ----------------------------------------------------- */
static void clear_screen(void)
{
printf("\033[2J\033[H");
fflush(stdout);
}
static void clear_stdin(void)
{
int c;
while *1 != '\n' && c != EOF)
;
}
static void wait_for_enter(void)
{
printf("\n[Enterキーで継続...]");
fflush(stdout);
clear_stdin();
}
static void safe_strncpy(char *dst, const char *src, size_t n)
{
if (n == 0) return;
strncpy(dst, src, n - 1);
dst[n - 1] = '\0';
}
static void now_str(char *buf, size_t n)
{
time_t t = time(NULL);
struct tm *tm = localtime(&t);
if (tm)
strftime(buf, n, "%Y-%m-%d %H:%M:%S", tm);
else
safe_strncpy(buf, "UNKNOWN", n);
}
static int valid_ip(const char *ip)
{
int dots = 0, digits = 0;
const char *p = ip;
if (!ip || !*ip) return 0;
while (*p) {
if (*p == '.') {
if (digits < 1 || digits > 3) return 0;
dots++;
digits = 0;
} else if (isdigit*2 {
digits++;
} else {
return 0;
}
p++;
}
return (dots == 3 && digits >= 1 && digits <= 3);
}
static int valid_port(int p)
{
return p >= 1 && p <= 65535;
}
static const char *threat_level(int port)
{
switch (port) {
case 23: case 445: case 3389: return "HIGH";
case 22: return "MEDIUM";
case 80: case 443: return "INFO";
default: return "LOW";
}
}
/* 適応度(Fitness)計算 */
static int calc_fitness(const Target *t)
{
int base = t->generation * 10;
if (strcmp(t->severity, "HIGH") == 0) base += 50;
else if (strcmp(t->severity, "MEDIUM") == 0) base += 30;
else base += 10;
if (t->blocked) base -= 20;
return base < 0 ? 0 : base;
}
/* ----------------------------------------------------- */
static void save_log(const char *action, const Target *t)
{
FILE *fp;
char ts[64];
if (!t) return;
now_str(ts, sizeof(ts));
fp = fopen(LOG_FILE, "a");
if (!fp) return;
fprintf(fp, "%s | %s | %s | %s | %d | %s | %s | %s | %s | %s | GEN:%d | FIT:%d\n",
ts, action, t->name, t->ip, t->port, t->severity,
t->partition, t->room, t->type, t->comm_id, t->generation, t->fitness);
fclose(fp);
}
static int write_file(const char *path)
{
FILE *fp = fopen(path, "w");
int i;
if (!fp) return -1;
for (i = 0; i < target_count; i++) {
fprintf(fp, "%s|%s|%d|%s|%d|%s|%s|%s|%s|%s|%.6f|%.6f|%d|%d|%d\n",
targets[i].name, targets[i].ip, targets[i].port,
targets[i].severity, targets[i].blocked,
targets[i].estimated_region,
targets[i].partition, targets[i].room,
targets[i].type, targets[i].comm_id,
targets[i].latitude, targets[i].longitude,
targets[i].location_known, targets[i].generation,
targets[i].fitness);
}
fclose(fp);
return 0;
}
static void save_all(void)
{
write_file(TARGET_FILE);
write_file(TARGET_BAK);
write_file(TARGET_BAK2);
}
/* 創世記(カンブリア爆発) */
static void cambrian_explosion(void)
{
int i;
int ports = {22, 80, 443, 445, 3389, 8080, 21, 23};
target_count = 0;
printf("\n[生態系リスタート] 創世記プロトコルが発動しました。\n");
printf("[カンブリア爆発] 遺伝的多様性ノードを自動再創生中...\n");
for (i = 0; i < 5; i++) {
Target *t = &targets[i];
memset(t, 0, sizeof(*t));
snprintf(t->name, NAME_LEN, "CyberBio-Gen%d", i + 1);
snprintf(t->ip, IP_LEN, "10.0.%d.%d", rand() % 5 + 1, rand() % 200 + 10);
t->port = ports[rand() % 8];
safe_strncpy(t->severity, threat_level(t->port), SEVERITY_LEN);
t->blocked = 0;
safe_strncpy(t->estimated_region, "ORIGIN_BIOME", REGION_LEN);
snprintf(t->partition, PART_LEN, "CLUSTER-%C", 'A' + i);
snprintf(t->room, ROOM_LEN, "CELL-%d", rand() % 89 + 10);
safe_strncpy(t->type, "AUTONOMOUS", TYPE_LEN);
snprintf(t->comm_id, COMM_LEN, "DNA-%04X", rand() % 0xFFFF);
t->location_known = 0;
t->generation = 1;
t->fitness = calc_fitness(t);
}
target_count = 5;
selected = 0;
save_all();
}
static int load_file(const char *path)
{
FILE *fp = fopen(path, "r");
char line[LINE_LEN];
int n = 0;
if (!fp) return -1;
target_count = 0;
while (fgets(line, sizeof(line), fp) && target_count < MAX_TARGETS) {
Target *t = &targets[target_count];
char *p = strchr(line, '\n'); if (p) *p = '\0';
p = strchr(line, '\r'); if (p) *p = '\0';
int parsed = sscanf(line,
"%63[^|]|%63[^|]|%d|%15[^|]|%d|%63[^|]|%31[^|]|%31[^|]|%31[^|]|%31[^|]|%lf|%lf|%d|%d|%d",
t->name, t->ip, &t->port, t->severity, &t->blocked,
t->estimated_region, t->partition, t->room, t->type, t->comm_id,
&t->latitude, &t->longitude, &t->location_known, &t->generation, &t->fitness);
if (parsed >= 13) {
if (parsed < 14) t->generation = 1;
if (parsed < 15) t->fitness = calc_fitness(t);
if (!valid_port(t->port)) t->port = 80;
target_count++;
n++;
}
}
fclose(fp);
if (target_count == 0) selected = 0;
else if (selected >= target_count) selected = target_count - 1;
return n;
}
static void load_targets(void)
{
if (load_file(TARGET_FILE) >= 0 && target_count > 0) return;
if (load_file(TARGET_BAK) >= 0 && target_count > 0) { save_all(); return; }
if (load_file(TARGET_BAK2) >= 0 && target_count > 0) { save_all(); return; }
cambrian_explosion();
}
/* ----------------------------------------------------- */
/* 突発的変異(Mutation)処理 */
static void mutate_target(int idx)
{
if (idx < 0 || idx >= target_count) return;
Target *t = &targets[idx];
int ports = {22, 80, 443, 445, 3389, 8080, 8443, 23};
t->port = ports[rand() % 8];
safe_strncpy(t->severity, threat_level(t->port), SEVERITY_LEN);
snprintf(t->comm_id, COMM_LEN, "MUT-%04X", rand() % 0xFFFF);
t->fitness = calc_fitness(t);
save_log("MUTATED", t);
}
/* ノード交配・遺伝子伝播 (Cross-Breeding) */
static void breed_targets(void)
{
if (target_count < 2) {
printf("\n交配に必要なノード数が不足しています(2ノード以上必要)。\n");
wait_for_enter();
return;
}
int parent1 = selected;
int parent2 = (selected + 1) % target_count;
if (target_count >= MAX_TARGETS) {
printf("\n生態系の容量(上限50)に達しています。\n");
wait_for_enter();
return;
}
Target *child = &targets[target_count];
memset(child, 0, sizeof(*child));
snprintf(child->name, NAME_LEN, "Hybr-%s", targets[parent1].name);
snprintf(child->ip, IP_LEN, "10.0.%d.%d", rand() % 10 + 10, rand() % 200 + 1);
child->port = targets[parent2].port;
safe_strncpy(child->severity, threat_level(child->port), SEVERITY_LEN);
child->blocked = 0;
safe_strncpy(child->estimated_region, targets[parent1].estimated_region, REGION_LEN);
safe_strncpy(child->partition, targets[parent2].partition, PART_LEN);
safe_strncpy(child->room, targets[parent1].room, ROOM_LEN);
safe_strncpy(child->type, "HYBRID", TYPE_LEN);
snprintf(child->comm_id, COMM_LEN, "CRX-%04X", rand() % 0xFFFF);
child->generation = 1;
child->fitness = calc_fitness(child);
target_count++;
selected = target_count - 1;
save_log("BRED_NEW_NODE", child);
save_all();
printf("\n✓ 親1[%s] × 親2[%s] の遺伝子交配により次世代ハイブリッドノード[%s]が誕生しました!\n",
targets[parent1].name, targets[parent2].name, child->name);
wait_for_enter();
}
/* ----------------------------------------------------- */
static void integrity_check(int quiet)
{
int ok1 = 0, ok2 = 0, ok3 = 0;
FILE *fp;
cycle_count++;
env_stress += 5;
for (int i = 0; i < target_count; i++) {
targets[i].generation++;
targets[i].fitness = calc_fitness(&targets[i]);
}
if (env_stress >= 30 && target_count > 0) {
int victim = rand() % target_count;
mutate_target(victim);
env_stress = 0;
}
fp = fopen(TARGET_FILE, "r"); if (fp) { ok1 = 1; fclose(fp); }
fp = fopen(TARGET_BAK, "r"); if (fp) { ok2 = 1; fclose(fp); }
fp = fopen(TARGET_BAK2, "r"); if (fp) { ok3 = 1; fclose(fp); }
if (!quiet) {
printf("\n[環境周期 #%d] メイン:%s BAK1:%s BAK2:%s | ストレス負荷: %d%%\n",
cycle_count, ok1 ? "OK" : "欠損", ok2 ? "OK" : "欠損", ok3 ? "OK" : "欠損", env_stress);
}
if (!ok1) {
if (ok2 && load_file(TARGET_BAK) > 0) { save_all(); }
else if (ok3 && load_file(TARGET_BAK2) > 0) { save_all(); }
else { cambrian_explosion(); }
} else {
save_all();
}
}
/* 自然選択・高精度淘汰 */
static void natural_selection(void)
{
int i, j;
int pruned = 0;
if (target_count == 0) {
cambrian_explosion();
return;
}
for (i = 0; i < target_count; ) {
if (targets[i].blocked || targets[i].fitness < 20) {
save_log("NATURAL_SELECTION_PRUNED", &targets[i]);
for (j = i; j < target_count - 1; j++) {
targets[j] = targets[j + 1];
}
target_count--;
pruned++;
} else {
i++;
}
}
if (target_count == 0) {
printf("\n[絶滅検知] 全ノードが淘汰されました。即時カンブリア爆発を実行します。\n");
cambrian_explosion();
} else {
if (selected >= target_count) selected = target_count - 1;
save_all();
printf("\n[自然淘汰完了] 環境不適合ノード %d 件を消滅させました。\n", pruned);
}
wait_for_enter();
}
/* ----------------------------------------------------- */
static void show_list(void)
{
int i;
printf(
"╔════════════════════════════════════════════════════════════╗\n"
"║ PHONE GUARD Ω - 次世代自律電子生態系版 ║\n"
"║ Next-Gen Autonomous Evolutionary System ║\n"
"╚════════════════════════════════════════════════════════════╝\n\n"
);
if (target_count == 0) {
printf("ノードが存在しません。A で追加、または R で創世記を実行してください。\n");
} else {
for (i = 0; i < target_count; i++) {
printf("%s[%02d] %-14s %-15s %-5s %-8s (Gen:%d/Fit:%d)%s\n",
i == selected ? " ▶ " : " ",
i + 1,
targets[i].name,
targets[i].ip,
targets[i].severity,
targets[i].partition,
targets[i].generation,
targets[i].fitness,
targets[i].blocked ? " [B]" : "");
}
printf("\n────────────────────────────────────────────────────────────\n");
printf("選択 : %s\n", targets[selected].name);
printf("IP : %s PORT: %d\n", targets[selected].ip, targets[selected].port);
printf("危険度: %s (生存世代: %d | 適応度: %d)\n",
targets[selected].severity, targets[selected].generation, targets[selected].fitness);
printf("地域 : %s\n", targets[selected].estimated_region);
printf("区分 : %s / %s / %s\n",
targets[selected].partition, targets[selected].room, targets[selected].type);
printf("通信識別子: %s\n", targets[selected].comm_id);
}
printf("\n環境サイクル: %d | ストレス蓄積度: [%d%%]\n\n", cycle_count, env_stress);
printf("1-9:選択 0:次へ E:防御 F:全件防御 X:遺伝子交配(新種誕生)\n");
printf("A:追加 D:削除 S:検索 L:ログ B:遮断 M:変異誘発 K:環境淘汰\n");
printf("R:環境復元/創世 C:健全性・環境更新 Q:終了\n");
}
/* ----------------------------------------------------- */
static void defense_one(void)
{
if (target_count == 0) { printf("\n対象がありません。\n"); wait_for_enter(); return; }
Target *t = &targets[selected];
save_log("DETECTED", t);
t->blocked = 1;
t->fitness = calc_fitness(t);
save_log("BLOCK_REGISTERED", t);
save_all();
printf("\n✓ [%s] 防御・分離処理完了\n", t->name);
wait_for_enter();
}
static void defense_all(void)
{
if (target_count == 0) { printf("\n対象がありません。\n"); wait_for_enter(); return; }
printf("\n全 %d 件のノードを一括防御・分離中...\n", target_count);
for (int i = 0; i < target_count; i++) {
save_log("DETECTED", &targets[i]);
targets[i].blocked = 1;
targets[i].fitness = calc_fitness(&targets[i]);
save_log("BLOCK_REGISTERED", &targets[i]);
}
save_all();
printf("✓ 全ノードの防御完了\n");
wait_for_enter();
}
static void add_target(void)
{
Target *t;
char buf[128];
int port;
if (target_count >= MAX_TARGETS) { printf("\n容量上限です。\n"); wait_for_enter(); return; }
t = &targets[target_count];
memset(t, 0, sizeof(*t));
printf("\n名前: ");
if (scanf("%63s", buf) != 1 || strchr(buf, '|')) { clear_stdin(); printf("無効な名前です。\n"); wait_for_enter(); return; }
safe_strncpy(t->name, buf, NAME_LEN);
printf("IP: ");
if (scanf("%63s", buf) != 1 || !valid_ip(buf)) { clear_stdin(); printf("無効なIPです。\n"); wait_for_enter(); return; }
safe_strncpy(t->ip, buf, IP_LEN);
printf("PORT: ");
if (scanf("%d", &port) != 1 || !valid_port(port)) { clear_stdin(); printf("無効なポートです。\n"); wait_for_enter(); return; }
t->port = port;
safe_strncpy(t->severity, threat_level(port), SEVERITY_LEN);
printf("地域: ");
if (scanf("%63s", buf) != 1) safe_strncpy(t->estimated_region, "UNKNOWN", REGION_LEN);
else safe_strncpy(t->estimated_region, buf, REGION_LEN);
printf("パーティション: ");
if (scanf("%31s", buf) != 1) safe_strncpy(t->partition, "PART-X", PART_LEN);
else safe_strncpy(t->partition, buf, PART_LEN);
printf("部屋: ");
if (scanf("%31s", buf) != 1) safe_strncpy(t->room, "ROOM-X", ROOM_LEN);
else safe_strncpy(t->room, buf, ROOM_LEN);
printf("種類: ");
if (scanf("%31s", buf) != 1) safe_strncpy(t->type, "UNKNOWN", TYPE_LEN);
else safe_strncpy(t->type, buf, TYPE_LEN);
printf("通信番号: ");
if (scanf("%31s", buf) != 1) safe_strncpy(t->comm_id, "COMM-000", COMM_LEN);
else safe_strncpy(t->comm_id, buf, COMM_LEN);
t->blocked = 0;
t->location_known = 0;
t->generation = 1;
t->fitness = calc_fitness(t);
target_count++;
selected = target_count - 1;
save_all();
printf("✓ 新規ノード追加完了\n");
wait_for_enter();
}
static void delete_target(void)
{
if (target_count == 0) { printf("\n対象がありません。\n"); wait_for_enter(); return; }
printf("\n「%s」を手動消滅させますか? (y/N): ", targets[selected].name);
clear_stdin();
char c = getchar();
if (tolower(c) != 'y') { printf("キャンセルしました。\n"); wait_for_enter(); return; }
for (int i = selected; i < target_count - 1; i++) targets[i] = targets[i + 1];
target_count--;
if (target_count == 0) cambrian_explosion();
else if (selected >= target_count) selected = target_count - 1;
save_all();
printf("✓ ノード削除完了\n");
wait_for_enter();
}
static void search_local(void)
{
char key[64];
printf("\nキーワード検索: ");
if (scanf("%63s", key) != 1) { clear_stdin(); return; }
printf("\n--- 検索結果 ---\n");
int found = 0;
for (int i = 0; i < target_count; i++) {
if (strstr(targets[i].name, key) || strstr(targets[i].ip, key) ||
strstr(targets[i].severity, key) || strstr(targets[i].partition, key) ||
strstr(targets[i].type, key) || strstr(targets[i].comm_id, key)) {
printf("[%02d] %s %s %s %s (Gen:%d/Fit:%d)%s\n",
i + 1, targets[i].name, targets[i].ip, targets[i].severity,
targets[i].partition, targets[i].generation, targets[i].fitness,
targets[i].blocked ? " [B]" : "");
found++;
}
}
if (!found) printf("該当ノードなし\n");
printf("----------------\n");
wait_for_enter();
}
static void block_one(void)
{
if (target_count == 0) { printf("\n対象がありません。\n"); wait_for_enter(); return; }
targets[selected].blocked = 1;
targets[selected].fitness = calc_fitness(&targets[selected]);
save_log("BLOCK", &targets[selected]);
save_all();
printf("\n✓ 遮断登録完了\n");
wait_for_enter();
}
static void trigger_mutation(void)
{
if (target_count == 0) { printf("\n対象がありません。\n"); wait_for_enter(); return; }
mutate_target(selected);
save_all();
printf("\n⚡ [%s] に放射線刺激を与え、人工突然変異を起こさせました!\n", targets[selected].name);
wait_for_enter();
}
static void show_log(void)
{
FILE *fp;
char line[LINE_LEN];
clear_screen();
printf("=== CYBER-ECOSYSTEM LOG ===\n\n");
fp = fopen(LOG_FILE, "r");
if (!fp) printf("ログが存在しません。\n");
else {
while (fgets(line, sizeof(line), fp)) fputs(line, stdout);
fclose(fp);
}
wait_for_enter();
}
static void force_restore(void)
{
load_targets();
printf("\n環境再構築完了(現在のノード数: %d)\n", target_count);
wait_for_enter();
}
/* ----------------------------------------------------- */
static int read_cmd(void)
{
int c, next;
printf("\n> ");
fflush(stdout);
c = getchar();
if (c == EOF) return 'q';
if (c == '\n' || c == '\r') return 'e';
while *3 != '\n' && next != EOF)
;
return tolower(c);
}
static void main_loop(void)
{
int cmd;
while (1) {
clear_screen();
show_list();
cmd = read_cmd();
switch (cmd) {
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
if (target_count > 0) {
int idx = cmd - '1';
if (idx < target_count) selected = idx;
}
break;
case '0':
if (target_count > 0) selected = (selected + 1) % target_count;
break;
case 'e': defense_one(); break;
case 'f': defense_all(); break;
case 'x': breed_targets(); break;
case 'a': add_target(); break;
case 'd': delete_target(); break;
case 's': search_local(); break;
case 'l': show_log(); break;
case 'b': block_one(); break;
case 'm': trigger_mutation(); break;
case 'k': natural_selection(); break;
case 'r': force_restore(); break;
case 'c':
integrity_check(0);
wait_for_enter();
break;
case 'q':
save_all();
return;
default: break;
}
}
}
int main(void)
{
srand*4;
load_targets();
integrity_check(1);
main_loop();
clear_screen();
printf("PHONE GUARD Ω 次世代電子生態系版 を終了しました。\n");
printf("全シミュレーション状態は三重ゲノムバックアップに完全保存されました。\n");
return 0;
}