public static IEnumerator AutoCloseEnumerator(Door __instance, ZNetView ___m_nview)
            {
                while (true)
                {
                    // 一定時間待機
                    yield return(new WaitForSeconds(0.2f));

                    if (!toggleSwitch) // トグルスイッチでMODが無効化されている
                    {
                        coroutinePairs.Remove(___m_nview.GetHashCode());
                        yield break;
                    }

                    // ドア種別ごとの設定値
                    String doorName        = ___m_nview.GetPrefabName();
                    float  distanceSetting = Utils.GetSettingRangeByDoor(doorName, false);

                    // プレイヤーとの距離を取得し、指定された範囲より離れているときはドアを閉じる
                    float distance = Utils.GetPlayerDistance(__instance.m_doorObject);
                    if (distance > distanceSetting)
                    {
                        yield return(new WaitForSeconds(waitForDoorToCloseSeconds.Value));

                        ___m_nview.GetZDO().Set("state", 0);
                        coroutinePairs.Remove(___m_nview.GetHashCode());
                        yield break;
                    }
                }
            }
            private static void Postfix(ref Door __instance, ZNetView ___m_nview)
            {
                if (!isEnabled.Value ||             // MODが無効化されている
                    __instance.m_keyItem != null || // 対象のドアに鍵が必要
                    isInsideCrypt ||                // プレイヤーがCrypt内にいる
                    !toggleSwitch)                  // トグルスイッチでMODが無効化されている
                {
                    return;
                }

                if (coroutinePairs.ContainsKey(___m_nview.GetHashCode()))
                {
                    ___m_nview.StopCoroutine(coroutinePairs[___m_nview.GetHashCode()]);
                }

                Coroutine coroutine = ___m_nview.StartCoroutine(AutoCloseEnumerator(__instance, ___m_nview));

                coroutinePairs[___m_nview.GetHashCode()] = coroutine;
            }
            private static void Postfix(Door __instance, ref ZNetView ___m_nview)
            {
                if (!isEnabled.Value) // MODが無効化されている
                {
                    return;
                }

                // ログイン中はインスタンスが取得できないので何もしない
                Player localPlayer = Player.m_localPlayer;

                if (localPlayer == null || __instance == null || ___m_nview == null)
                {
                    return;
                }

                String doorName = ___m_nview.GetPrefabName();
                int    hashCode = ___m_nview.GetHashCode();

                if (__instance.m_keyItem != null ||                             // 対象のドアに鍵が必要
                    (disableAutomaticDoorOpenInCrypt.Value && isInsideCrypt) || // プレイヤーがCrypt内にいる
                    !toggleSwitch)                                              // トグルスイッチでMODが無効化されている
                {
                    return;
                }

                // すでにドアが開いているときは一定時間後に閉じる処理を起動
                if (___m_nview.GetZDO().GetInt("state", 0) != 0)
                {
                    if (!coroutinePairs.ContainsKey(hashCode) && // まだコルーチンが起動していない
                        !isInsideCrypt &&                        // プレイヤーがCrypt内にいない
                        !doorName.StartsWith("dungeon_"))        // ドアのプレハブ名がdungeon_で始まってない
                    {
                        Coroutine coroutine = ___m_nview.StartCoroutine(AutomaticDoorClose.AutoCloseEnumerator(__instance, ___m_nview));
                        coroutinePairs[hashCode] = coroutine;
                    }
                    return;
                }

                // ドア種別ごとのdistanceサポート
                float distanceSetting = Utils.GetSettingRangeByDoor(doorName, true);

                // プレイヤーがドアの範囲内にいる、かつ、初めてプレイヤーが近づいたときにドアを開く
                float distance = Utils.GetPlayerDistance(__instance.m_doorObject);

                isAlreadyEnteredDict.TryGetValue(hashCode, out bool result);
                if (distance <= distanceSetting && !result)
                {
                    __instance.Interact(localPlayer, false);
                    isAlreadyEnteredDict[hashCode] = true;
                }
                else if (distance > distanceSetting)
                {
                    isAlreadyEnteredDict[hashCode] = false;
                }
            }