Sync and Convert Game Rules with Fixed IPv4 #222
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Sync and Convert Game Rules with Fixed IPv4 | |
| on: | |
| schedule: | |
| - cron: '0 18 * * *' # 北京时间 02:00 执行 | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| game_rules: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install dependencies | |
| run: npm install fs-extra yaml | |
| - name: Fetch Game Rules | |
| run: | | |
| mkdir -p tmp_repo | |
| git clone --depth=1 --filter=blob:none --sparse https://github.com/FQrabbit/SSTap-Rule.git tmp_repo | |
| cd tmp_repo | |
| git sparse-checkout set rules | |
| cp -r rules/* ../rules/Game/ | |
| cd .. | |
| rm -rf tmp_repo | |
| - name: Convert Rules to YAML with Fixed IPv4 | |
| run: | | |
| node <<'EOF' | |
| const fs = require('fs-extra'); | |
| const path = require('path'); | |
| const inDir = 'rules/Game'; | |
| const outDir = 'rules/Game'; | |
| function isPrivateIP(ip) { | |
| return /^(10\..*|172\.(1[6-9]|2[0-9]|3[01])\..*|192\.168\..*|169\.254\..*|22[4-9]\..*|2[3-5][0-9]\..*)$/.test(ip); | |
| } | |
| function fixIPv4(line) { | |
| const cidrMatch = line.match(/\/(\d+)$/); | |
| const cidr = cidrMatch ? parseInt(cidrMatch[1],10) : 32; | |
| const parts = line.split('/'); | |
| let ip = parts[0]; | |
| const suffix = parts[1] || ''; | |
| let octets = ip.split('.').map(n => n.trim()); | |
| while(octets.length < 4) octets.push('0'); | |
| for (let i=0;i<octets.length;i++) { | |
| let num = parseInt(octets[i],10); | |
| if (isNaN(num)) num = 0; | |
| octets[i] = num.toString(); | |
| } | |
| if (cidr === 24) { | |
| // 第四段置0,第三段截取不超过三位 | |
| let third = parseInt(octets[2],10); | |
| let thirdStr = third.toString(); | |
| if (thirdStr.length > 3) { | |
| octets[2] = thirdStr.slice(0,3); | |
| } else if (thirdStr.length > 2) { | |
| octets[2] = thirdStr.slice(0,2); | |
| } else { | |
| octets[2] = thirdStr; | |
| } | |
| octets[3] = '0'; | |
| } else if (cidr === 32) { | |
| // 第三段末两位为第三段,剩余为第四段,如果第四段为空就1 | |
| let third = parseInt(octets[2],10); | |
| let thirdStr = third.toString(); | |
| if (thirdStr.length <= 2) { | |
| octets[2] = thirdStr; | |
| octets[3] = '1'; | |
| } else { | |
| octets[2] = thirdStr.slice(0,2); | |
| octets[3] = thirdStr.slice(2) || '1'; | |
| } | |
| } | |
| return octets.join('.') + '/' + cidr; | |
| } | |
| async function walk(dir) { | |
| let files = []; | |
| for (const f of await fs.readdir(dir)) { | |
| const fullPath = path.join(dir, f); | |
| const stat = await fs.stat(fullPath); | |
| if (stat.isDirectory()) { | |
| files = files.concat(await walk(fullPath)); | |
| } else if (f.endsWith('.rules')) { | |
| files.push(fullPath); | |
| } | |
| } | |
| return files; | |
| } | |
| async function main() { | |
| await fs.ensureDir(outDir); | |
| const files = await walk(inDir); | |
| for (const file of files) { | |
| const content = await fs.readFile(file, 'utf8'); | |
| const lines = content.split(/\r?\n/).filter(l => l && !l.startsWith('#')); | |
| const payload = lines | |
| .map(fixIPv4) | |
| .filter(line => !isPrivateIP(line)); | |
| const baseName = path.basename(file, '.rules') + '.yaml'; | |
| const outPath = path.join(outDir, baseName); | |
| await fs.writeFile(outPath, 'payload:\n' + payload.map(l => ` - '${l}'`).join('\n')); | |
| console.log(`Generated YAML: ${outPath}`); | |
| } | |
| } | |
| main().catch(e => { console.error(e); process.exit(1); }); | |
| EOF | |
| - name: Commit and Push Changes | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| if ls rules/Game/*.yaml 1> /dev/null 2>&1; then | |
| git add rules/Game/*.yaml | |
| git commit -m "Updated Game rules with fixed IPv4" --allow-empty | |
| git push | |
| else | |
| echo "No YAML files generated, skipping commit." | |
| fi |