java类org.bukkit.configuration.file.FileConfiguration的实例源码

ConfigurationBuilder.java 文件源码 项目:Minecordbot 阅读 28 收藏 0 点赞 0 评论 0
/**
 * Write in-memory changes of config to its file
 *
 * @param clazz The configuration class to sync.
 */
public static void sync(Class clazz) {
    Object config = configurations.get(clazz);

    if (config == null)
        return;

    String name = config.getClass().getDeclaredAnnotation(Configuration.class).value();
    File file = new File(JavaPlugin.getProvidingPlugin(clazz).getDataFolder(), String.format("%s.yml", name));
    FileConfiguration configFile = new YamlConfiguration();

    buildToConfig(config, configFile);

    try {
        configFile.save(file);
    } catch (IOException e) {
        Logger.err("Couldn't sync config " + name + " to its file!");
    }
}
ArenaManager.java 文件源码 项目:ZorahPractice 阅读 19 收藏 0 点赞 0 评论 0
private void initiateArenas() {
    FileConfiguration config = ManagerHandler.getConfig().getArenasConfig().getConfig();

    if (!config.contains("arenas")) return;

    for (String name : config.getConfigurationSection("arenas").getKeys(false)) {
        try {
            String displayName = config.getString("arenas." + name + ".display-name");
            Integer displayOrder = config.getInt("arenas." + name + ".display-order");
            Location location1 = LocationUtils.getLocation(config.getString("arenas." + name + ".location1"));
            Location location2 = LocationUtils.getLocation(config.getString("arenas." + name + ".location2"));
            Arena arena = new Arena(name, displayName, displayOrder, location1, location2);
            this.arenas.put(name, arena);
        }
        catch (Exception e) {
            PracticePlugin.getInstance().getLogger().severe("Failed to load arena '" + name + "', stack trace below:");
            PracticePlugin.getInstance().getLogger().severe("------------------------------------------------------");
            e.printStackTrace();
            PracticePlugin.getInstance().getLogger().severe("------------------------------------------------------");
        }
    }
}
ConfigurationBuilder.java 文件源码 项目:Minecordbot 阅读 20 收藏 0 点赞 0 评论 0
private static Object buildFromConfig(FileConfiguration config, Class clazz, Object instance) {
    for (String key : config.getKeys(false)) {
        try {
            Field field = clazz.getField(key);

            field.setAccessible(true);
            fieldSet(field, config, instance, key);
        } catch (NoSuchFieldException ignored) {
            Logger.log(Level.FINER, "A key in YAML was not found in the class it is being rebuilt to.");
        } catch (IllegalAccessException e) {
            Logger.err("Couldn't access a field when rebuilding a config!");
        }
    }

    return instance;
}
DDoSManager.java 文件源码 项目:ViperBot 阅读 23 收藏 0 点赞 0 评论 0
public void loadUsers(){
    allowedUsers.clear();
    FileConfiguration config = getConfig();
    for(String key : config.getKeys(false)){
        allowedUsers.put(key.replace("_(dot)_", "."), (Date) config.get(key));
    }
    ArrayList<String> toRemove = new ArrayList<>();
    for(Entry<String, Date> ent : allowedUsers.entrySet()){
        if(Calendar.getInstance().getTime().after(ent.getValue())){
            try {
                Core.send(Core.skype.getOrLoadContact(ent.getKey()).getPrivateConversation(), "You DDoS-Attack permission is over");
            } catch (ConnectionException | ChatNotFoundException e) {
                e.printStackTrace();
            }
            toRemove.add(ent.getKey());
        }
    }
    for(String user : toRemove){
        allowedUsers.remove(user);
    }
}
Command.java 文件源码 项目:StartupCommands 阅读 24 收藏 0 点赞 0 评论 0
/**
 * Loads all of the startup commands from the plugin's configuration file.
 * @param plugin the StartupCommands plugin instance
 */
public static void loadCommands(StartupCommands plugin) {
    FileConfiguration config = plugin.getConfig();

        if (config.getConfigurationSection("commands") == null) {
            plugin.getLogger().info("There are no startup commands present.");
        } else {
            int delay = 0;

            for (String command : config.getConfigurationSection("commands").getKeys(false)) {
                delay = config.getInt("commands." + command + ".delay", 0);

                // Try to create the command
                try {
                    plugin.getCommands().add(new Command(command, delay));
                } catch (IllegalArgumentException e) {
                    plugin.getLogger().severe(e.getMessage());
                }
            }
        }
}
CraftStorage.java 文件源码 项目:CaulCrafting 阅读 28 收藏 0 点赞 0 评论 0
public void removeCraft(int nb) {
try {
    //replacing in the file
    File craftfile = new File(plugin.getDataFolder(), "crafts.yml");
    craftfile.createNewFile();
    FileConfiguration craftconfig = YamlConfiguration.loadConfiguration(craftfile);
    int count = 0;
    for(String craftuuid : craftconfig.getConfigurationSection("Crafts").getKeys(false)) {
        if(nb == count) {
            craftconfig.set("Crafts." + craftuuid, null);
        }
        count++;
    }
    craftconfig.save(craftfile);
    } catch (Exception e) {
        //
    }
  }
ConfigurationBuilder.java 文件源码 项目:Minecordbot 阅读 26 收藏 0 点赞 0 评论 0
private static Object build(Class clazz) {
    Object object;

    try {
        object = clazz.newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
        Logger.err("Failed to build a configuration - couldn't access the class!");
        return null;
    }

    String name = object.getClass().getDeclaredAnnotation(Configuration.class).value();
    File file = new File(JavaPlugin.getProvidingPlugin(clazz).getDataFolder(), String.format("%s.yml", name));
    FileConfiguration configFile = YamlConfiguration.loadConfiguration(file);

    buildFromConfig(configFile, clazz, object);

    return object;
}
LobbyModule.java 文件源码 项目:OpenUHC 阅读 25 收藏 0 点赞 0 评论 0
@Override
public void onEnable() {
  world = Bukkit.createWorld(new WorldCreator(OpenUHC.WORLD_DIR_PREFIX + "lobby"));
  // Read lobby yml if it exists
  File lobbyFile = new File(OpenUHC.WORLD_DIR_PREFIX + "lobby/lobby.yml");
  if (lobbyFile.exists()) {
    FileConfiguration lobbyConfig = YamlConfiguration.loadConfiguration(lobbyFile);
    ConfigurationSection spawn = lobbyConfig.getConfigurationSection("spawn");
    if (spawn != null) {
      double x = spawn.getDouble("x", 0);
      double y = spawn.getDouble("y", 64);
      double z = spawn.getDouble("z", 0);
      double r = spawn.getDouble("r", 1);
      this.spawn = new Vector(x, y, z);
      radius = (float) r;
    }
  }
  OpenUHC.registerEvents(this);
}
GameController.java 文件源码 项目:SkyWarsReloaded 阅读 18 收藏 0 点赞 0 评论 0
public void removeSignJoinGame(String gameNumber) {
    File signJoinFile = new File(SkyWarsReloaded.get().getDataFolder(), "signJoinGames.yml");
    FileConfiguration storage = YamlConfiguration.loadConfiguration(signJoinFile);
        storage.set("games." + gameNumber, null);
        try {
        storage.save(signJoinFile);
    } catch (IOException e) {
        e.printStackTrace();
    }
       signJoinGames.remove(Integer.valueOf(gameNumber));
       Game game = getGame(Integer.valueOf(gameNumber));
       if (game != null) {
           if (game.getState() != GameState.PLAYING) {
            game.endGame();
           }
       }
}
ArcConfiguration.java 文件源码 项目:Arc-v2 阅读 26 收藏 0 点赞 0 评论 0
/**
 * Get the data from config file.
 *
 * @param config the configuration file.
 */
public void read(FileConfiguration config) {

    // read type and time.
    banType = BanList.Type.valueOf(config.getString("ban-type"));
    banTime = config.getInt("ban-time", banTime);

    // convert the days into a date.
    String days = config.getString("ban-days");
    if (Objects.isNull(days) || Objects.equals(days, "0")) {
        banDate = null;
    } else {
        GregorianCalendar c = new GregorianCalendar();
        c.add(GregorianCalendar.DATE, Integer.parseInt(days));
        banDate = c.getTime();
    }

    tpsLimit = config.getInt("tps-limit", tpsLimit);

    broadcastBan = config.getBoolean("broadcast-ban");
    if (broadcastBan) {
        String message = config.getString("broadcast-message");
        broadcastMessage = ChatColor.translateAlternateColorCodes('&', message);
    }

}
Map.java 文件源码 项目:mczone 阅读 26 收藏 0 点赞 0 评论 0
public boolean reload() {
    ConfigAPI api = new ConfigAPI(getConfig());
       FileConfiguration config = api.getConfig();
       String title = config.getString("info.title");
       String worldName = config.getString("info.worldName");

       List<Location> spawns = new ArrayList<Location>();
       for (String s : config.getConfigurationSection("spawns").getKeys(false)) {
        Location l = api.getLocation("spawns." + s);
            spawns.add(l);
       }
       Location specSpawn = api.getLocation("spawns.spec");

       this.title = title;
       this.worldName = worldName;
       this.specSpawn = specSpawn;
       this.spawns = spawns;
    return true;
}
BungeeCordController.java 文件源码 项目:BlockBall 阅读 23 收藏 0 点赞 0 评论 0
public void add(String server, Location location) {
    final BungeeCordSignInfo info = new BungeeCordSignInfo.Container(location, server);
    this.signs.add(info);
    final BungeeCordSignInfo[] signInfos = this.signs.toArray(new BungeeCordSignInfo[this.signs.size()]);
    this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> {
        try {
            final FileConfiguration configuration = new YamlConfiguration();
            final File file = new File(BungeeCordController.this.plugin.getDataFolder(), "bungeecord_signs.yml");
            if (file.exists()) {
                if (!file.delete()) {
                    Bukkit.getLogger().log(Level.WARNING, "File cannot get deleted.");
                }
            }
            for (int i = 0; i < signInfos.length; i++) {
                configuration.set("signs." + i, signInfos[i].serialize());
            }
            configuration.save(file);
        } catch (final IOException e) {
            Bukkit.getLogger().log(Level.WARNING, "Save sign location.", e);
        }
    });
}
BungeeCordController.java 文件源码 项目:BlockBall 阅读 25 收藏 0 点赞 0 评论 0
private void load(JavaPlugin plugin) {
    try {
        final FileConfiguration configuration = new YamlConfiguration();
        final File file = new File(plugin.getDataFolder(), "bungeecord_signs.yml");
        if (!file.exists()) {
            if (!file.createNewFile()) {
                Bukkit.getLogger().log(Level.WARNING, "File cannot get created.");
            }
        }
        configuration.load(file);
        if (configuration.getConfigurationSection("signs") != null) {
            final Map<String, Object> data = configuration.getConfigurationSection("signs").getValues(false);
            for (final String s : data.keySet()) {
                this.signs.add(new BungeeCordSignInfo.Container(((ConfigurationSection) data.get(s)).getValues(true)));
            }
        }
    } catch (IOException | InvalidConfigurationException e) {
        Bukkit.getLogger().log(Level.WARNING, "Save load location.", e);
    }
}
ArenaFileManager.java 文件源码 项目:BlockBall 阅读 23 收藏 0 点赞 0 评论 0
void save(Arena item) {
    if (item != null && item.getName() != null) {
        try {
            final FileConfiguration configuration = new YamlConfiguration();
            final File file = new File(this.getFolder(), "arena_" + item.getName() + ".yml");
            if (file.exists()) {
                if (!file.delete())
                    throw new IllegalStateException("Cannot delete file!");
            }
            if (!file.createNewFile())
                throw new IllegalStateException("Cannot create file!");
            configuration.load(file);
            final Map<String, Object> data = item.serialize();
            for (final String key : data.keySet()) {
                configuration.set("arena." + key, data.get(key));
            }
            configuration.save(file);
        } catch (IOException | InvalidConfigurationException ex) {
            Bukkit.getLogger().log(Level.WARNING,"Cannot save arena." ,ex.getMessage());
        }
    }
}
ArenaFileManager.java 文件源码 项目:BlockBall 阅读 19 收藏 0 点赞 0 评论 0
Arena[] load() {
    final List<Arena> items = new ArrayList<>();
    for (int i = 0; (this.getFolder() != null) && (i < this.getFolder().list().length); i++) {
        final String s = this.getFolder().list()[i];
        try {
            if (s.contains("arena_")) {
                final FileConfiguration configuration = new YamlConfiguration();
                final File file = new File(this.getFolder(), s);
                configuration.load(file);
                final Map<String, Object> data = configuration.getConfigurationSection("arena").getValues(true);
                final Arena arenaEntity = new ArenaEntity(data, configuration.getStringList("arena.properties.wall-bouncing"));
                items.add(arenaEntity);
            }
        } catch (final Exception ex) {
            Bukkit.getLogger().log(Level.WARNING, "Cannot read arena file " + s + '.', ex);
        }
    }
    return items.toArray(new Arena[items.size()]);
}
LearnData.java 文件源码 项目:Crescent 阅读 25 收藏 0 点赞 0 评论 0
public void storeNewData(Learn learn, KnownCheating knownCheating) {
    final FileConfiguration fc = getConfig();

    // Generate a UUID for this check (its identifier).
    UUID uuid = UUID.randomUUID();

    while (fc.isConfigurationSection(uuid.toString())) {
        uuid = UUID.randomUUID();
    }

    // The path to put the data in the file.
    String cheatPath = getCheatPath(knownCheating);

    // Get general values.
    final double currentMean = fc.getDouble(cheatPath + "CurrentMean");
    final double currentLowRange = fc.getDouble(cheatPath + "CurrentLowRange");
    final double currentHighRange = fc.getDouble(cheatPath + "CurrentHighRange");
    final long totalSamples = fc.getLong(cheatPath + "TotalSamples");

    if (currentLowRange == 0.0 || learn.getValue() < currentLowRange) {
        fc.set(cheatPath + "CurrentLowRange", learn.getValue());
    } else if (learn.getValue() > currentHighRange) {
        fc.set(cheatPath + "CurrentHighRange", learn.getValue());
    }

    // Calculate the new average.
    double updateMean = (currentMean + learn.getValue()) / 2.0;

    fc.set(cheatPath + "CurrentMean", updateMean);
    fc.set(cheatPath + "TotalSamples", totalSamples + 1);

    // Save the file.
    save(fc);
}
CropControlDatabaseHandler.java 文件源码 项目:CropControl 阅读 21 收藏 0 点赞 0 评论 0
public CropControlDatabaseHandler(FileConfiguration config) {
    if (!configureData(config.getConfigurationSection("database"))) {
        throw new RuntimeException("Failed to configure Database for CropControl!");
    }
    CropControlDatabaseHandler.instance = this;
    this.dataAccessObject = new DAO(this);
}
ScriptManager.java 文件源码 项目:uppercore 阅读 26 收藏 0 点赞 0 评论 0
public void reloadConfig(File configFile) {
    extensionsToEngineName = new HashMap<>();

    FileConfiguration config = YamlConfiguration.loadConfiguration(configFile);
    ConfigurationSection section = config.getConfigurationSection("engines");
    for (Map.Entry<String, Object> obj : section.getValues(false).entrySet())
        extensionsToEngineName.put(obj.getKey(), obj.getValue().toString());
}
DDoSManager.java 文件源码 项目:ViperBot 阅读 19 收藏 0 点赞 0 评论 0
public void saveUsers(){
    File userFile = new File(mainFolder, "AllowedUsers.yml");
    FileConfiguration config = new YamlConfiguration();
    for(Entry<String, Date> ent : allowedUsers.entrySet()){
        config.set(ent.getKey().replace(".", "_(dot)_"), ent.getValue());
    }
    try {
        config.save(userFile);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Datafiles.java 文件源码 项目:RPGPlus 阅读 25 收藏 0 点赞 0 评论 0
public void createFile(Player p) {
    File pFileDir = new File(Main.getInstance().getDataFolder(), "Players");
    if (!pFileDir.exists()) {
        pFileDir.mkdir();
    }
    File pFile = new File(Main.getInstance().getDataFolder(), "Players/" + p.getName().toLowerCase() + ".yml");
    if (!pFile.exists())
        try {
            pFile.createNewFile();
            List<String> combo = new ArrayList<String>();
            List<String> guilds = new ArrayList<String>();
            combo.add(0, "???");
            combo.add(1, "???");
            combo.add(2, "???");
            FileConfiguration pConfig = YamlConfiguration.loadConfiguration(pFile);
            pConfig.set("User", p.getName());
            pConfig.set("Class", Default);
            pConfig.set("Race", Default);
            pConfig.set("Guilds", guilds);
            pConfig.set("Kills", Integer.valueOf(0));
            pConfig.set("Deaths", Integer.valueOf(0));

            pConfig.set("Counter", Integer.valueOf(1));
            pConfig.set("Combo", combo);

            // pConfig.set("Reader", Boolean[].class);
            /*
             * pConfig.set("ObservationHakiLevel", Integer.valueOf(0));
             * pConfig.set("ObservationHakiXP", Integer.valueOf(0));
             * pConfig.set("ConquerorsHaki", Boolean.valueOf(false));
             * pConfig.set("ConquerorHakiLevel", Integer.valueOf(0));
             * pConfig.set("ConquerorHakiXP", Integer.valueOf(0));
             */
            pConfig.save(pFile);
        } catch (Exception e) {
        }
}
Datafiles.java 文件源码 项目:RPGPlus 阅读 25 收藏 0 点赞 0 评论 0
public static void addKill(String p) {
    File pFile = new File(Main.getInstance().getDataFolder(), "Players/" + p.toLowerCase() + ".yml");
    FileConfiguration pConfig = YamlConfiguration.loadConfiguration(pFile);
    pConfig.set("Kills", Integer.valueOf(pConfig.getInt("Kills") + 1));
    try {
        pConfig.save(pFile);
    } catch (Exception e) {
    }
}
BanRequest.java 文件源码 项目:EpicBanRequests 阅读 28 收藏 0 点赞 0 评论 0
public void writeToConfig() {
    FileConfiguration c = Main.getInstance().getConfig();
    c.set("ban_requests." + id + ".timeOpened", timeOpened);
    c.set("ban_requests." + id + ".timeClosed", timeClosed);
    c.set("ban_requests." + id + ".openerUUID", openerUUID);
    c.set("ban_requests." + id + ".closerUUID", closerUUID);
    c.set("ban_requests." + id + ".timeOpenedFormatted", timeOpenedFormatted);
    c.set("ban_requests." + id + ".timeClosedFormatted", timeClosedFormatted);
    c.set("ban_requests." + id + ".closed", closed);
    c.set("ban_requests." + id + ".accepted", accepted);
    c.set("ban_requests." + id + ".denied", denied);
    c.set("ban_requests." + id + ".banReason", banReason);
    c.set("ban_requests." + id + ".playerToBanUUID", playerToBanUUID);
    Main.getInstance().saveConfig();
}
Datafiles.java 文件源码 项目:RPGPlus 阅读 20 收藏 0 点赞 0 评论 0
public void addPoints(String p, int amountAdded) {
    File pFile = new File(Main.getInstance().getDataFolder(), "Players/" + p.toLowerCase() + ".yml");
    FileConfiguration pConfig = YamlConfiguration.loadConfiguration(pFile);
    pConfig.set("Points", Integer.valueOf(pConfig.getInt("Points") + amountAdded));
    try {
        pConfig.save(pFile);
    } catch (Exception e) {
    }
}
Datafiles.java 文件源码 项目:RPGPlus 阅读 23 收藏 0 点赞 0 评论 0
public static void incrementCounter(String p) {
    File pFile = new File(Main.getInstance().getDataFolder(), "Players/" + p.toLowerCase() + ".yml");
    FileConfiguration pConfig = YamlConfiguration.loadConfiguration(pFile);
    pConfig.set("counter", Integer.valueOf(pConfig.getInt("counter") + 1));
    try {
        pConfig.save(pFile);
    } catch (Exception e) {
    }
}
AzureAPI.java 文件源码 项目:Recreator 阅读 29 收藏 0 点赞 0 评论 0
public static FileConfiguration loadOrCreateFile(File file) {
    if (!file.exists()) {
        try {
            file.createNewFile();
        } catch (IOException ex) {
        }
    }
    return YamlConfiguration.loadConfiguration(file);
}
Command.java 文件源码 项目:StartupCommands 阅读 21 收藏 0 点赞 0 评论 0
/**
 * Static method for removing a command from the configuration.
 * @param plugin The StartupCommands instance.
 * @param removeStr The String of the command to remove. If it is an Integer
 * the command will be removed by index, otherwise, the method looks for a matching
 * command String.
 * @return removeStr The command String of the removed command.
 * @throws IllegalArgumentException if the command doesn't exist, if the index provided 
 * is less than zero or greater than commands.size() - 1, or if the configuration file 
 * cannot be saved.
 */
public static String removeCommand(StartupCommands plugin, String removeStr) {
    FileConfiguration config = plugin.getConfig();

    // Find the command String if removeStr is an Integer
    if (StartupCommands.isInteger(removeStr)) {
        List<Command> commands = plugin.getCommands();
        int index = Integer.parseInt(removeStr) - 1;

        // Ensure index is valid
        if (index < 0 || index > commands.size() - 1) {
            throw new IllegalArgumentException("Index must be greater than 0 and less than the number of startup commands.");
        }

        removeStr = plugin.getCommands().remove(index).getCommand();
    }

    if (config.contains("commands." + removeStr)) {
        config.set("commands." + removeStr, null);

        // Try to save configuration
        try {
            config.save(plugin.getDataFolder() + File.separator + "config.yml");
        } catch (IOException e) {
            throw new IllegalArgumentException("Could not save configuration file.");
        }

        return removeStr;
    } else {
        throw new IllegalArgumentException("Could not identify command to remove by " + removeStr + ".");
    }
}
MapLibrary.java 文件源码 项目:Warzone 阅读 28 收藏 0 点赞 0 评论 0
public MapLibrary(FileConfiguration fileConfiguration, MapLoader mapLoader) {
    for (String s : fileConfiguration.getConfigurationSection("map").getStringList("sources")) {
        sources.add(new File(s));
        Bukkit.getLogger().info("Added map source: " + s);
    }

    this.mapLoader = mapLoader;
}
ConfigurationBuilder.java 文件源码 项目:Minecordbot 阅读 20 收藏 0 点赞 0 评论 0
private static void fieldSet(Field f, FileConfiguration config, Object instance, String key) throws IllegalAccessException {
    if (config.get(key) instanceof Boolean) {
        f.set(instance, config.getBoolean(key));
    } else if (config.get(key) instanceof Integer) {
        f.set(instance, config.getInt(key));
    } else if (config.get(key) instanceof ConfigurationSection) {
        f.set(instance, f.getType().cast(((ConfigurationSection) config.get(key)).getValues(false)));
    } else {
        f.set(instance, f.getType().cast(config.get(key)));
    }
}
WorldSpawnLimiter.java 文件源码 项目:EscapeLag 阅读 23 收藏 0 点赞 0 评论 0
@EventHandler
public void WorldSeterLimitor(WorldInitEvent event) {
    World world = event.getWorld();
    FileConfiguration config = EscapeLag.configOptimize.getValue();
    if (config.getBoolean("WorldSpawnLimitor." + world.getName() + ".enable")) {
        world.setMonsterSpawnLimit(config.getInt("WorldSpawnLimitor." + world.getName() + ".PerChunkMonsters"));
        world.setAnimalSpawnLimit(config.getInt("WorldSpawnLimitor." + world.getName() + ".PerChunkAnimals"));
        world.setAmbientSpawnLimit(config.getInt("WorldSpawnLimitor." + world.getName() + ".PerChunkAmbient"));
        EscapeLag.MainThis.getLogger().info("已为世界 " + world.getName() + " 设定了生物刷新速率~");
    }
}
EmojiHandler.java 文件源码 项目:EmojiChat 阅读 22 收藏 0 点赞 0 评论 0
/**
 * Loads the disabled emojis from the config.
 *
 * @param config The config to load disabled emojis from.
 * @param plugin The EmojiChat main class instance.
 */
private void loadDisabledEmojis(FileConfiguration config, EmojiChat plugin) {
    if (config.getBoolean("disable-emojis")) {
        for (String disabledEmoji : config.getStringList("disabled-emojis")) {
            if (disabledEmoji == null || !emojis.containsKey(disabledEmoji)) {
                plugin.getLogger().warning("Invalid emoji specified in 'disabled-emojis': '" + disabledEmoji + "'. Skipping...");
                continue;
            }
            disabledCharacters.add(emojis.remove(disabledEmoji)); // Remove disabled emojis from the emoji list
        }
    }
}


问题


面经


文章

微信
公众号

扫码关注公众号