Files
string-to-gag/gag.py
2025-11-29 20:04:26 +08:00

253 lines
7.9 KiB
Python

import keyboard
import time
import pyperclip
import socket
import random
# 定义端口和延时
port = 25848
DELAY = 0.01
# 检测并占用端口防止多次运行
try:
s = socket.socket()
s.bind(('localhost', port))
s.listen()
run = True
except OSError:
run = False
# 口塞模糊配置
MUFFLE_EFFECTS = {
'塑料口球': {
'prefix': '(透过塑料口球)',
'fuzziness': 0.25,
'min_dots': 2,
'max_dots': 4,
'filler_words': ['', '', '', ''],
'filler_probs': [0.3, 0.3, 0.2, 0.2],
'insert_prob': 0.2 # 20%概率在字符后添加而不是替换
},
'金属口球': {
'prefix': '(透过金属口球)',
'fuzziness': 0.28,
'min_dots': 2,
'max_dots': 5,
'filler_words': ['', '', ''],
'filler_probs': [0.4, 0.4, 0.2],
'insert_prob': 0.2
},
'硅胶口球': {
'prefix': '(透过硅胶口球)',
'fuzziness': 0.2,
'min_dots': 1,
'max_dots': 3,
'filler_words': ['', '', ''],
'filler_probs': [0.4, 0.3, 0.3],
'insert_prob': 0.2
},
'强制口交环': {
'prefix': '(透过强制口交环)',
'fuzziness': 0.38,
'min_dots': 3,
'max_dots': 6,
'filler_words': ['', '', ''],
'filler_probs': [0.5, 0.3, 0.2],
'insert_prob': 0.2
},
'假阴茎口塞': {
'prefix': '(透过假阴茎口塞)',
'fuzziness': 0.32,
'min_dots': 2,
'max_dots': 5,
'filler_words': ['', '', '', ''],
'filler_probs': [0.3, 0.3, 0.2, 0.2],
'insert_prob': 0.15
},
'深喉口塞': {
'prefix': '(透过深喉口塞)',
'fuzziness': 0.45,
'min_dots': 3,
'max_dots': 8,
'filler_words': ['', '', ''],
'filler_probs': [0.4, 0.3, 0.3],
'insert_prob': 0.15
},
'白丝口塞': {
'prefix': '(透过白丝口塞)',
'fuzziness': 0.22,
'min_dots': 2,
'max_dots': 5,
'filler_words': ['', '', '', '',''],
'filler_probs': [0.4, 0.3, 0.3,0.1,0.1],
'insert_prob': 0.25
},
'黑丝口塞': {
'prefix': '(透过黑丝口塞)',
'fuzziness': 0.22,
'min_dots': 2,
'max_dots': 5,
'filler_words': ['', '', '', '',''],
'filler_probs': [0.4, 0.3, 0.3,0.1,0.1],
'insert_prob': 0.25
},
'胶带': {
'prefix': '(透过胶带)',
'fuzziness': 0.32,
'min_dots': 3,
'max_dots': 6,
'filler_words': ['', '', ''],
'filler_probs': [0.5, 0.3, 0.2],
'insert_prob': 0.3
}
}
# 随机选择一个口塞类型
muffle_types = list(MUFFLE_EFFECTS.keys())
selected_muffle_type = random.choice(muffle_types)
print(f"[INFO] 随机选中的口塞类型: {selected_muffle_type}")
def convert_string_with_effects(input_string, effect_settings):
"""
将输入字符串根据口塞效果配置进行模糊处理
Args:
input_string (str): 原始输入字符串
effect_settings (dict): 口塞效果配置参数
Returns:
str: 处理后的模糊字符串
"""
fuzziness = effect_settings.get('fuzziness', 0.3)
min_dots = effect_settings.get('min_dots', 1)
max_dots = effect_settings.get('max_dots', 5)
filler_words = effect_settings.get('filler_words', ['', '', ''])
filler_probs = effect_settings.get('filler_probs', [0.33, 0.33, 0.34])
insert_prob = effect_settings.get('insert_prob', 0.3) # 添加语气词的概率
result = []
has_replaced = False
# 遍历每个字符进行处理
for i, char in enumerate(input_string):
# 决定是否替换当前字符
should_replace = random.random() < fuzziness
# 确保短字符串至少有一个替换
if not has_replaced and i == len(input_string) - 1:
should_replace = True
if should_replace:
filler = random.choices(filler_words, weights=filler_probs, k=1)[0]
# 决定是替换还是插入
if random.random() < insert_prob:
# 插入模式:保留原字符,在其后添加语气词
result.append(char)
result.append(filler)
else:
# 替换模式:用语气词替换原字符
result.append(filler)
has_replaced = True
else:
result.append(char)
# 每个字符后都添加点号
dot_count = random.randint(min_dots, max_dots)
result.append('.' * dot_count)
# 极端情况下确保至少有一个替换
if not has_replaced and len(input_string) > 0:
# 找到最后一个字符位置进行替换或插入
last_char_index = len(result) - 1
while last_char_index >= 0 and result[last_char_index].startswith('.'):
last_char_index -= 1
if last_char_index >= 0:
filler = random.choices(filler_words, weights=filler_probs, k=1)[0]
dot_count = random.randint(min_dots, max_dots)
# 决定是替换还是插入最后一个字符
if random.random() < insert_prob and last_char_index < len(result):
# 插入模式
result.insert(last_char_index + 1, filler)
# 在插入的语气词后添加点号
result.insert(last_char_index + 2, '.' * dot_count)
else:
# 替换模式
if last_char_index < len(result):
result[last_char_index] = filler
return ''.join(result)
def convert_string_with_muffle_type(input_string, muffle_type):
"""
根据指定的口塞类型转换字符串
Args:
input_string (str): 原始输入字符串
muffle_type (str): 口塞类型名称
Returns:
str: 添加了口塞前缀的转换结果
"""
if muffle_type not in MUFFLE_EFFECTS:
raise ValueError(f"不支持的口塞类型: {muffle_type}")
effect_settings = MUFFLE_EFFECTS[muffle_type].copy()
prefix = effect_settings.pop('prefix')
converted_text = convert_string_with_effects(input_string, effect_settings)
return prefix + converted_text
def start():
"""
主要处理函数:获取剪贴板内容,应用口塞效果,然后粘贴回原位置
"""
# 保存原始剪贴板内容
old_clip = pyperclip.paste()
pyperclip.copy("")
# 全选并剪切当前文本
keyboard.send('ctrl+a')
time.sleep(DELAY)
keyboard.send('ctrl+x')
time.sleep(DELAY)
# 获取剪切的文本
current_clip = pyperclip.paste()
# 如果有有效文本内容,则进行转换
if isinstance(current_clip, str) and current_clip.strip():
new_text = convert_string_with_muffle_type(current_clip, selected_muffle_type)
pyperclip.copy(new_text)
print("原始文本:", repr(current_clip))
print("转换结果:", new_text)
# 全选并粘贴转换后的文本
keyboard.send('ctrl+a')
time.sleep(DELAY)
keyboard.send('ctrl+v')
time.sleep(DELAY)
# 按回车键确认
keyboard.send('enter')
# 恢复原始剪贴板内容
pyperclip.copy(old_clip or "")
# 根据程序运行状态启动相应功能
if run:
keyboard.add_hotkey('enter', start, suppress=True)
print("程序运行中,请在任意文本框中按 Enter 测试效果。")
keyboard.wait()
else:
print("程序已在运行中,无法重复启动。")